--- Makefile.am | 7 +- anaconda | 932 ++++++++++++++++++++++++++++++++++++++++ anaconda.py | 932 ---------------------------------------- bin/Makefile.am | 2 +- bin/isys/.gitignore | 6 + bin/isys/Makefile.am | 56 +++ bin/isys/__init__.py | 560 ++++++++++++++++++++++++ bin/isys/auditd.c | 134 ++++++ bin/isys/auditd.h | 30 ++ bin/isys/cpio.c | 46 ++ bin/isys/cpio.h | 102 +++++ bin/isys/devices.c | 221 ++++++++++ bin/isys/devices.h | 42 ++ bin/isys/eddsupport.c | 339 +++++++++++++++ bin/isys/eddsupport.h | 28 ++ bin/isys/ethtool.c | 119 +++++ bin/isys/ethtool.h | 41 ++ bin/isys/iface.c | 543 +++++++++++++++++++++++ bin/isys/iface.h | 166 +++++++ bin/isys/imount.c | 328 ++++++++++++++ bin/isys/imount.h | 50 +++ bin/isys/isofs.c | 55 +++ bin/isys/isys.c | 701 ++++++++++++++++++++++++++++++ bin/isys/isys.h | 39 ++ bin/isys/lang.c | 207 +++++++++ bin/isys/lang.h | 44 ++ bin/isys/linkdetect.c | 202 +++++++++ bin/isys/log.c | 224 ++++++++++ bin/isys/log.h | 51 +++ bin/isys/stubs.h | 44 ++ bin/isys/uncpio.c | 798 ++++++++++++++++++++++++++++++++++ bin/isys/vio.c | 106 +++++ bin/loader/Makefile.am | 6 +- bin/loader/modules.c | 2 +- configure.ac | 17 +- data/Makefile.am | 2 +- po/POTFILES.in | 266 ++++++------ pyanaconda/Makefile.am | 2 +- pyanaconda/isys/.gitignore | 6 - pyanaconda/isys/Makefile.am | 56 --- pyanaconda/isys/__init__.py | 560 ------------------------ pyanaconda/isys/auditd.c | 134 ------ pyanaconda/isys/auditd.h | 30 -- pyanaconda/isys/cpio.c | 46 -- pyanaconda/isys/cpio.h | 102 ----- pyanaconda/isys/devices.c | 221 ---------- pyanaconda/isys/devices.h | 42 -- pyanaconda/isys/eddsupport.c | 339 --------------- pyanaconda/isys/eddsupport.h | 28 -- pyanaconda/isys/ethtool.c | 119 ----- pyanaconda/isys/ethtool.h | 41 -- pyanaconda/isys/iface.c | 543 ----------------------- pyanaconda/isys/iface.h | 166 ------- pyanaconda/isys/imount.c | 328 -------------- pyanaconda/isys/imount.h | 50 --- pyanaconda/isys/isofs.c | 55 --- pyanaconda/isys/isys.c | 701 ------------------------------ pyanaconda/isys/isys.h | 39 -- pyanaconda/isys/lang.c | 207 --------- pyanaconda/isys/lang.h | 44 -- pyanaconda/isys/linkdetect.c | 202 --------- pyanaconda/isys/log.c | 224 ---------- pyanaconda/isys/log.h | 51 --- pyanaconda/isys/stubs.h | 44 -- pyanaconda/isys/uncpio.c | 798 ---------------------------------- pyanaconda/isys/vio.c | 106 ----- scripts/getlangnames.py | 2 +- tests/Makefile.am | 2 - tests/mock/Makefile.am | 3 - tests/storage_test/Makefile.am | 1 - utils/Makefile.am | 4 +- utils/mapshdr.c | 2 +- utils/modlist.c | 2 +- utils/readmap.c | 2 +- 74 files changed, 6378 insertions(+), 6372 deletions(-) create mode 100755 anaconda delete mode 100755 anaconda.py create mode 100644 bin/isys/.gitignore create mode 100644 bin/isys/Makefile.am create mode 100755 bin/isys/__init__.py create mode 100644 bin/isys/auditd.c create mode 100644 bin/isys/auditd.h create mode 100644 bin/isys/cpio.c create mode 100644 bin/isys/cpio.h create mode 100644 bin/isys/devices.c create mode 100644 bin/isys/devices.h create mode 100644 bin/isys/eddsupport.c create mode 100644 bin/isys/eddsupport.h create mode 100644 bin/isys/ethtool.c create mode 100644 bin/isys/ethtool.h create mode 100644 bin/isys/iface.c create mode 100644 bin/isys/iface.h create mode 100644 bin/isys/imount.c create mode 100644 bin/isys/imount.h create mode 100644 bin/isys/isofs.c create mode 100644 bin/isys/isys.c create mode 100644 bin/isys/isys.h create mode 100644 bin/isys/lang.c create mode 100644 bin/isys/lang.h create mode 100644 bin/isys/linkdetect.c create mode 100644 bin/isys/log.c create mode 100644 bin/isys/log.h create mode 100644 bin/isys/stubs.h create mode 100644 bin/isys/uncpio.c create mode 100644 bin/isys/vio.c delete mode 100644 pyanaconda/isys/.gitignore delete mode 100644 pyanaconda/isys/Makefile.am delete mode 100755 pyanaconda/isys/__init__.py delete mode 100644 pyanaconda/isys/auditd.c delete mode 100644 pyanaconda/isys/auditd.h delete mode 100644 pyanaconda/isys/cpio.c delete mode 100644 pyanaconda/isys/cpio.h delete mode 100644 pyanaconda/isys/devices.c delete mode 100644 pyanaconda/isys/devices.h delete mode 100644 pyanaconda/isys/eddsupport.c delete mode 100644 pyanaconda/isys/eddsupport.h delete mode 100644 pyanaconda/isys/ethtool.c delete mode 100644 pyanaconda/isys/ethtool.h delete mode 100644 pyanaconda/isys/iface.c delete mode 100644 pyanaconda/isys/iface.h delete mode 100644 pyanaconda/isys/imount.c delete mode 100644 pyanaconda/isys/imount.h delete mode 100644 pyanaconda/isys/isofs.c delete mode 100644 pyanaconda/isys/isys.c delete mode 100644 pyanaconda/isys/isys.h delete mode 100644 pyanaconda/isys/lang.c delete mode 100644 pyanaconda/isys/lang.h delete mode 100644 pyanaconda/isys/linkdetect.c delete mode 100644 pyanaconda/isys/log.c delete mode 100644 pyanaconda/isys/log.h delete mode 100644 pyanaconda/isys/stubs.h delete mode 100644 pyanaconda/isys/uncpio.c delete mode 100644 pyanaconda/isys/vio.c diff --git a/Makefile.am b/Makefile.am index 7beccbf..d702dba 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,9 +19,8 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = po loader utils scripts \ - command-stubs docs tests \ - data bin booty pyanaconda +SUBDIRS = bin booty pyanaconda data \ + booty tests utils scripts docs po EXTRA_DIST = config.rpath COPYING \ anaconda.spec.in @@ -36,7 +35,7 @@ MOSTLYCLEANDIRS = m4 dist_noinst_DATA = $(PACKAGE_NAME).spec -dist_sbin_SCRIPTS = anaconda.py +dist_sbin_SCRIPTS = anaconda ARCHIVE_TAG = $(PACKAGE_NAME)-$(PACKAGE_VERSION)-$(PACKAGE_RELEASE) diff --git a/anaconda b/anaconda new file mode 100755 index 0000000..b5532b0 --- /dev/null +++ b/anaconda @@ -0,0 +1,932 @@ +#!/usr/bin/python +# +# anaconda: The Red Hat Linux Installation program +# +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 +# Red Hat, Inc. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Brent Fox <bfox@xxxxxxxxxx> +# Mike Fulbright <msf@xxxxxxxxxx> +# Jakub Jelinek <jakub@xxxxxxxxxx> +# Jeremy Katz <katzj@xxxxxxxxxx> +# Chris Lumens <clumens@xxxxxxxxxx> +# Paul Nasrat <pnasrat@xxxxxxxxxx> +# Erik Troan <ewt@xxxxxxxxx> +# Matt Wilson <msw@xxxxxxxxx> +# + +# This toplevel file is a little messy at the moment... + +import sys, os, re, time, subprocess +from optparse import OptionParser +from tempfile import mkstemp + +# keep up with process ID of the window manager if we start it +wm_pid = None + +# Make sure messages sent through python's warnings module get logged. +def AnacondaShowWarning(message, category, filename, lineno, file=sys.stderr, line=None): + log.warning("%s" % warnings.formatwarning(message, category, filename, lineno, line)) + +def startMetacityWM(): + childpid = os.fork() + if not childpid: + cmd = '/usr/bin/metacity' + if not os.access(cmd, os.X_OK): + log.error("Unable to find the window manager binary.") + sys.exit(1) + args = ['--display', ':1', + '--sm-disable'] + rc = iutil.execWithRedirect(cmd, args, + stdout='/dev/null', stderr='/dev/null') + if rc: + log.error("Error running window manager.") + sys.exit (rc) + else: + log.info("The window manager has terminated.") + sys.exit(0) + return childpid + +def startAuditDaemon(): + childpid = os.fork() + if not childpid: + cmd = '/sbin/auditd' + try: + os.execl(cmd, cmd) + except OSError as e: + log.error("Error running the audit daemon: %s" % str(e)) + sys.exit(0) + # auditd will turn into a daemon so catch the immediate child pid now: + os.waitpid(childpid, 0) + +# function to handle X startup special issues for anaconda +def doStartupX11Actions(runres="800x600"): + global wm_pid + + setupGraphicalLinks() + + # now start up the window manager + try: + wm_pid = startMetacityWM() + log.info("Starting window manager, pid %s." % (wm_pid,)) + except Exception: + wm_pid = None + log.error("Unable to start the window manager.") + + if wm_pid is not None: + import xutils + import gtk + + try: + xutils.setRootResource('Xcursor.size', '24') + xutils.setRootResource('Xcursor.theme', 'Bluecurve') + xutils.setRootResource('Xcursor.theme_core', 'true') + + xutils.setRootResource('Xft.antialias', '1') + xutils.setRootResource('Xft.hinting', '1') + xutils.setRootResource('Xft.hintstyle', 'hintslight') + xutils.setRootResource('Xft.rgba', 'none') + except: + sys.stderr.write("X SERVER STARTED, THEN FAILED"); + raise RuntimeError, "X server failed to start" + +def doShutdownX11Actions(): + global wm_pid + + if wm_pid is not None: + try: + os.kill(wm_pid, 15) + os.waitpid(wm_pid, 0) + except: + pass + +def setupPythonUpdates(): + from distutils.sysconfig import get_python_lib + + if not os.path.exists("/tmp/updates"): + return + + for pkg in os.listdir("/tmp/updates"): + d = "/tmp/updates/%s" % pkg + + if not os.path.isdir(d): + continue + + # See if the package exists in /usr/lib{64,}/python/?.?/site-packages. + # If it does, we can set it up as an update. If not, the pkg is + # likely a completely new directory and should not be looked at. + dest = "%s/%s" % (get_python_lib(), pkg) + if not os.access(dest, os.R_OK): + dest = "%s/%s" % (get_python_lib(1), pkg) + if not os.access(dest, os.R_OK): + continue + + contents = os.listdir(d) + + # Symlink over everything that's in the python libdir but not in + # the updates directory. + for f in filter(lambda fn: fn not in contents, os.listdir(dest)): + if f.endswith(".pyc") or f.endswith(".pyo"): + continue + + os.symlink("%s/%s" % (dest, f), "/tmp/updates/%s/%s" % (pkg, f)) + + + import glob + import shutil + for rule in glob.glob("/tmp/updates/*.rules"): + target = "/etc/udev/rules.d/" + rule.split('/')[-1] + shutil.copyfile(rule, target) + +def parseOptions(argv = None): + def resolution_cb (option, opt_str, value, parser): + parser.values.runres = value + + op = OptionParser() + # Interface + op.add_option("-C", "--cmdline", dest="display_mode", action="store_const", const="c", + default="g") + op.add_option("-G", "--graphical", dest="display_mode", action="store_const", const="g") + op.add_option("-T", "--text", dest="display_mode", action="store_const", const="t") + + # Network + op.add_option("--noipv4", action="store_true", default=False) + op.add_option("--noipv6", action="store_true", default=False) + op.add_option("--proxy") + op.add_option("--proxyAuth") + + # Method of operation + op.add_option("--autostep", action="store_true", default=False) + op.add_option("-d", "--debug", dest="debug", action="store_true", default=False) + op.add_option("--kickstart", dest="ksfile") + op.add_option("--rescue", dest="rescue", action="store_true", default=False) + op.add_option("--targetarch", dest="targetArch", nargs=1, type="string") + + op.add_option("-m", "--method", dest="method", default=None) + op.add_option("--repo", dest="method", default=None) + op.add_option("--stage2", dest="stage2", default=None) + + op.add_option("--liveinst", action="store_true", default=False) + + # Display + op.add_option("--headless", dest="isHeadless", action="store_true", default=False) + op.add_option("--nofb") + op.add_option("--resolution", action="callback", callback=resolution_cb, dest="runres", + default="800x600", nargs=1, type="string") + op.add_option("--serial", action="store_true", default=False) + op.add_option("--usefbx", dest="xdriver", action="store_const", const="fbdev") + op.add_option("--virtpconsole") + op.add_option("--vnc", action="store_true", default=False) + op.add_option("--vncconnect") + op.add_option("--xdriver", dest="xdriver", action="store", type="string", default=None) + + # Language + op.add_option("--keymap") + op.add_option("--kbdtype") + op.add_option("--lang") + + # Obvious + op.add_option("--loglevel") + op.add_option("--syslog") + + op.add_option("--noselinux", dest="selinux", action="store_false", default=True) + op.add_option("--selinux", action="store_true") + + op.add_option("--nompath", dest="mpath", action="store_false", default=True) + op.add_option("--mpath", action="store_true") + + op.add_option("--nodmraid", dest="dmraid", action="store_false", default=True) + op.add_option("--dmraid", action="store_true") + + op.add_option("--noibft", dest="ibft", action="store_false", default=True) + op.add_option("--ibft", action="store_true") + op.add_option("--noiscsi", dest="iscsi", action="store_false", default=False) + op.add_option("--iscsi", action="store_true") + + # Miscellaneous + op.add_option("--module", action="append", default=[]) + op.add_option("--nomount", dest="rescue_nomount", action="store_true", default=False) + op.add_option("--updates", dest="updateSrc", action="store", type="string") + op.add_option("--dogtail", dest="dogtail", action="store", type="string") + op.add_option("--dlabel", action="store_true", default=False) + + # Deprecated, unloved, unused + op.add_option("-r", "--rootPath", dest="unsupportedMode", + action="store_const", const="root path") + op.add_option("-t", "--test", dest="unsupportedMode", + action="store_const", const="test") + + return op.parse_args(argv) + +def setupPythonPath(): + haveUpdates = False + for ndx in range(len(sys.path)-1, -1, -1): + if sys.path[ndx].endswith('updates'): + haveUpdates = True + break + + # With anaconda being a real module this isn't strictly necessary, but + # setting up the path now prevents having to change every import line in + # anaconda. + from distutils.sysconfig import get_python_lib + d = get_python_lib(plat_specific=1) + + if haveUpdates: + sys.path.insert(ndx+1, "%s/pyanaconda" % d) + sys.path.insert(ndx+2, "%s/pyanaconda/textw" % d) + sys.path.insert(ndx+3, "%s/pyanaconda/iw" % d) + else: + sys.path.insert(0, "%s/pyanaconda" % d) + sys.path.insert(1, "%s/pyanaconda/textw" % d) + sys.path.insert(2, "%s/pyanaconda/iw" % d) + + sys.path.append('/usr/share/system-config-date') + +def addPoPath(dir): + """ Looks to see what translations are under a given path and tells + the gettext module to use that path as the base dir """ + for d in os.listdir(dir): + if not os.path.isdir("%s/%s" %(dir,d)): + continue + if not os.path.exists("%s/%s/LC_MESSAGES" %(dir,d)): + continue + for basename in os.listdir("%s/%s/LC_MESSAGES" %(dir,d)): + if not basename.endswith(".mo"): + continue + log.info("setting %s as translation source for %s" %(dir, basename[:-3])) + gettext.bindtextdomain(basename[:-3], dir) + +def setupTranslations(): + if os.path.isdir("/tmp/updates/po"): + addPoPath("/tmp/updates/po") + gettext.textdomain("anaconda") + +def setupEnvironment(): + # Silly GNOME stuff + if os.environ.has_key('HOME') and not os.environ.has_key("XAUTHORITY"): + os.environ['XAUTHORITY'] = os.environ['HOME'] + '/.Xauthority' + os.environ['HOME'] = '/tmp' + os.environ['LC_NUMERIC'] = 'C' + os.environ["GCONF_GLOBAL_LOCKS"] = "1" + + # In theory, this gets rid of our LVM file descriptor warnings + os.environ["LVM_SUPPRESS_FD_WARNINGS"] = "1" + + # make sure we have /sbin and /usr/sbin in our path + os.environ["PATH"] += ":/sbin:/usr/sbin" + + # we can't let the LD_PRELOAD hang around because it will leak into + # rpm %post and the like. ick :/ + if os.environ.has_key("LD_PRELOAD"): + del os.environ["LD_PRELOAD"] + + os.environ["GLADEPATH"] = "/tmp/updates/:/tmp/updates/ui/:ui/:/usr/share/anaconda/ui/:/usr/share/python-meh/" + os.environ["PIXMAPPATH"] = "/tmp/updates/pixmaps/:/tmp/updates/:/tmp/product/pixmaps/:/tmp/product/:pixmaps/:/usr/share/anaconda/pixmaps/:/usr/share/pixmaps/:/usr/share/anaconda/:/usr/share/python-meh/" + +def setupLoggingFromOpts(opts): + if opts.loglevel and anaconda_log.logLevelMap.has_key(opts.loglevel): + level = anaconda_log.logLevelMap[opts.loglevel] + anaconda_log.logger.tty_loglevel = level + anaconda_log.setHandlersLevel(log, level) + anaconda_log.setHandlersLevel(storage.storage_log.logger, level) + + if opts.syslog: + anaconda_log.logger.remote_syslog = opts.syslog + if opts.syslog.find(":") != -1: + (host, port) = opts.syslog.split(":") + anaconda_log.logger.addSysLogHandler(log, host, port=int(port)) + else: + anaconda_log.logger.addSysLogHandler(log, opts.syslog) + +# ftp installs pass the password via a file in /tmp so +# ps doesn't show it +def expandFTPMethod(str): + ret = None + + try: + filename = str[1:] + ret = open(filename, "r").readline() + ret = ret[:len(ret) - 1] + os.unlink(filename) + return ret + except: + return None + +def runVNC(): + global vncS + vncS.startServer() + + child = os.fork() + if child == 0: + for p in ('/tmp/updates/pyrc.py', \ + '/usr/share/anaconda/pyrc.py'): + if os.access(p, os.R_OK|os.X_OK): + os.environ['PYTHONSTARTUP'] = p + break + + while True: + # s390/s390x are the only places we /really/ need a shell on tty1, + # and everywhere else this just gets in the way of pdb. But we + # don't want to return, because that'll return try to start X + # a second time. + if iutil.isConsoleOnVirtualTerminal(): + time.sleep(10000) + else: + print _("Press <enter> for a shell") + sys.stdin.readline() + iutil.execConsole() + +def within_available_memory(needed_ram): + # kernel binary code estimate that is + # not reported in MemTotal by /proc/meminfo: + epsilon = 15360 # 15 MB + return needed_ram < (iutil.memInstalled() + epsilon) + +def check_memory(anaconda, opts, display_mode=None): + + if not display_mode: + display_mode = anaconda.displayMode + + extra_ram = 0 + reason = '' + if opts.stage2.startswith(('http', 'ftp', '@')): + extra_ram += isys.URL_INSTALL_EXTRA_RAM + reason = " using this install method" + + needed_ram = isys.MIN_RAM + extra_ram + if not within_available_memory(needed_ram): + from snack import SnackScreen, ButtonChoiceWindow + screen = SnackScreen() + ButtonChoiceWindow(screen, _('Fatal Error'), + _('You do not have enough RAM to install %s ' + 'on this machine%s.\n' + '\n' + 'Press <return> to reboot your system.\n') + %(product.productName, reason), + buttons = (_("OK"),)) + screen.finish() + sys.exit(0) + + # override display mode if machine cannot nicely run X + if display_mode not in ('t', 'c') and not flags.usevnc: + needed_ram = isys.MIN_GUI_RAM + extra_ram + + if not within_available_memory(needed_ram): + complain = _("You do not have enough RAM to use the graphical " + "installer.") + if flags.livecdInstall: + stdoutLog.warning(complain) + recommendation = _("Try the text mode installer by running:\n\n" + "'/usr/bin/liveinst -T'\n\n from a root " + "terminal.") + title = _("Not enough RAM") + text = "%s %s" %(complain, recommendation) + import gtk + dialog = gtk.MessageDialog(type = gtk.MESSAGE_ERROR, + buttons = gtk.BUTTONS_CLOSE, + message_format=text) + dialog.set_title(title) + dialog.run() + sys.exit(1) + else: + resolution = _("Starting text mode.") + stdoutLog.warning("%s %s" % (complain, resolution)) + anaconda.displayMode = 't' + time.sleep(2) + +def setupGraphicalLinks(): + for i in ( "imrc", "im_palette.pal", "gtk-2.0", "pango", "fonts", + "fb.modes"): + try: + if os.path.exists("/mnt/runtime/etc/%s" %(i,)): + os.symlink ("../mnt/runtime/etc/" + i, "/etc/" + i) + except: + pass + +def handleSshPw(anaconda): + if not anaconda.ksdata: + return + + import users + u = users.Users(anaconda) + + userdata = anaconda.ksdata.sshpw.dataList() + for ud in userdata: + if u.checkUserExists(ud.username, root="/"): + u.setUserPassword(username=ud.username, password=ud.password, + isCrypted=ud.isCrypted, lock=ud.lock) + else: + u.createUser(name=ud.username, password=ud.password, + isCrypted=ud.isCrypted, lock=ud.lock, + root="/") + + del u + +def createSshKey(algorithm, keyfile): + path = '/etc/ssh/%s' % (keyfile,) + argv = ['-q','-t',algorithm,'-f',path,'-C','','-N',''] + log.info("running \"%s\"" % (" ".join(['ssh-keygen']+argv),)) + + so = "/tmp/ssh-keygen-%s-stdout.log" % (algorithm,) + se = "/tmp/ssh-keygen-%s-stderr.log" % (algorithm,) + iutil.execWithRedirect('ssh-keygen', argv, stdout=so, stderr=se) + +def fork_orphan(): + """Forks an orphan. + + Returns 1 in the parent and 0 in the orphaned child. + """ + intermediate = os.fork() + if not intermediate: + if os.fork(): + # the intermediate child dies + os._exit(0) + return 0; + # the original process waits for the intermediate child + os.waitpid(intermediate, 0) + return 1 + +def startSsh(): + if iutil.isS390(): + return + + if not fork_orphan(): + os.mkdir("/var/log", 0755) + os.open("/var/log/lastlog", os.O_RDWR | os.O_CREAT, 0644) + ssh_keys = { + 'rsa1':'ssh_host_key', + 'rsa':'ssh_host_rsa_key', + 'dsa':'ssh_host_dsa_key', + } + for (algorithm, keyfile) in ssh_keys.items(): + createSshKey(algorithm, keyfile) + args = ["/sbin/sshd", "-f", "/etc/ssh/sshd_config.anaconda"] + os.execv("/sbin/sshd", args) + sys.exit(1) + +def startDebugger(signum, frame): + import epdb + epdb.serve(skip=1) + +if __name__ == "__main__": + setupPythonPath() + + # Allow a file to be loaded as early as possible + try: + import updates_disk_hook + except ImportError: + pass + + # Set up logging as early as possible. + import logging + import anaconda_log + anaconda_log.init() + + log = logging.getLogger("anaconda") + stdoutLog = logging.getLogger("anaconda.stdout") + + if os.geteuid() != 0: + stdoutLog.error("anaconda must be run as root.") + sys.exit(0) + + # pull this in to get product name and versioning + import product + + # this handles setting up updates for pypackages to minimize the set needed + setupPythonUpdates() + + import isys + isys.initLog() + + import signal, string, iutil, time + import warnings + import vnc + import users + import kickstart + import storage.storage_log + + from flags import flags + + # the following makes me very sad. -- katzj + # we have a slightly different set of udev rules in the second + # stage than the first stage. why this doesn't get picked up + # automatically, I don't know. but we need to trigger so that we + # have all the information about netdevs that we care about for + # NetworkManager in the udev database + from baseudev import udev_trigger, udev_settle + udev_trigger("net") + udev_settle() + # and for added fun, once doesn't seem to be enough? so we + # do it twice, it works and we scream at the world "OH WHY?" + udev_trigger("net") + udev_settle() + + import gettext + _ = lambda x: gettext.ldgettext("anaconda", x) + + from pyanaconda import Anaconda + anaconda = Anaconda() + warnings.showwarning = AnacondaShowWarning + setupTranslations() + + # reset python's default SIGINT handler + signal.signal(signal.SIGINT, signal.SIG_DFL) + signal.signal(signal.SIGSEGV, isys.handleSegv) + + setupEnvironment() + + pidfile = open("/var/run/anaconda.pid", "w") + pidfile.write("%s\n" % (os.getpid(),)) + del pidfile + # add our own additional signal handlers + signal.signal(signal.SIGHUP, startDebugger) + + # we need to do this really early so we make sure its done before rpm + # is imported + iutil.writeRpmPlatform() + + graphical_failed = 0 + vncS = vnc.VncServer() # The vnc Server object. + vncS.anaconda = anaconda + xserver_pid = None + + (opts, args) = parseOptions() + + # check memory, just the text mode for now: + check_memory(anaconda, opts, 't') + + if opts.unsupportedMode: + stdoutLog.error("Running anaconda in %s mode is no longer supported." % opts.unsupportedMode) + sys.exit(0) + + # Now that we've got arguments, do some extra processing. + setupLoggingFromOpts(opts) + + # Default is to prompt to mount the installed system. + anaconda.rescue_mount = not opts.rescue_nomount + + if opts.dlabel: #autodetected driverdisc in use + flags.dlabel = True + + anaconda.displayMode = opts.display_mode + anaconda.isHeadless = opts.isHeadless + + if opts.noipv4: + flags.useIPv4 = False + + if opts.noipv6: + flags.useIPv6 = False + + if opts.proxy: + anaconda.proxy = opts.proxy + + if opts.proxyAuth: + filename = opts.proxyAuth + ret = open(filename, "r").readlines() + os.unlink(filename) + + anaconda.proxyUsername = ret[0].rstrip() + if len(ret) == 2: + anaconda.proxyPassword = ret[1].rstrip() + + if opts.updateSrc: + anaconda.updateSrc = opts.updateSrc + + if opts.method: + if opts.method[0] == '@': + opts.method = expandFTPMethod(opts.method) + + anaconda.setMethodstr(opts.method) + else: + anaconda.methodstr = None + + if opts.stage2: + if opts.stage2[0] == '@': + opts.stage2 = expandFTPMethod(opts.stage2) + + anaconda.stage2 = opts.stage2 + + if opts.liveinst: + flags.livecdInstall = True + + if opts.module: + for mod in opts.module: + (path, name) = string.split(mod, ":") + anaconda.extraModules.append((path, name)) + + if opts.vnc: + flags.usevnc = 1 + anaconda.displayMode = 'g' + vncS.recoverVNCPassword() + + # Only consider vncconnect when vnc is a param + if opts.vncconnect: + cargs = string.split(opts.vncconnect, ":") + vncS.vncconnecthost = cargs[0] + if len(cargs) > 1 and len(cargs[1]) > 0: + if len(cargs[1]) > 0: + vncS.vncconnectport = cargs[1] + + if opts.ibft: + flags.ibft = 1 + + if opts.iscsi: + flags.iscsi = 1 + + if opts.targetArch: + flags.targetarch = opts.targetArch + + # set flags + flags.dmraid = opts.dmraid + flags.mpath = opts.mpath + flags.selinux = opts.selinux + + if opts.serial: + flags.serial = True + if opts.virtpconsole: + flags.virtpconsole = opts.virtpconsole + + if opts.xdriver: + anaconda.xdriver = opts.xdriver + anaconda.writeXdriver(root="/") + + if not flags.livecdInstall: + startAuditDaemon() + + # setup links required for all install types + for i in ( "services", "protocols", "nsswitch.conf", "joe", "selinux", + "mke2fs.conf" ): + try: + if os.path.exists("/mnt/runtime/etc/" + i): + os.symlink ("../mnt/runtime/etc/" + i, "/etc/" + i) + except: + pass + + # This is the one place we do all kickstart file parsing. + if opts.ksfile: + kickstart.preScriptPass(anaconda, opts.ksfile) + anaconda.ksdata = kickstart.parseKickstart(anaconda, opts.ksfile) + opts.rescue = anaconda.ksdata.rescue.rescue + + if flags.sshd: + # we need to have a libuser.conf that points to the installer root for + # sshpw, but after that we start sshd, we need one that points to the + # install target. + luserConf = users.createLuserConf(instPath="") + handleSshPw(anaconda) + startSsh() + del(os.environ["LIBUSER_CONF"]) + + users.createLuserConf(anaconda.rootPath) + + if opts.rescue: + anaconda.rescue = True + + import rescue + + if anaconda.ksdata: + anaconda.instClass.configure(anaconda) + + # We need an interface before running kickstart execute methods for + # storage. + from snack import * + screen = SnackScreen() + anaconda.intf = rescue.RescueInterface(screen) + + anaconda.ksdata.execute() + + anaconda.intf = None + screen.finish() + + # command line 'nomount' overrides kickstart /same for vnc/ + anaconda.rescue_mount = not (opts.rescue_nomount or anaconda.ksdata.rescue.nomount) + + rescue.runRescue(anaconda) + + # shouldn't get back here + sys.exit(1) + + if anaconda.ksdata: + if anaconda.ksdata.vnc.enabled: + flags.usevnc = 1 + anaconda.displayMode = 'g' + + if vncS.password == "": + vncS.password = anaconda.ksdata.vnc.password + + if vncS.vncconnecthost == "": + vncS.vncconnecthost = anaconda.ksdata.vnc.host + + if vncS.vncconnectport == "": + vncS.vncconnectport = anaconda.ksdata.vnc.port + + flags.vncquestion = False + + # disable VNC over text question when not enough memory is available + if iutil.memInstalled() < isys.MIN_GUI_RAM: + flags.vncquestion = False + + if os.environ.has_key('DISPLAY'): + flags.preexisting_x11 = True + + if anaconda.displayMode == 't' and flags.vncquestion: #we prefer vnc over text mode, so ask about that + title = _("Would you like to use VNC?") + message = _("Text mode provides a limited set of installation options. " + "It does not allow you to specify your own partitioning " + "layout or package selections. Would you like to use VNC " + "mode instead?") + + ret = vnc.askVncWindow(title, message) + if ret != -1: + anaconda.displayMode = 'g' + flags.usevnc = 1 + if ret is not None: + vncS.password = ret + + if opts.debug: + flags.debug = True + + log.info("anaconda called with cmdline = %s" %(sys.argv,)) + log.info("Display mode = %s" % anaconda.displayMode) + log.info("Default encoding = %s " % sys.getdefaultencoding()) + + check_memory(anaconda, opts) + + # + # now determine if we're going to run in GUI or TUI mode + # + # if no X server, we have to use text mode + if not flags.livecdInstall and not iutil.isS390() and not os.access("/usr/bin/Xorg", os.X_OK): + stdoutLog.warning(_("Graphical installation is not available. " + "Starting text mode.")) + time.sleep(2) + anaconda.displayMode = 't' + + # s390/iSeries checks + if anaconda.isHeadless and anaconda.displayMode == "g" and not \ + (flags.preexisting_x11 or flags.usevnc): + stdoutLog.warning(_("DISPLAY variable not set. Starting text mode.")) + anaconda.displayMode = 't' + graphical_failed = 1 + time.sleep(2) + + # if DISPLAY not set either vnc server failed to start or we're not + # running on a redirected X display, so start local X server + if anaconda.displayMode == 'g' and not flags.preexisting_x11 and not flags.usevnc: + try: + # The following code depends on no SIGCHLD being delivered, possibly + # only except the one from a failing X.org. Thus make sure before + # entering this section that all the other children of anaconda have + # terminated or were forked into an orphan (which won't deliver a + # SIGCHLD to mess up the fragile signaling below). + + # start X with its USR1 handler set to ignore. this will make it send + # us SIGUSR1 if it succeeds. if it fails, catch SIGCHLD and bomb out. + + def sigchld_handler(num, frame): + raise OSError + + def sigusr1_handler(num, frame): + pass + + def preexec_fn(): + signal.signal(signal.SIGUSR1, signal.SIG_IGN) + + old_sigusr1 = signal.signal(signal.SIGUSR1, sigusr1_handler) + old_sigchld = signal.signal(signal.SIGCHLD, sigchld_handler) + xout = open("/dev/tty5", "w") + + proc = subprocess.Popen(["Xorg", "-br", "-logfile", "/tmp/X.log", + ":1", "vt6", "-s", "1440", "-ac", + "-nolisten", "tcp", "-dpi", "96"], + close_fds=True, stdout=xout, stderr=xout, + preexec_fn=preexec_fn) + + signal.pause() + + os.environ["DISPLAY"] = ":1" + doStartupX11Actions(opts.runres) + xserver_pid = proc.pid + except (OSError, RuntimeError): + stdoutLog.warning(" X startup failed, falling back to text mode") + anaconda.displayMode = 't' + graphical_failed = 1 + time.sleep(2) + finally: + signal.signal(signal.SIGUSR1, old_sigusr1) + signal.signal(signal.SIGCHLD, old_sigchld) + + if anaconda.displayMode == 't' and graphical_failed and not anaconda.ksdata: + ret = vnc.askVncWindow() + if ret != -1: + anaconda.displayMode = 'g' + flags.usevnc = 1 + if ret is not None: + vncS.password = ret + + # if they want us to use VNC do that now + if anaconda.displayMode == 'g' and flags.usevnc: + runVNC() + doStartupX11Actions(opts.runres) + + # with X running we can initialize the UI interface + anaconda.initInterface() + anaconda.instClass.configure(anaconda) + + # comment out the next line to make exceptions non-fatal + from exception import initExceptionHandling + anaconda.mehConfig = initExceptionHandling(anaconda) + + # add our own additional signal handlers + signal.signal(signal.SIGUSR2, lambda signum, frame: anaconda.dumpState()) + + # download and run Dogtail script + if opts.dogtail: + try: + import urlgrabber + + try: + fr = urlgrabber.urlopen(opts.dogtail) + except urlgrabber.grabber.URLGrabError, e: + log.error("Could not retrieve Dogtail script from %s.\nError was\n%s" % (opts.dogtail, e)) + fr = None + + if fr: + (fw, testcase) = mkstemp(prefix='testcase.py.', dir='/tmp') + os.write(fw, fr.read()) + fr.close() + os.close(fw) + + # download completed, run the test + if not os.fork(): + # we are in the child + os.chmod(testcase, 0755) + os.execv(testcase, [testcase]) + sys.exit(0) + else: + # we are in the parent, sleep to give time for the testcase to initialize + # todo: is this needed, how to avoid possible race conditions + time.sleep(1) + except Exception, e: + log.error("Exception %s while running Dogtail testcase" % e) + + if opts.lang: + # this is lame, but make things match what we expect (#443408) + opts.lang = opts.lang.replace(".utf8", ".UTF-8") + anaconda.dispatch.skipStep("language", permanent = 1) + anaconda.instLanguage.instLang = opts.lang + anaconda.instLanguage.systemLang = opts.lang + anaconda.timezone.setTimezoneInfo(anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath)) + + if opts.keymap: + anaconda.dispatch.skipStep("keyboard", permanent = 1) + anaconda.keyboard.set(opts.keymap) + anaconda.keyboard.activate() + + if anaconda.ksdata: + import storage + storage.storageInitialize(anaconda) + + # Now having initialized storage, we can apply all the other kickstart + # commands. This gives us the ability to check that storage commands + # are correctly formed and refer to actual devices. + anaconda.ksdata.execute() + + # set up the headless case + if anaconda.isHeadless: + anaconda.dispatch.skipStep("keyboard", permanent = 1) + + if not anaconda.ksdata: + anaconda.instClass.setSteps(anaconda) + else: + kickstart.setSteps(anaconda) + + try: + anaconda.intf.run(anaconda) + except SystemExit, code: + anaconda.intf.shutdown() + + if anaconda.ksdata and anaconda.ksdata.reboot.eject: + for drive in anaconda.storage.devicetree.devices: + if drive.type != "cdrom": + continue + + log.info("attempting to eject %s" % drive.path) + drive.eject() + + del anaconda.intf + +# vim:tw=78:ts=4:et:sw=4 diff --git a/anaconda.py b/anaconda.py deleted file mode 100755 index b5532b0..0000000 --- a/anaconda.py +++ /dev/null @@ -1,932 +0,0 @@ -#!/usr/bin/python -# -# anaconda: The Red Hat Linux Installation program -# -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 -# Red Hat, Inc. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -# Author(s): Brent Fox <bfox@xxxxxxxxxx> -# Mike Fulbright <msf@xxxxxxxxxx> -# Jakub Jelinek <jakub@xxxxxxxxxx> -# Jeremy Katz <katzj@xxxxxxxxxx> -# Chris Lumens <clumens@xxxxxxxxxx> -# Paul Nasrat <pnasrat@xxxxxxxxxx> -# Erik Troan <ewt@xxxxxxxxx> -# Matt Wilson <msw@xxxxxxxxx> -# - -# This toplevel file is a little messy at the moment... - -import sys, os, re, time, subprocess -from optparse import OptionParser -from tempfile import mkstemp - -# keep up with process ID of the window manager if we start it -wm_pid = None - -# Make sure messages sent through python's warnings module get logged. -def AnacondaShowWarning(message, category, filename, lineno, file=sys.stderr, line=None): - log.warning("%s" % warnings.formatwarning(message, category, filename, lineno, line)) - -def startMetacityWM(): - childpid = os.fork() - if not childpid: - cmd = '/usr/bin/metacity' - if not os.access(cmd, os.X_OK): - log.error("Unable to find the window manager binary.") - sys.exit(1) - args = ['--display', ':1', - '--sm-disable'] - rc = iutil.execWithRedirect(cmd, args, - stdout='/dev/null', stderr='/dev/null') - if rc: - log.error("Error running window manager.") - sys.exit (rc) - else: - log.info("The window manager has terminated.") - sys.exit(0) - return childpid - -def startAuditDaemon(): - childpid = os.fork() - if not childpid: - cmd = '/sbin/auditd' - try: - os.execl(cmd, cmd) - except OSError as e: - log.error("Error running the audit daemon: %s" % str(e)) - sys.exit(0) - # auditd will turn into a daemon so catch the immediate child pid now: - os.waitpid(childpid, 0) - -# function to handle X startup special issues for anaconda -def doStartupX11Actions(runres="800x600"): - global wm_pid - - setupGraphicalLinks() - - # now start up the window manager - try: - wm_pid = startMetacityWM() - log.info("Starting window manager, pid %s." % (wm_pid,)) - except Exception: - wm_pid = None - log.error("Unable to start the window manager.") - - if wm_pid is not None: - import xutils - import gtk - - try: - xutils.setRootResource('Xcursor.size', '24') - xutils.setRootResource('Xcursor.theme', 'Bluecurve') - xutils.setRootResource('Xcursor.theme_core', 'true') - - xutils.setRootResource('Xft.antialias', '1') - xutils.setRootResource('Xft.hinting', '1') - xutils.setRootResource('Xft.hintstyle', 'hintslight') - xutils.setRootResource('Xft.rgba', 'none') - except: - sys.stderr.write("X SERVER STARTED, THEN FAILED"); - raise RuntimeError, "X server failed to start" - -def doShutdownX11Actions(): - global wm_pid - - if wm_pid is not None: - try: - os.kill(wm_pid, 15) - os.waitpid(wm_pid, 0) - except: - pass - -def setupPythonUpdates(): - from distutils.sysconfig import get_python_lib - - if not os.path.exists("/tmp/updates"): - return - - for pkg in os.listdir("/tmp/updates"): - d = "/tmp/updates/%s" % pkg - - if not os.path.isdir(d): - continue - - # See if the package exists in /usr/lib{64,}/python/?.?/site-packages. - # If it does, we can set it up as an update. If not, the pkg is - # likely a completely new directory and should not be looked at. - dest = "%s/%s" % (get_python_lib(), pkg) - if not os.access(dest, os.R_OK): - dest = "%s/%s" % (get_python_lib(1), pkg) - if not os.access(dest, os.R_OK): - continue - - contents = os.listdir(d) - - # Symlink over everything that's in the python libdir but not in - # the updates directory. - for f in filter(lambda fn: fn not in contents, os.listdir(dest)): - if f.endswith(".pyc") or f.endswith(".pyo"): - continue - - os.symlink("%s/%s" % (dest, f), "/tmp/updates/%s/%s" % (pkg, f)) - - - import glob - import shutil - for rule in glob.glob("/tmp/updates/*.rules"): - target = "/etc/udev/rules.d/" + rule.split('/')[-1] - shutil.copyfile(rule, target) - -def parseOptions(argv = None): - def resolution_cb (option, opt_str, value, parser): - parser.values.runres = value - - op = OptionParser() - # Interface - op.add_option("-C", "--cmdline", dest="display_mode", action="store_const", const="c", - default="g") - op.add_option("-G", "--graphical", dest="display_mode", action="store_const", const="g") - op.add_option("-T", "--text", dest="display_mode", action="store_const", const="t") - - # Network - op.add_option("--noipv4", action="store_true", default=False) - op.add_option("--noipv6", action="store_true", default=False) - op.add_option("--proxy") - op.add_option("--proxyAuth") - - # Method of operation - op.add_option("--autostep", action="store_true", default=False) - op.add_option("-d", "--debug", dest="debug", action="store_true", default=False) - op.add_option("--kickstart", dest="ksfile") - op.add_option("--rescue", dest="rescue", action="store_true", default=False) - op.add_option("--targetarch", dest="targetArch", nargs=1, type="string") - - op.add_option("-m", "--method", dest="method", default=None) - op.add_option("--repo", dest="method", default=None) - op.add_option("--stage2", dest="stage2", default=None) - - op.add_option("--liveinst", action="store_true", default=False) - - # Display - op.add_option("--headless", dest="isHeadless", action="store_true", default=False) - op.add_option("--nofb") - op.add_option("--resolution", action="callback", callback=resolution_cb, dest="runres", - default="800x600", nargs=1, type="string") - op.add_option("--serial", action="store_true", default=False) - op.add_option("--usefbx", dest="xdriver", action="store_const", const="fbdev") - op.add_option("--virtpconsole") - op.add_option("--vnc", action="store_true", default=False) - op.add_option("--vncconnect") - op.add_option("--xdriver", dest="xdriver", action="store", type="string", default=None) - - # Language - op.add_option("--keymap") - op.add_option("--kbdtype") - op.add_option("--lang") - - # Obvious - op.add_option("--loglevel") - op.add_option("--syslog") - - op.add_option("--noselinux", dest="selinux", action="store_false", default=True) - op.add_option("--selinux", action="store_true") - - op.add_option("--nompath", dest="mpath", action="store_false", default=True) - op.add_option("--mpath", action="store_true") - - op.add_option("--nodmraid", dest="dmraid", action="store_false", default=True) - op.add_option("--dmraid", action="store_true") - - op.add_option("--noibft", dest="ibft", action="store_false", default=True) - op.add_option("--ibft", action="store_true") - op.add_option("--noiscsi", dest="iscsi", action="store_false", default=False) - op.add_option("--iscsi", action="store_true") - - # Miscellaneous - op.add_option("--module", action="append", default=[]) - op.add_option("--nomount", dest="rescue_nomount", action="store_true", default=False) - op.add_option("--updates", dest="updateSrc", action="store", type="string") - op.add_option("--dogtail", dest="dogtail", action="store", type="string") - op.add_option("--dlabel", action="store_true", default=False) - - # Deprecated, unloved, unused - op.add_option("-r", "--rootPath", dest="unsupportedMode", - action="store_const", const="root path") - op.add_option("-t", "--test", dest="unsupportedMode", - action="store_const", const="test") - - return op.parse_args(argv) - -def setupPythonPath(): - haveUpdates = False - for ndx in range(len(sys.path)-1, -1, -1): - if sys.path[ndx].endswith('updates'): - haveUpdates = True - break - - # With anaconda being a real module this isn't strictly necessary, but - # setting up the path now prevents having to change every import line in - # anaconda. - from distutils.sysconfig import get_python_lib - d = get_python_lib(plat_specific=1) - - if haveUpdates: - sys.path.insert(ndx+1, "%s/pyanaconda" % d) - sys.path.insert(ndx+2, "%s/pyanaconda/textw" % d) - sys.path.insert(ndx+3, "%s/pyanaconda/iw" % d) - else: - sys.path.insert(0, "%s/pyanaconda" % d) - sys.path.insert(1, "%s/pyanaconda/textw" % d) - sys.path.insert(2, "%s/pyanaconda/iw" % d) - - sys.path.append('/usr/share/system-config-date') - -def addPoPath(dir): - """ Looks to see what translations are under a given path and tells - the gettext module to use that path as the base dir """ - for d in os.listdir(dir): - if not os.path.isdir("%s/%s" %(dir,d)): - continue - if not os.path.exists("%s/%s/LC_MESSAGES" %(dir,d)): - continue - for basename in os.listdir("%s/%s/LC_MESSAGES" %(dir,d)): - if not basename.endswith(".mo"): - continue - log.info("setting %s as translation source for %s" %(dir, basename[:-3])) - gettext.bindtextdomain(basename[:-3], dir) - -def setupTranslations(): - if os.path.isdir("/tmp/updates/po"): - addPoPath("/tmp/updates/po") - gettext.textdomain("anaconda") - -def setupEnvironment(): - # Silly GNOME stuff - if os.environ.has_key('HOME') and not os.environ.has_key("XAUTHORITY"): - os.environ['XAUTHORITY'] = os.environ['HOME'] + '/.Xauthority' - os.environ['HOME'] = '/tmp' - os.environ['LC_NUMERIC'] = 'C' - os.environ["GCONF_GLOBAL_LOCKS"] = "1" - - # In theory, this gets rid of our LVM file descriptor warnings - os.environ["LVM_SUPPRESS_FD_WARNINGS"] = "1" - - # make sure we have /sbin and /usr/sbin in our path - os.environ["PATH"] += ":/sbin:/usr/sbin" - - # we can't let the LD_PRELOAD hang around because it will leak into - # rpm %post and the like. ick :/ - if os.environ.has_key("LD_PRELOAD"): - del os.environ["LD_PRELOAD"] - - os.environ["GLADEPATH"] = "/tmp/updates/:/tmp/updates/ui/:ui/:/usr/share/anaconda/ui/:/usr/share/python-meh/" - os.environ["PIXMAPPATH"] = "/tmp/updates/pixmaps/:/tmp/updates/:/tmp/product/pixmaps/:/tmp/product/:pixmaps/:/usr/share/anaconda/pixmaps/:/usr/share/pixmaps/:/usr/share/anaconda/:/usr/share/python-meh/" - -def setupLoggingFromOpts(opts): - if opts.loglevel and anaconda_log.logLevelMap.has_key(opts.loglevel): - level = anaconda_log.logLevelMap[opts.loglevel] - anaconda_log.logger.tty_loglevel = level - anaconda_log.setHandlersLevel(log, level) - anaconda_log.setHandlersLevel(storage.storage_log.logger, level) - - if opts.syslog: - anaconda_log.logger.remote_syslog = opts.syslog - if opts.syslog.find(":") != -1: - (host, port) = opts.syslog.split(":") - anaconda_log.logger.addSysLogHandler(log, host, port=int(port)) - else: - anaconda_log.logger.addSysLogHandler(log, opts.syslog) - -# ftp installs pass the password via a file in /tmp so -# ps doesn't show it -def expandFTPMethod(str): - ret = None - - try: - filename = str[1:] - ret = open(filename, "r").readline() - ret = ret[:len(ret) - 1] - os.unlink(filename) - return ret - except: - return None - -def runVNC(): - global vncS - vncS.startServer() - - child = os.fork() - if child == 0: - for p in ('/tmp/updates/pyrc.py', \ - '/usr/share/anaconda/pyrc.py'): - if os.access(p, os.R_OK|os.X_OK): - os.environ['PYTHONSTARTUP'] = p - break - - while True: - # s390/s390x are the only places we /really/ need a shell on tty1, - # and everywhere else this just gets in the way of pdb. But we - # don't want to return, because that'll return try to start X - # a second time. - if iutil.isConsoleOnVirtualTerminal(): - time.sleep(10000) - else: - print _("Press <enter> for a shell") - sys.stdin.readline() - iutil.execConsole() - -def within_available_memory(needed_ram): - # kernel binary code estimate that is - # not reported in MemTotal by /proc/meminfo: - epsilon = 15360 # 15 MB - return needed_ram < (iutil.memInstalled() + epsilon) - -def check_memory(anaconda, opts, display_mode=None): - - if not display_mode: - display_mode = anaconda.displayMode - - extra_ram = 0 - reason = '' - if opts.stage2.startswith(('http', 'ftp', '@')): - extra_ram += isys.URL_INSTALL_EXTRA_RAM - reason = " using this install method" - - needed_ram = isys.MIN_RAM + extra_ram - if not within_available_memory(needed_ram): - from snack import SnackScreen, ButtonChoiceWindow - screen = SnackScreen() - ButtonChoiceWindow(screen, _('Fatal Error'), - _('You do not have enough RAM to install %s ' - 'on this machine%s.\n' - '\n' - 'Press <return> to reboot your system.\n') - %(product.productName, reason), - buttons = (_("OK"),)) - screen.finish() - sys.exit(0) - - # override display mode if machine cannot nicely run X - if display_mode not in ('t', 'c') and not flags.usevnc: - needed_ram = isys.MIN_GUI_RAM + extra_ram - - if not within_available_memory(needed_ram): - complain = _("You do not have enough RAM to use the graphical " - "installer.") - if flags.livecdInstall: - stdoutLog.warning(complain) - recommendation = _("Try the text mode installer by running:\n\n" - "'/usr/bin/liveinst -T'\n\n from a root " - "terminal.") - title = _("Not enough RAM") - text = "%s %s" %(complain, recommendation) - import gtk - dialog = gtk.MessageDialog(type = gtk.MESSAGE_ERROR, - buttons = gtk.BUTTONS_CLOSE, - message_format=text) - dialog.set_title(title) - dialog.run() - sys.exit(1) - else: - resolution = _("Starting text mode.") - stdoutLog.warning("%s %s" % (complain, resolution)) - anaconda.displayMode = 't' - time.sleep(2) - -def setupGraphicalLinks(): - for i in ( "imrc", "im_palette.pal", "gtk-2.0", "pango", "fonts", - "fb.modes"): - try: - if os.path.exists("/mnt/runtime/etc/%s" %(i,)): - os.symlink ("../mnt/runtime/etc/" + i, "/etc/" + i) - except: - pass - -def handleSshPw(anaconda): - if not anaconda.ksdata: - return - - import users - u = users.Users(anaconda) - - userdata = anaconda.ksdata.sshpw.dataList() - for ud in userdata: - if u.checkUserExists(ud.username, root="/"): - u.setUserPassword(username=ud.username, password=ud.password, - isCrypted=ud.isCrypted, lock=ud.lock) - else: - u.createUser(name=ud.username, password=ud.password, - isCrypted=ud.isCrypted, lock=ud.lock, - root="/") - - del u - -def createSshKey(algorithm, keyfile): - path = '/etc/ssh/%s' % (keyfile,) - argv = ['-q','-t',algorithm,'-f',path,'-C','','-N',''] - log.info("running \"%s\"" % (" ".join(['ssh-keygen']+argv),)) - - so = "/tmp/ssh-keygen-%s-stdout.log" % (algorithm,) - se = "/tmp/ssh-keygen-%s-stderr.log" % (algorithm,) - iutil.execWithRedirect('ssh-keygen', argv, stdout=so, stderr=se) - -def fork_orphan(): - """Forks an orphan. - - Returns 1 in the parent and 0 in the orphaned child. - """ - intermediate = os.fork() - if not intermediate: - if os.fork(): - # the intermediate child dies - os._exit(0) - return 0; - # the original process waits for the intermediate child - os.waitpid(intermediate, 0) - return 1 - -def startSsh(): - if iutil.isS390(): - return - - if not fork_orphan(): - os.mkdir("/var/log", 0755) - os.open("/var/log/lastlog", os.O_RDWR | os.O_CREAT, 0644) - ssh_keys = { - 'rsa1':'ssh_host_key', - 'rsa':'ssh_host_rsa_key', - 'dsa':'ssh_host_dsa_key', - } - for (algorithm, keyfile) in ssh_keys.items(): - createSshKey(algorithm, keyfile) - args = ["/sbin/sshd", "-f", "/etc/ssh/sshd_config.anaconda"] - os.execv("/sbin/sshd", args) - sys.exit(1) - -def startDebugger(signum, frame): - import epdb - epdb.serve(skip=1) - -if __name__ == "__main__": - setupPythonPath() - - # Allow a file to be loaded as early as possible - try: - import updates_disk_hook - except ImportError: - pass - - # Set up logging as early as possible. - import logging - import anaconda_log - anaconda_log.init() - - log = logging.getLogger("anaconda") - stdoutLog = logging.getLogger("anaconda.stdout") - - if os.geteuid() != 0: - stdoutLog.error("anaconda must be run as root.") - sys.exit(0) - - # pull this in to get product name and versioning - import product - - # this handles setting up updates for pypackages to minimize the set needed - setupPythonUpdates() - - import isys - isys.initLog() - - import signal, string, iutil, time - import warnings - import vnc - import users - import kickstart - import storage.storage_log - - from flags import flags - - # the following makes me very sad. -- katzj - # we have a slightly different set of udev rules in the second - # stage than the first stage. why this doesn't get picked up - # automatically, I don't know. but we need to trigger so that we - # have all the information about netdevs that we care about for - # NetworkManager in the udev database - from baseudev import udev_trigger, udev_settle - udev_trigger("net") - udev_settle() - # and for added fun, once doesn't seem to be enough? so we - # do it twice, it works and we scream at the world "OH WHY?" - udev_trigger("net") - udev_settle() - - import gettext - _ = lambda x: gettext.ldgettext("anaconda", x) - - from pyanaconda import Anaconda - anaconda = Anaconda() - warnings.showwarning = AnacondaShowWarning - setupTranslations() - - # reset python's default SIGINT handler - signal.signal(signal.SIGINT, signal.SIG_DFL) - signal.signal(signal.SIGSEGV, isys.handleSegv) - - setupEnvironment() - - pidfile = open("/var/run/anaconda.pid", "w") - pidfile.write("%s\n" % (os.getpid(),)) - del pidfile - # add our own additional signal handlers - signal.signal(signal.SIGHUP, startDebugger) - - # we need to do this really early so we make sure its done before rpm - # is imported - iutil.writeRpmPlatform() - - graphical_failed = 0 - vncS = vnc.VncServer() # The vnc Server object. - vncS.anaconda = anaconda - xserver_pid = None - - (opts, args) = parseOptions() - - # check memory, just the text mode for now: - check_memory(anaconda, opts, 't') - - if opts.unsupportedMode: - stdoutLog.error("Running anaconda in %s mode is no longer supported." % opts.unsupportedMode) - sys.exit(0) - - # Now that we've got arguments, do some extra processing. - setupLoggingFromOpts(opts) - - # Default is to prompt to mount the installed system. - anaconda.rescue_mount = not opts.rescue_nomount - - if opts.dlabel: #autodetected driverdisc in use - flags.dlabel = True - - anaconda.displayMode = opts.display_mode - anaconda.isHeadless = opts.isHeadless - - if opts.noipv4: - flags.useIPv4 = False - - if opts.noipv6: - flags.useIPv6 = False - - if opts.proxy: - anaconda.proxy = opts.proxy - - if opts.proxyAuth: - filename = opts.proxyAuth - ret = open(filename, "r").readlines() - os.unlink(filename) - - anaconda.proxyUsername = ret[0].rstrip() - if len(ret) == 2: - anaconda.proxyPassword = ret[1].rstrip() - - if opts.updateSrc: - anaconda.updateSrc = opts.updateSrc - - if opts.method: - if opts.method[0] == '@': - opts.method = expandFTPMethod(opts.method) - - anaconda.setMethodstr(opts.method) - else: - anaconda.methodstr = None - - if opts.stage2: - if opts.stage2[0] == '@': - opts.stage2 = expandFTPMethod(opts.stage2) - - anaconda.stage2 = opts.stage2 - - if opts.liveinst: - flags.livecdInstall = True - - if opts.module: - for mod in opts.module: - (path, name) = string.split(mod, ":") - anaconda.extraModules.append((path, name)) - - if opts.vnc: - flags.usevnc = 1 - anaconda.displayMode = 'g' - vncS.recoverVNCPassword() - - # Only consider vncconnect when vnc is a param - if opts.vncconnect: - cargs = string.split(opts.vncconnect, ":") - vncS.vncconnecthost = cargs[0] - if len(cargs) > 1 and len(cargs[1]) > 0: - if len(cargs[1]) > 0: - vncS.vncconnectport = cargs[1] - - if opts.ibft: - flags.ibft = 1 - - if opts.iscsi: - flags.iscsi = 1 - - if opts.targetArch: - flags.targetarch = opts.targetArch - - # set flags - flags.dmraid = opts.dmraid - flags.mpath = opts.mpath - flags.selinux = opts.selinux - - if opts.serial: - flags.serial = True - if opts.virtpconsole: - flags.virtpconsole = opts.virtpconsole - - if opts.xdriver: - anaconda.xdriver = opts.xdriver - anaconda.writeXdriver(root="/") - - if not flags.livecdInstall: - startAuditDaemon() - - # setup links required for all install types - for i in ( "services", "protocols", "nsswitch.conf", "joe", "selinux", - "mke2fs.conf" ): - try: - if os.path.exists("/mnt/runtime/etc/" + i): - os.symlink ("../mnt/runtime/etc/" + i, "/etc/" + i) - except: - pass - - # This is the one place we do all kickstart file parsing. - if opts.ksfile: - kickstart.preScriptPass(anaconda, opts.ksfile) - anaconda.ksdata = kickstart.parseKickstart(anaconda, opts.ksfile) - opts.rescue = anaconda.ksdata.rescue.rescue - - if flags.sshd: - # we need to have a libuser.conf that points to the installer root for - # sshpw, but after that we start sshd, we need one that points to the - # install target. - luserConf = users.createLuserConf(instPath="") - handleSshPw(anaconda) - startSsh() - del(os.environ["LIBUSER_CONF"]) - - users.createLuserConf(anaconda.rootPath) - - if opts.rescue: - anaconda.rescue = True - - import rescue - - if anaconda.ksdata: - anaconda.instClass.configure(anaconda) - - # We need an interface before running kickstart execute methods for - # storage. - from snack import * - screen = SnackScreen() - anaconda.intf = rescue.RescueInterface(screen) - - anaconda.ksdata.execute() - - anaconda.intf = None - screen.finish() - - # command line 'nomount' overrides kickstart /same for vnc/ - anaconda.rescue_mount = not (opts.rescue_nomount or anaconda.ksdata.rescue.nomount) - - rescue.runRescue(anaconda) - - # shouldn't get back here - sys.exit(1) - - if anaconda.ksdata: - if anaconda.ksdata.vnc.enabled: - flags.usevnc = 1 - anaconda.displayMode = 'g' - - if vncS.password == "": - vncS.password = anaconda.ksdata.vnc.password - - if vncS.vncconnecthost == "": - vncS.vncconnecthost = anaconda.ksdata.vnc.host - - if vncS.vncconnectport == "": - vncS.vncconnectport = anaconda.ksdata.vnc.port - - flags.vncquestion = False - - # disable VNC over text question when not enough memory is available - if iutil.memInstalled() < isys.MIN_GUI_RAM: - flags.vncquestion = False - - if os.environ.has_key('DISPLAY'): - flags.preexisting_x11 = True - - if anaconda.displayMode == 't' and flags.vncquestion: #we prefer vnc over text mode, so ask about that - title = _("Would you like to use VNC?") - message = _("Text mode provides a limited set of installation options. " - "It does not allow you to specify your own partitioning " - "layout or package selections. Would you like to use VNC " - "mode instead?") - - ret = vnc.askVncWindow(title, message) - if ret != -1: - anaconda.displayMode = 'g' - flags.usevnc = 1 - if ret is not None: - vncS.password = ret - - if opts.debug: - flags.debug = True - - log.info("anaconda called with cmdline = %s" %(sys.argv,)) - log.info("Display mode = %s" % anaconda.displayMode) - log.info("Default encoding = %s " % sys.getdefaultencoding()) - - check_memory(anaconda, opts) - - # - # now determine if we're going to run in GUI or TUI mode - # - # if no X server, we have to use text mode - if not flags.livecdInstall and not iutil.isS390() and not os.access("/usr/bin/Xorg", os.X_OK): - stdoutLog.warning(_("Graphical installation is not available. " - "Starting text mode.")) - time.sleep(2) - anaconda.displayMode = 't' - - # s390/iSeries checks - if anaconda.isHeadless and anaconda.displayMode == "g" and not \ - (flags.preexisting_x11 or flags.usevnc): - stdoutLog.warning(_("DISPLAY variable not set. Starting text mode.")) - anaconda.displayMode = 't' - graphical_failed = 1 - time.sleep(2) - - # if DISPLAY not set either vnc server failed to start or we're not - # running on a redirected X display, so start local X server - if anaconda.displayMode == 'g' and not flags.preexisting_x11 and not flags.usevnc: - try: - # The following code depends on no SIGCHLD being delivered, possibly - # only except the one from a failing X.org. Thus make sure before - # entering this section that all the other children of anaconda have - # terminated or were forked into an orphan (which won't deliver a - # SIGCHLD to mess up the fragile signaling below). - - # start X with its USR1 handler set to ignore. this will make it send - # us SIGUSR1 if it succeeds. if it fails, catch SIGCHLD and bomb out. - - def sigchld_handler(num, frame): - raise OSError - - def sigusr1_handler(num, frame): - pass - - def preexec_fn(): - signal.signal(signal.SIGUSR1, signal.SIG_IGN) - - old_sigusr1 = signal.signal(signal.SIGUSR1, sigusr1_handler) - old_sigchld = signal.signal(signal.SIGCHLD, sigchld_handler) - xout = open("/dev/tty5", "w") - - proc = subprocess.Popen(["Xorg", "-br", "-logfile", "/tmp/X.log", - ":1", "vt6", "-s", "1440", "-ac", - "-nolisten", "tcp", "-dpi", "96"], - close_fds=True, stdout=xout, stderr=xout, - preexec_fn=preexec_fn) - - signal.pause() - - os.environ["DISPLAY"] = ":1" - doStartupX11Actions(opts.runres) - xserver_pid = proc.pid - except (OSError, RuntimeError): - stdoutLog.warning(" X startup failed, falling back to text mode") - anaconda.displayMode = 't' - graphical_failed = 1 - time.sleep(2) - finally: - signal.signal(signal.SIGUSR1, old_sigusr1) - signal.signal(signal.SIGCHLD, old_sigchld) - - if anaconda.displayMode == 't' and graphical_failed and not anaconda.ksdata: - ret = vnc.askVncWindow() - if ret != -1: - anaconda.displayMode = 'g' - flags.usevnc = 1 - if ret is not None: - vncS.password = ret - - # if they want us to use VNC do that now - if anaconda.displayMode == 'g' and flags.usevnc: - runVNC() - doStartupX11Actions(opts.runres) - - # with X running we can initialize the UI interface - anaconda.initInterface() - anaconda.instClass.configure(anaconda) - - # comment out the next line to make exceptions non-fatal - from exception import initExceptionHandling - anaconda.mehConfig = initExceptionHandling(anaconda) - - # add our own additional signal handlers - signal.signal(signal.SIGUSR2, lambda signum, frame: anaconda.dumpState()) - - # download and run Dogtail script - if opts.dogtail: - try: - import urlgrabber - - try: - fr = urlgrabber.urlopen(opts.dogtail) - except urlgrabber.grabber.URLGrabError, e: - log.error("Could not retrieve Dogtail script from %s.\nError was\n%s" % (opts.dogtail, e)) - fr = None - - if fr: - (fw, testcase) = mkstemp(prefix='testcase.py.', dir='/tmp') - os.write(fw, fr.read()) - fr.close() - os.close(fw) - - # download completed, run the test - if not os.fork(): - # we are in the child - os.chmod(testcase, 0755) - os.execv(testcase, [testcase]) - sys.exit(0) - else: - # we are in the parent, sleep to give time for the testcase to initialize - # todo: is this needed, how to avoid possible race conditions - time.sleep(1) - except Exception, e: - log.error("Exception %s while running Dogtail testcase" % e) - - if opts.lang: - # this is lame, but make things match what we expect (#443408) - opts.lang = opts.lang.replace(".utf8", ".UTF-8") - anaconda.dispatch.skipStep("language", permanent = 1) - anaconda.instLanguage.instLang = opts.lang - anaconda.instLanguage.systemLang = opts.lang - anaconda.timezone.setTimezoneInfo(anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath)) - - if opts.keymap: - anaconda.dispatch.skipStep("keyboard", permanent = 1) - anaconda.keyboard.set(opts.keymap) - anaconda.keyboard.activate() - - if anaconda.ksdata: - import storage - storage.storageInitialize(anaconda) - - # Now having initialized storage, we can apply all the other kickstart - # commands. This gives us the ability to check that storage commands - # are correctly formed and refer to actual devices. - anaconda.ksdata.execute() - - # set up the headless case - if anaconda.isHeadless: - anaconda.dispatch.skipStep("keyboard", permanent = 1) - - if not anaconda.ksdata: - anaconda.instClass.setSteps(anaconda) - else: - kickstart.setSteps(anaconda) - - try: - anaconda.intf.run(anaconda) - except SystemExit, code: - anaconda.intf.shutdown() - - if anaconda.ksdata and anaconda.ksdata.reboot.eject: - for drive in anaconda.storage.devicetree.devices: - if drive.type != "cdrom": - continue - - log.info("attempting to eject %s" % drive.path) - drive.eject() - - del anaconda.intf - -# vim:tw=78:ts=4:et:sw=4 diff --git a/bin/Makefile.am b/bin/Makefile.am index 53a5c44..d8b3e7d 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -17,7 +17,7 @@ # # Author: Martin Sivak <msivak@xxxxxxxxxx> -SUBDIRS = loader gptsync +SUBDIRS = isys loader gptsync MAINTAINERCLEANFILES = Makefile.in diff --git a/bin/isys/.gitignore b/bin/isys/.gitignore new file mode 100644 index 0000000..0b04e81 --- /dev/null +++ b/bin/isys/.gitignore @@ -0,0 +1,6 @@ +*.pyc +.depend +*.lo +*.do +nfs_mountversion.h +auditd diff --git a/bin/isys/Makefile.am b/bin/isys/Makefile.am new file mode 100644 index 0000000..8b5dd00 --- /dev/null +++ b/bin/isys/Makefile.am @@ -0,0 +1,56 @@ +# isys/Makefile.am for anaconda +# +# Copyright (C) 2009 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author: David Cantrell <dcantrell@xxxxxxxxxx> + +pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME) + +ISYS_SRCS = devices.c imount.c cpio.c uncpio.c lang.c \ + isofs.c linkdetect.c vio.c ethtool.c eddsupport.c iface.c \ + auditd.c log.c + +dist_noinst_HEADERS = *.h + +ISYS_CFLAGS = -DVERSION='"$(PACKAGE_VERSION)"' $(NFS_CFLAGS) \ + $(NETWORKMANAGER_CFLAGS) $(LIBNL_CFLAGS) $(LIBNM_GLIB_CFLAGS) \ + $(SELINUX_CFLAGS) +ISYS_LIBS = $(RESOLV_LIBS) $(EXT2FS_LIBS) $(ZLIB_LIBS) \ + $(DEVMAPPER_LIBS) $(BLKID_LIBS) $(X11_LIBS) $(SELINUX_LIBS) \ + $(LIBNL_LIBS) $(LIBNM_GLIB_LIBS) + +isysdir = $(pkgpyexecdir)/isys +isys_PYTHON = *.py + +pkgpyexec_LTLIBRARIES = _isys.la +_isys_la_CFLAGS = $(PYTHON_INCLUDES) $(ISYS_CFLAGS) +_isys_la_LDFLAGS = -module -avoid-version $(PYTHON_LDFLAGS) +_isys_la_LIBADD = $(PYTHON_LIBS) $(ISYS_LIBS) +_isys_la_SOURCES = isys.c $(ISYS_SRCS) + +noinst_LTLIBRARIES = libisys.la +libisys_la_CFLAGS = $(ISYS_CFLAGS) +libisys_la_LDFLAGS = -static +libisys_la_LIBADD = $(ISYS_LIBS) +libisys_la_SOURCES = $(ISYS_SRCS) + +auditddir = $(libexecdir)/$(PACKAGE_NAME) +auditd_PROGRAMS = auditd +auditd_SOURCES = auditd.c +auditd_CFLAGS = -DSTANDALONE $(SELINUX_CFLAGS) +auditd_LDADD = $(SELINUX_LIBS) $(LIBNL_LIBS) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/bin/isys/__init__.py b/bin/isys/__init__.py new file mode 100755 index 0000000..eb9a010 --- /dev/null +++ b/bin/isys/__init__.py @@ -0,0 +1,560 @@ +# +# isys.py - installer utility functions and glue for C module +# +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. +# All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Author(s): Matt Wilson <msw@xxxxxxxxxx> +# Erik Troan <ewt@xxxxxxxxxx> +# Jeremy Katz <katzj@xxxxxxxxxx> +# + +import _isys +import string +import os +import os.path +import socket +import stat +import posix +import sys +import pyanaconda.iutil as iutil +import warnings +import resource +import re +import struct +import block +import dbus +import selinux + +import logging +log = logging.getLogger("anaconda") + +NM_SERVICE = "org.freedesktop.NetworkManager" +NM_MANAGER_PATH = "/org/freedesktop/NetworkManager" +NM_MANAGER_IFACE = "org.freedesktop.NetworkManager" +NM_ACTIVE_CONNECTION_IFACE = "org.freedesktop.NetworkManager.Connection.Active" +NM_CONNECTION_IFACE = "org.freedesktop.NetworkManagerSettings.Connection" +NM_DEVICE_IFACE = "org.freedesktop.NetworkManager.Device" + +NM_STATE_UNKNOWN = 0 +NM_STATE_ASLEEP = 1 +NM_STATE_CONNECTING = 2 +NM_STATE_CONNECTED = 3 +NM_STATE_DISCONNECTED = 4 + +DBUS_PROPS_IFACE = "org.freedesktop.DBus.Properties" + +mountCount = {} + +MIN_RAM = _isys.MIN_RAM +MIN_GUI_RAM = _isys.MIN_GUI_RAM +URL_INSTALL_EXTRA_RAM = _isys.URL_INSTALL_EXTRA_RAM +EARLY_SWAP_RAM = _isys.EARLY_SWAP_RAM + +## Get the amount of free space available under a directory path. +# @param path The directory path to check. +# @return The amount of free space available, in +def pathSpaceAvailable(path): + return _isys.devSpaceFree(path) + +## Set up an already existing device node to be used as a loopback device. +# @param device The full path to a device node to set up as a loopback device. +# @param file The file to mount as loopback on device. +# @param readOnly Should this loopback device be used read-only? +def losetup(device, file, readOnly = 0): + # FIXME: implement this as a storage.devices.Device subclass + if readOnly: + mode = os.O_RDONLY + else: + mode = os.O_RDWR + targ = os.open(file, mode) + loop = os.open(device, mode) + try: + _isys.losetup(loop, targ, file) + finally: + os.close(loop) + os.close(targ) + +def lochangefd(device, file): + # FIXME: implement this as a storage.devices.Device subclass + loop = os.open(device, os.O_RDONLY) + targ = os.open(file, os.O_RDONLY) + try: + _isys.lochangefd(loop, targ) + finally: + os.close(loop) + os.close(targ) + +## Disable a previously setup loopback device. +# @param device The full path to an existing loopback device node. +def unlosetup(device): + # FIXME: implement this as a storage.devices.Device subclass + loop = os.open(device, os.O_RDONLY) + try: + _isys.unlosetup(loop) + finally: + os.close(loop) + +## Mount a filesystem, similar to the mount system call. +# @param device The device to mount. If bindMount is True, this should be an +# already mounted directory. Otherwise, it should be a device +# name. +# @param location The path to mount device on. +# @param fstype The filesystem type on device. This can be disk filesystems +# such as vfat or ext3, or pseudo filesystems such as proc or +# selinuxfs. +# @param readOnly Should this filesystem be mounted readonly? +# @param bindMount Is this a bind mount? (see the mount(8) man page) +# @param remount Are we mounting an already mounted filesystem? +# @return The return value from the mount system call. +def mount(device, location, fstype = "ext2", readOnly = False, + bindMount = False, remount = False, options = None): + flags = None + location = os.path.normpath(location) + if not options: + opts = ["defaults"] + else: + opts = options.split(",") + + # We don't need to create device nodes for devices that start with '/' + # (like '/usbdevfs') and also some special fake devices like 'proc'. + # First try to make a device node and if that fails, assume we can + # mount without making a device node. If that still fails, the caller + # will have to deal with the exception. + # We note whether or not we created a node so we can clean up later. + + if mountCount.has_key(location) and mountCount[location] > 0: + mountCount[location] = mountCount[location] + 1 + return + + if readOnly or bindMount or remount: + if readOnly: + opts.append("ro") + if bindMount: + opts.append("bind") + if remount: + opts.append("remount") + + flags = ",".join(opts) + + log.debug("isys.py:mount()- going to mount %s on %s as %s with options %s" %(device, location, fstype, flags)) + rc = _isys.mount(fstype, device, location, flags) + + if not rc: + mountCount[location] = 1 + + return rc + +## Unmount a filesystem, similar to the umount system call. +# @param what The directory to be unmounted. This does not need to be the +# absolute path. +# @param removeDir Should the mount point be removed after being unmounted? +# @return The return value from the umount system call. +def umount(what, removeDir = True): + what = os.path.normpath(what) + + if not os.path.isdir(what): + raise ValueError, "isys.umount() can only umount by mount point" + + if mountCount.has_key(what) and mountCount[what] > 1: + mountCount[what] = mountCount[what] - 1 + return + + log.debug("isys.py:umount()- going to unmount %s, removeDir = %s" % (what, removeDir)) + rc = _isys.umount(what) + + if removeDir and os.path.isdir(what): + try: + os.rmdir(what) + except: + pass + + if not rc and mountCount.has_key(what): + del mountCount[what] + + return rc + +## Disable swap. +# @param path The full path of the swap device to disable. +def swapoff (path): + return _isys.swapoff (path) + +## Enable swap. +# @param path The full path of the swap device to enable. +def swapon (path): + return _isys.swapon (path) + +## Load a keyboard layout for text mode installs. +# @param keymap The keyboard layout to load. This must be one of the values +# from rhpl.KeyboardModels. +def loadKeymap(keymap): + return _isys.loadKeymap (keymap) + +def resetResolv(): + return _isys.resetresolv() + +def readFSUuid(device): + if not os.path.exists(device): + device = "/dev/%s" % device + + label = _isys.getblkid(device, "UUID") + return label + +def readFSLabel(device): + if not os.path.exists(device): + device = "/dev/%s" % device + + label = _isys.getblkid(device, "LABEL") + return label + +def readFSType(device): + if not os.path.exists(device): + device = "/dev/%s" % device + + fstype = _isys.getblkid(device, "TYPE") + if fstype is None: + # FIXME: libblkid doesn't show physical volumes as having a filesystem + # so let's sniff for that.(#409321) + try: + fd = os.open(device, os.O_RDONLY) + buf = os.read(fd, 2048) + except: + return fstype + finally: + try: + os.close(fd) + except: + pass + + if buf.startswith("HM"): + return "physical volume (LVM)" + for sec in range(0, 4): + off = (sec * 512) + 24 + if len(buf) < off: + continue + if buf[off:].startswith("LVM2"): + return "physical volume (LVM)" + elif fstype == "lvm2pv": + return "physical volume (LVM)" + return fstype + +def ext2IsDirty(device): + label = _isys.e2dirty(device) + return label + +def ext2HasJournal(device): + hasjournal = _isys.e2hasjournal(device) + return hasjournal + +def modulesWithPaths(): + mods = [] + for modline in open("/proc/modules", "r"): + modName = modline.split(" ", 1)[0] + modInfo = iutil.execWithCapture("modinfo", + ["-F", "filename", modName]).splitlines() + modPaths = [ line.strip() for line in modInfo if line!="" ] + mods.extend(modPaths) + return mods + +def driveUsesModule(device, modules): + """Returns true if a drive is using a prticular module. Only works + for SCSI devices right now.""" + + if not isinstance(modules, ().__class__) and not \ + isinstance(modules, [].__class__): + modules = [modules] + + if device[:2] == "hd": + return False + rc = False + if os.access("/tmp/scsidisks", os.R_OK): + sdlist=open("/tmp/scsidisks", "r") + sdlines = sdlist.readlines() + sdlist.close() + for l in sdlines: + try: + # each line has format of: <device> <module> + (sddev, sdmod) = string.split(l) + + if sddev == device: + if sdmod in modules: + rc = True + break + except: + pass + return rc + +def vtActivate (num): + if iutil.isS390(): + return + _isys.vtActivate (num) + +def isPseudoTTY (fd): + return _isys.isPseudoTTY (fd) + +## Flush filesystem buffers. +def sync (): + return _isys.sync () + +## Determine if a file is an ISO image or not. +# @param file The full path to a file to check. +# @return True if ISO image, False otherwise. +def isIsoImage(file): + return _isys.isisoimage(file) + +# Return number of network devices +def getNetworkDeviceCount(): + bus = dbus.SystemBus() + nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH) + devlist = nm.get_dbus_method("GetDevices")() + return len(devlist) + +# Get a D-Bus interface for the specified device's (e.g., eth0) properties. +# If dev=None, return a hash of the form 'hash[dev] = props_iface' that +# contains all device properties for all interfaces that NetworkManager knows +# about. +def getDeviceProperties(dev=None): + bus = dbus.SystemBus() + nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH) + devlist = nm.get_dbus_method("GetDevices")() + all = {} + + for path in devlist: + device = bus.get_object(NM_SERVICE, path) + device_props_iface = dbus.Interface(device, DBUS_PROPS_IFACE) + + device_interface = str(device_props_iface.Get(NM_MANAGER_IFACE, "Interface")) + + if dev is None: + all[device_interface] = device_props_iface + elif device_interface == dev: + return device_props_iface + + if dev is None: + return all + else: + return None + +# Return true if method is currently 'dhcp' for the specified device. +def isDeviceDHCP(dev=None): + if dev is None: + return False + + bus = dbus.SystemBus() + nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH) + nm_props_iface = dbus.Interface(nm, DBUS_PROPS_IFACE) + active_connections = nm_props_iface.Get(NM_MANAGER_IFACE, "ActiveConnections") + + for path in active_connections: + active = bus.get_object(NM_SERVICE, path) + active_props_iface = dbus.Interface(active, DBUS_PROPS_IFACE) + + active_service_name = active_props_iface.Get(NM_ACTIVE_CONNECTION_IFACE, "ServiceName") + active_path = active_props_iface.Get(NM_ACTIVE_CONNECTION_IFACE, "Connection") + active_devices = active_props_iface.Get(NM_ACTIVE_CONNECTION_IFACE, "Devices") + + device = bus.get_object(NM_SERVICE, active_devices[0]) + device_props_iface = dbus.Interface(device, DBUS_PROPS_IFACE) + iface = device_props_iface.Get(NM_DEVICE_IFACE, "Interface") + + if iface != dev: + continue + + connection = bus.get_object(active_service_name, active_path) + connection_iface = dbus.Interface(connection, NM_CONNECTION_IFACE) + settings = connection_iface.GetSettings() + + ip4_setting = settings.get('ipv4') + if not ip4_setting or not ip4_setting['method'] or ip4_setting['method'] == 'auto': + return True + + return False + +# Get the MAC address for a network device. +def getMacAddress(dev): + if dev == '' or dev is None: + return False + + device_props_iface = getDeviceProperties(dev=dev) + if device_props_iface is None: + return None + + device_macaddr = None + try: + device_macaddr = device_props_iface.Get(NM_MANAGER_IFACE, "HwAddress").upper() + except dbus.exceptions.DBusException as e: + if e.get_dbus_name() != 'org.freedesktop.DBus.Error.InvalidArgs': + raise + return device_macaddr + +# Get a description string for a network device (e.g., eth0) +def getNetDevDesc(dev): + from baseudev import udev_get_device + desc = "Network Interface" + + if dev == '' or dev is None: + return desc + + bus = dbus.SystemBus() + nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH) + devlist = nm.get_dbus_method("GetDevices")() + + for path in devlist: + device = bus.get_object(NM_SERVICE, path) + device_iface = dbus.Interface(device, DBUS_PROPS_IFACE) + device_props = device_iface.get_dbus_method("GetAll")(NM_DEVICE_IFACE) + + if dev == device_props['Interface']: + # This is the sysfs path (for now). + udev_path = device_props['Udi'] + dev = udev_get_device(udev_path[4:]) + + if dev is None: + log.debug("weird, we have a None dev with path %s" % path) + elif dev.has_key("ID_VENDOR_ENC") and dev.has_key("ID_MODEL_ENC"): + desc = "%s %s" % (dev["ID_VENDOR_ENC"], dev["ID_MODEL_ENC"]) + elif dev.has_key("ID_VENDOR_FROM_DATABASE") and dev.has_key("ID_MODEL_FROM_DATABASE"): + desc = "%s %s" % (dev["ID_VENDOR_FROM_DATABASE"], dev["ID_MODEL_FROM_DATABASE"]) + + return desc + + return desc + +# Determine if a network device is a wireless device. +def isWireless(dev): + if dev == '' or dev is None: + return False + + device_props_iface = getDeviceProperties(dev=dev) + if device_props_iface is None: + return None + + device_type = int(device_props_iface.Get(NM_MANAGER_IFACE, "DeviceType")) + + # from include/NetworkManager.h in the NM source code + # 0 == NM_DEVICE_TYPE_UNKNOWN + # 1 == NM_DEVICE_TYPE_ETHERNET + # 2 == NM_DEVICE_TYPE_WIFI + # 3 == NM_DEVICE_TYPE_GSM + # 4 == NM_DEVICE_TYPE_CDMA + if device_type == 2: + return True + else: + return False + +# Get the IP address for a network device. +def getIPAddress(dev): + if dev == '' or dev is None: + return None + + device_props_iface = getDeviceProperties(dev=dev) + if device_props_iface is None: + return None + + # XXX: add support for IPv6 addresses when NM can do that + device_ip4addr = device_props_iface.Get(NM_MANAGER_IFACE, "Ip4Address") + + try: + tmp = struct.pack('I', device_ip4addr) + address = socket.inet_ntop(socket.AF_INET, tmp) + except ValueError, e: + return None + + return address + +## Get the correct context for a file from loaded policy. +# @param fn The filename to query. +def matchPathContext(fn): + con = None + try: + con = selinux.matchpathcon(os.path.normpath(fn), 0)[1] + except OSError as e: + log.info("failed to get default SELinux context for %s: %s" % (fn, e)) + return con + +## Set the SELinux file context of a file +# @param fn The filename to fix. +# @param con The context to use. +# @param instroot An optional root filesystem to look under for fn. +def setFileContext(fn, con, instroot = '/'): + full_path = os.path.normpath("%s/%s" % (instroot, fn)) + rc = False + if con is not None and os.access(full_path, os.F_OK): + try: + rc = (selinux.lsetfilecon(full_path, con) == 0) + except OSError as e: + log.info("failed to set SELinux context for %s: %s" % (full_path, e)) + return rc + +## Restore the SELinux file context of a file to its default. +# @param fn The filename to fix. +# @param instroot An optional root filesystem to look under for fn. +def resetFileContext(fn, instroot = '/'): + con = matchPathContext(fn) + if con: + if setFileContext(fn, con, instroot): + return con + return None + +def prefix2netmask(prefix): + return _isys.prefix2netmask(prefix) + +def netmask2prefix (netmask): + prefix = 0 + + while prefix < 33: + if (prefix2netmask(prefix) == netmask): + return prefix + + prefix += 1 + + return prefix + +isPAE = None +def isPaeAvailable(): + global isPAE + if isPAE is not None: + return isPAE + + isPAE = False + if not iutil.isX86(): + return isPAE + + f = open("/proc/cpuinfo", "r") + lines = f.readlines() + f.close() + + for line in lines: + if line.startswith("flags") and line.find("pae") != -1: + isPAE = True + break + + return isPAE + +def getLinkStatus(dev): + return _isys.getLinkStatus(dev) + +def getAnacondaVersion(): + return _isys.getAnacondaVersion() + +auditDaemon = _isys.auditdaemon + +handleSegv = _isys.handleSegv + +printObject = _isys.printObject +bind_textdomain_codeset = _isys.bind_textdomain_codeset +isVioConsole = _isys.isVioConsole +initLog = _isys.initLog diff --git a/bin/isys/auditd.c b/bin/isys/auditd.c new file mode 100644 index 0000000..2ca6d04 --- /dev/null +++ b/bin/isys/auditd.c @@ -0,0 +1,134 @@ +/* + * auditd.c: This is a simple audit daemon that throws all messages away. + * + * Copyright (C) 2006 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Peter Jones <pjones@xxxxxxxxxx> + */ + +#define _GNU_SOURCE 1 + +#include <sys/types.h> +#include <sys/syscall.h> +#include <sys/poll.h> +#include <unistd.h> +#include <fcntl.h> +#include <signal.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> + +#include <libaudit.h> + +#include "auditd.h" + +#ifdef USESELINUX +static int done; + +static void sig_done(int sig) +{ + done = 1; +} + +static void do_auditd(int fd) { + struct audit_reply rep; + sigset_t sigs; + struct sigaction sa; + struct pollfd pds = { + .events = POLLIN, + .revents = 0, + .fd = fd, + }; + + if (audit_set_pid(fd, getpid(), WAIT_YES) < 0) + return; + + if (audit_set_enabled(fd, 1) < 0) + return; + + memset(&sa, '\0', sizeof (sa)); + sa.sa_handler = sig_done; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + sigaction(SIGHUP, &sa, NULL); + + sigfillset(&sigs); + sigdelset(&sigs, SIGTERM); + sigdelset(&sigs, SIGINT); + sigdelset(&sigs, SIGHUP); + + while (1) { + int retval; + + memset(&rep, 0, sizeof(rep)); + + do { + retval = ppoll(&pds, 1, NULL, &sigs); + } while (retval == -1 && errno == EINTR && !done); + + if (done) + break; + + if (audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0) > 0) { + /* we don't actually want to do anything here. */ + ; + } + } + return; +} +#endif /* USESELINUX */ + +int audit_daemonize(void) { +#ifdef USESELINUX + int fd; + pid_t child; + int i; + if ((child = fork()) > 0) + return 0; + +#ifndef STANDALONE + for (i = 0; i < getdtablesize(); i++) + close(i); + signal(SIGTTOU, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGTSTP, SIG_IGN); +#endif /* !defined(STANDALONE) */ + + if ((fd = open("/proc/self/oom_adj", O_RDWR)) >= 0) { + i = write(fd, "-17", 3); + close(fd); + } + fd = audit_open(); + do_auditd(fd); + audit_close(fd); + +#ifndef STANDALONE + exit(0); +#endif /* !defined(STANDALONE) */ + +#endif /* USESELINUX */ + return 0; +} + +#ifdef STANDALONE +int main(void) { + return audit_daemonize(); +} +#endif /* STANDALONE */ + +/* + * vim:ts=8:sw=4:sts=4:et + */ diff --git a/bin/isys/auditd.h b/bin/isys/auditd.h new file mode 100644 index 0000000..55ec5ce --- /dev/null +++ b/bin/isys/auditd.h @@ -0,0 +1,30 @@ +/* + * auditd.h: This is a simple audit daemon that throws all messages away. + * + * Copyright (C) 2006 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Peter Jones <pjones@xxxxxxxxxx> + */ + +#ifndef ISYS_AUDIT_H +#define ISYS_AUDIT_H 1 + +extern int audit_daemonize(void); + +#endif /* ISYS_AUDIT_H */ +/* + * vim:ts=8:sw=4:sts=4:et + */ diff --git a/bin/isys/cpio.c b/bin/isys/cpio.c new file mode 100644 index 0000000..fd83605 --- /dev/null +++ b/bin/isys/cpio.c @@ -0,0 +1,46 @@ +/* + * cpio.c + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "cpio.h" + +int installCpioFile(gzFile fd, char * cpioName, char * outName, int inWin) { + struct cpioFileMapping map; + int rc; + const char * failedFile; + + if (outName) { + map.archivePath = cpioName; + map.fsPath = outName; + map.mapFlags = CPIO_MAP_PATH; + } + + rc = myCpioInstallArchive(fd, outName ? &map : NULL, 1, NULL, NULL, + &failedFile); + + if (rc || access(outName, R_OK)) { + return -1; + } + + return 0; +} diff --git a/bin/isys/cpio.h b/bin/isys/cpio.h new file mode 100644 index 0000000..4cbb7c0 --- /dev/null +++ b/bin/isys/cpio.h @@ -0,0 +1,102 @@ +/* + * cpio.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef H_CPIO +#define H_CPIO + +#include <sys/types.h> + +#include "stubs.h" + +/* Note the CPIO_CHECK_ERRNO bit is set only if errno is valid. These have to + be positive numbers or this setting the high bit stuff is a bad idea. */ +#define CPIOERR_CHECK_ERRNO 0x80000000 + +#define CPIOERR_BAD_MAGIC (2 ) +#define CPIOERR_BAD_HEADER (3 ) +#define CPIOERR_OPEN_FAILED (4 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_CHMOD_FAILED (5 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_CHOWN_FAILED (6 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_WRITE_FAILED (7 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_UTIME_FAILED (8 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_UNLINK_FAILED (9 | CPIOERR_CHECK_ERRNO) + +#define CPIOERR_SYMLINK_FAILED (11 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_STAT_FAILED (12 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_MKDIR_FAILED (13 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_MKNOD_FAILED (14 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_MKFIFO_FAILED (15 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_LINK_FAILED (16 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_READLINK_FAILED (17 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_READ_FAILED (18 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_COPY_FAILED (19 | CPIOERR_CHECK_ERRNO) +#define CPIOERR_INTERNAL (20 ) +#define CPIOERR_HDR_SIZE (21 ) +#define CPIOERR_UNKNOWN_FILETYPE (22 ) + + +/* Don't think this behaves just like standard cpio. It's pretty close, but + it has some behaviors which are more to RPM's liking. I tried to document + them inline in cpio.c, but I may have missed some. */ + +#define CPIO_MAP_PATH (1 << 0) +#define CPIO_MAP_MODE (1 << 1) +#define CPIO_MAP_UID (1 << 2) +#define CPIO_MAP_GID (1 << 3) +#define CPIO_FOLLOW_SYMLINKS (1 << 4) /* only for building */ + +struct cpioFileMapping { + char * archivePath; + char * fsPath; + mode_t finalMode; + uid_t finalUid; + gid_t finalGid; + int mapFlags; +}; + +/* on cpio building, only "file" is filled in */ +struct cpioCallbackInfo { + char * file; + long fileSize; /* total file size */ + long fileComplete; /* amount of file unpacked */ + long bytesProcessed; /* bytes in archive read */ +}; + +typedef void (*cpioCallback)(struct cpioCallbackInfo * filespec, void * data); + +/* If no mappings are passed, this installs everything! If one is passed + it should be sorted according to cpioFileMapCmp() and only files included + in the map are installed. Files are installed relative to the current + directory unless a mapping is given which specifies an absolute + directory. The mode mapping is only used for the permission bits, not + for the file type. The owner/group mappings are ignored for the nonroot + user. If *failedFile is non-NULL on return, it should be free()d. */ +int myCpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings, + int numMappings, cpioCallback cb, void * cbData, + const char ** failedFile); +int myCpioFilterArchive(gzFile inStream, gzFile outStream, char ** pattern); + +/* This is designed to be qsort/bsearch compatible */ +int myCpioFileMapCmp(const void * a, const void * b); + +const char *myCpioStrerror(int rc); + +int installCpioFile(gzFile fd, char * cpioName, char * outName, int inWin); + +#endif diff --git a/bin/isys/devices.c b/bin/isys/devices.c new file mode 100644 index 0000000..53130d1 --- /dev/null +++ b/bin/isys/devices.c @@ -0,0 +1,221 @@ +/* + * devices.c - various hardware probing functionality + * + * Copyright (C) 2007 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Bill Nottingham <notting@xxxxxxxxxx> + */ + +#include <ctype.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <limits.h> + +#include "devices.h" + +/* for 'disks', to filter out weird stuff */ +#define MINIMUM_INTERESTING_SIZE 32*1024 /* 32MB */ + +/* from genhd.h, kernel side */ +#define GENHD_FL_REMOVABLE 1 +#define GENHD_FL_DRIVERFS 2 +#define GENHD_FL_MEDIA_CHANGE_NOTIFY 4 +#define GENHD_FL_CD 8 +#define GENHD_FL_UP 16 +#define GENHD_FL_SUPPRESS_PARTITION_INFO 32 +#define GENHD_FL_FAIL 64 + + +struct device **getDevices(enum deviceType type) { + struct device **ret = NULL; + struct device *new; + int numdevices = 0; + + if (type & (DEVICE_DISK | DEVICE_CDROM)) { + DIR *dir; + struct dirent *ent; + + dir = opendir("/sys/block"); + + if (!dir) goto storagedone; + + while ((ent = readdir(dir))) { + char path[64]; + char buf[64]; + int fd, caps, devtype; + + snprintf(path, 64, "/sys/block/%s/capability", ent->d_name); + fd = open(path, O_RDONLY); + if (fd == -1) + continue; + if (read(fd, buf, 63) <= 0) { + close(fd); + continue; + } + + close(fd); + errno = 0; + caps = strtol(buf, NULL, 16); + + if ((errno == ERANGE && (caps == LONG_MIN || caps == LONG_MAX)) || + (errno != 0 && caps == 0)) { + return NULL; + } + + if (caps & GENHD_FL_CD) + devtype = DEVICE_CDROM; + else + devtype = DEVICE_DISK; + if (!(devtype & type)) + continue; + + if (devtype == DEVICE_DISK && !(caps & GENHD_FL_REMOVABLE)) { + int size; + + snprintf(path, 64, "/sys/block/%s/size", ent->d_name); + fd = open(path, O_RDONLY); + + if (fd == -1) + continue; + if (read(fd, buf, 63) <= 0) { + close(fd); + continue; + } + + close(fd); + errno = 0; + size = strtol(buf, NULL, 10); + + if ((errno == ERANGE && (size == LONG_MIN || + size == LONG_MAX)) || + (errno != 0 && size == 0)) { + return NULL; + } + + if (size < MINIMUM_INTERESTING_SIZE) + continue; + } + + new = calloc(1, sizeof(struct device)); + new->device = strdup(ent->d_name); + /* FIXME */ + if (asprintf(&new->description, "Storage device %s", + new->device) == -1) { + fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, + strerror(errno)); + fflush(stderr); + abort(); + } + new->type = devtype; + if (caps & GENHD_FL_REMOVABLE) { + new->priv.removable = 1; + } + ret = realloc(ret, (numdevices+2) * sizeof(struct device)); + ret[numdevices] = new; + ret[numdevices+1] = NULL; + numdevices++; + } + + closedir(dir); + } +storagedone: + + if (type & DEVICE_NETWORK) { + DIR *dir; + struct dirent *ent; + + dir = opendir("/sys/class/net"); + + if (!dir) goto netdone; + + while ((ent = readdir(dir))) { + char path[64]; + int fd, type; + char buf[64]; + + snprintf(path, 64, "/sys/class/net/%s/type", ent->d_name); + fd = open(path, O_RDONLY); + if (fd == -1) + continue; + if (read(fd, buf, 63) <= 0) { + close(fd); + continue; + } + + close(fd); + errno = 0; + type = strtol(buf, NULL, 10); + + if ((errno == ERANGE && (type == LONG_MIN || type == LONG_MAX)) || + (errno != 0 && type == 0)) { + return NULL; + } + + if (type != 1) + continue; + + new = calloc(1, sizeof(struct device)); + new->device = strdup(ent->d_name); + /* FIXME */ + snprintf(path, 64, "/sys/class/net/%s/address", ent->d_name); + fd = open(path, O_RDONLY); + if (fd != -1) { + memset(buf, '\0', 64); + if (read(fd, buf, 63) > 0) { + int i; + for (i = (strlen(buf)-1); isspace(buf[i]); i--) + buf[i] = '\0'; + new->priv.hwaddr = strdup(buf); + } + } + + if (new->priv.hwaddr) { + if (asprintf(&new->description, "Ethernet device %s - %s", + new->device, new->priv.hwaddr) == -1) { + fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, + strerror(errno)); + fflush(stderr); + abort(); + } + } else { + if (asprintf(&new->description, "Ethernet device %s", + new->device) == -1) { + fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, + strerror(errno)); + fflush(stderr); + abort(); + } + } + + ret = realloc(ret, (numdevices+2) * sizeof(struct device)); + ret[numdevices] = new; + ret[numdevices+1] = NULL; + numdevices++; + } + + closedir(dir); + } +netdone: + return ret; +} + diff --git a/bin/isys/devices.h b/bin/isys/devices.h new file mode 100644 index 0000000..9428a77 --- /dev/null +++ b/bin/isys/devices.h @@ -0,0 +1,42 @@ +/* + * devices.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DEVICES_H +#define DEVICES_H + +enum deviceType { + DEVICE_ANY = ~0, + DEVICE_NETWORK = (1 << 0), + DEVICE_DISK = (1 << 1), + DEVICE_CDROM = (1 << 2) +}; + +struct device { + char *device; + char *description; + enum deviceType type; + union { + char *hwaddr; + int removable; + } priv; +}; + +struct device **getDevices(enum deviceType type); + +#endif diff --git a/bin/isys/eddsupport.c b/bin/isys/eddsupport.c new file mode 100644 index 0000000..c50278e --- /dev/null +++ b/bin/isys/eddsupport.c @@ -0,0 +1,339 @@ +/* + * eddsupport.c - handling of mapping disk drives in Linux to disk drives + * according to the BIOS using the edd kernel module + * + * Copyright (C) 2004 Dell, Inc. All rights reserved. + * Copyright (C) 2004 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Rezwanul_Kabir@xxxxxxxx + * Jeremy Katz <katzj@xxxxxxxxxx> + */ + +#include <ctype.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/reboot.h> +#include <sys/types.h> +#include <linux/types.h> + + +#include "eddsupport.h" +#include "devices.h" +#include "isys.h" + +#define EDD_DIR "/sys/firmware/edd" +#define SIG_FILE "mbr_signature" +#define MBRSIG_OFFSET 0x1b8 + +#define HASH_TABLE_SIZE 17 + + +struct diskMapEntry{ + uint32_t key; + char *diskname; + struct diskMapEntry *next; +}; + +struct diskMapTable { + struct diskMapEntry **table; + int tableSize; +}; + +static struct diskMapTable *mbrSigToName = NULL; +static int diskHashInit = 0; + + + +static struct diskMapTable* initializeHashTable(int); +static int insertHashItem(struct diskMapTable *, struct diskMapEntry *); +static struct diskMapEntry* lookupHashItem(struct diskMapTable *, uint32_t); +static int addToHashTable(struct diskMapTable *, uint32_t , char *); +static struct device ** createDiskList(); +static int mapBiosDisks(struct device ** , const char *); +static int readDiskSig(char *, uint32_t *); +static int readMbrSig(char *, uint32_t *); + +/* This is the top level function that creates a disk list present in the + * system, checks to see if unique signatures exist on the disks at offset + * 0x1b8. If a unique signature exists then it will map BIOS disks to their + * corresponding hd/sd device names. Otherwise, we'll avoid mapping drives. + */ + +int probeBiosDisks() { + struct device ** devices = NULL; + + devices = createDiskList(); + if(!devices){ +#ifdef STANDALONE + fprintf(stderr, "No disks!\n"); +#endif + return -1; + } + + if(!mapBiosDisks(devices, EDD_DIR)){ +#ifdef STANDALONE + fprintf(stderr, "WARNING: couldn't map BIOS disks\n"); +#endif + return -1; + } + return 0; +} + + +static struct device ** createDiskList(){ + return getDevices (DEVICE_DISK); +} + +static int readDiskSig(char *device, uint32_t *disksig) { + int fd, rc; + char devnodeName[64]; + + snprintf(devnodeName, sizeof(devnodeName), "/dev/%s", device); + fd = open(devnodeName, O_RDONLY); + if (fd < 0) { +#ifdef STANDALONE + fprintf(stderr, "Error opening device %s: %s\n ", device, + strerror(errno)); +#endif + return -errno; + } + + rc = lseek(fd, MBRSIG_OFFSET, SEEK_SET); + if (rc < 0){ + close(fd); + +#ifdef STANDALONE + fprintf(stderr, "Error seeking to MBRSIG_OFFSET in %s: %s\n", + device, strerror(errno)); +#endif + return -1; + } + + rc = read(fd, disksig, sizeof(uint32_t)); + if (rc < sizeof(uint32_t)) { + close(fd); + +#ifdef STANDALONE + fprintf(stderr, "Failed to read signature from %s\n", device); +#endif + return -1; + } + + close(fd); + return 0; +} + +static int mapBiosDisks(struct device** devices,const char *path) { + DIR *dirHandle; + struct dirent *entry; + char * sigFileName; + uint32_t mbrSig, biosNum, currentSig; + struct device **currentDev, **foundDisk; + int i, rc, ret, dm_nr, highest_dm; + + dirHandle = opendir(path); + if(!dirHandle){ +#ifdef STANDALONE + fprintf(stderr, "Failed to open directory %s: %s\n", path, + strerror(errno)); +#endif + return 0; + } + + mbrSigToName = initializeHashTable(HASH_TABLE_SIZE); + if(!mbrSigToName){ +#ifdef STANDALONE + fprintf(stderr, "Error initializing mbrSigToName table\n"); +#endif + closedir(dirHandle); + return 0; + } + + while ((entry = readdir(dirHandle)) != NULL) { + if(!strncmp(entry->d_name,".",1) || !strncmp(entry->d_name,"..",2)) { + continue; + } + ret = sscanf((entry->d_name+9), "%x", &biosNum); + + sigFileName = malloc(strlen(path) + strlen(entry->d_name) + 20); + sprintf(sigFileName, "%s/%s/%s", path, entry->d_name, SIG_FILE); + if (readMbrSig(sigFileName, &mbrSig) == 0) { + for (currentDev = devices, i = 0, foundDisk=NULL, highest_dm=-1; + (*currentDev) != NULL; + currentDev++) { + if (!(*currentDev)->device) + continue; + + if ((rc=readDiskSig((*currentDev)->device, ¤tSig)) < 0) { + if (rc == -ENOMEDIUM || rc == -ENXIO) + continue; + closedir(dirHandle); + return 0; + } + + if (mbrSig == currentSig) { + /* When we have a fakeraid setup we will find multiple hits + a number for the raw disks (1 when striping, 2 when + mirroring, more with raid on raid like raid 01 or 10) + and a number for the dm devices (normally only one dm + device will match, but more with raid on raid). + Since with raid on raid the last dm device created + will be the top layer raid, we want the highest matching + dm device. */ + if (!strncmp((*currentDev)->device, "dm-", 3) && + sscanf((*currentDev)->device+3, "%d", &dm_nr) == 1) { + if (dm_nr > highest_dm) { + highest_dm = dm_nr; + foundDisk=currentDev; + i = 1; + } + } else if (!foundDisk || + strncmp((*foundDisk)->device, "dm-", 3)) { + foundDisk=currentDev; + i++; + } + } + } + + if (i==1) { + if(!addToHashTable(mbrSigToName, (uint32_t)biosNum, + (*foundDisk)->device)) { + closedir(dirHandle); + return 0; + } + } + } + } + closedir(dirHandle); + return 1; +} + + +static int readMbrSig(char *filename, uint32_t *int_sig){ + FILE* fh; + + fh = fopen(filename,"r"); + if(fh == NULL) { +#ifdef STANDALONE + fprintf(stderr, "Error opening mbr_signature file %s: %s\n", filename, + strerror(errno)); +#endif + return -1; + } + fseek(fh, 0, SEEK_SET); + if (fscanf(fh, "%x", int_sig) != 1) { +#ifdef STANDALONE + fprintf(stderr, "Error reading %s\n", filename); +#endif + fclose(fh); + return -1; + } + + fclose(fh); + return 0; +} + + +static struct diskMapTable* initializeHashTable(int size) { + struct diskMapTable *hashTable; + + hashTable = malloc(sizeof(struct diskMapTable)); + hashTable->tableSize = size; + hashTable->table = malloc(sizeof(struct diskMapEntry *) * size); + memset(hashTable->table,0,(sizeof(struct diskMapEntry *) * size)); + return hashTable; +} + + +static int insertHashItem(struct diskMapTable *hashTable, + struct diskMapEntry *hashItem) { + int index; + + index = (hashItem->key) % (hashTable->tableSize); + + if(hashTable->table[index] == NULL){ + hashTable->table[index] = hashItem; + return index; + } else { + hashItem->next = hashTable->table[index]; + hashTable->table[index] = hashItem; + return index; + } +} + + +static struct diskMapEntry * lookupHashItem(struct diskMapTable *hashTable, + uint32_t itemKey) { + int index; + struct diskMapEntry *hashItem; + + index = itemKey % (hashTable->tableSize); + for (hashItem = hashTable->table[index]; + (hashItem != NULL) && (hashItem->key != itemKey); + hashItem = hashItem->next) { + ; + } + return hashItem; +} + + +static int addToHashTable(struct diskMapTable *hashTable, + uint32_t itemKey, char *diskName) { + int index; + struct diskMapEntry *diskSigToNameEntry; + + diskSigToNameEntry = malloc(sizeof(struct diskMapEntry)); + diskSigToNameEntry->next = NULL; + diskSigToNameEntry->key = itemKey; + diskSigToNameEntry->diskname = diskName; + + if ((index = insertHashItem(hashTable, diskSigToNameEntry)) < 0){ +#ifdef STANDALONE + fprintf(stderr, "Unable to insert item\n"); +#endif + return 0; + } else { + return 1; + } +} + + +char * getBiosDisk(char *biosStr) { + uint32_t biosNum; + struct diskMapEntry * disk; + int ret; + + if (diskHashInit == 0) { + probeBiosDisks(); + diskHashInit = 1; + } + + if (mbrSigToName == NULL) + return NULL; + + ret = sscanf(biosStr,"%x",&biosNum); + disk = lookupHashItem(mbrSigToName, biosNum); + if (disk) return disk->diskname; + + return NULL; +} diff --git a/bin/isys/eddsupport.h b/bin/isys/eddsupport.h new file mode 100644 index 0000000..77fc4c4 --- /dev/null +++ b/bin/isys/eddsupport.h @@ -0,0 +1,28 @@ +/* + * eddsupport.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef EDDSUPPORT_H +#define EDDSUPPORT_H + +int probeBiosDisks(); +char* getBiosDisk(char *); + +#endif + + diff --git a/bin/isys/ethtool.c b/bin/isys/ethtool.c new file mode 100644 index 0000000..871f1d4 --- /dev/null +++ b/bin/isys/ethtool.c @@ -0,0 +1,119 @@ +/* + * ethtool.c - setting of basic ethtool options + * + * Copyright (C) 2003 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Jeremy Katz <katzj@xxxxxxxxxx> + */ + +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <net/if.h> + +#include <linux/sockios.h> +#include "ethtool.h" + +static int set_intf_up(struct ifreq ifr, int sock) { + if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { + return (-1); + } + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) { + fprintf(stderr, "failed to bring up interface %s: %s", ifr.ifr_name, + strerror(errno)); + return -1; + } + return (0); +} + +int setEthtoolSettings(char * dev, ethtool_speed speed, + ethtool_duplex duplex) { + int sock, err; + struct ethtool_cmd ecmd; + struct ifreq ifr; + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("Unable to create socket"); + return -1; + } + + /* Setup our control structures. */ + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, dev); + + if (set_intf_up(ifr, sock) == -1) { + fprintf(stderr, "unable to bring up interface %s: %s", dev, + strerror(errno)); + return -1; + } + + ecmd.cmd = ETHTOOL_GSET; + ifr.ifr_data = (caddr_t)&ecmd; + err = ioctl(sock, SIOCETHTOOL, &ifr); + if (err < 0) { + perror("Unable to get settings via ethtool. Not setting"); + return -1; + } + + if (speed != ETHTOOL_SPEED_UNSPEC) + ecmd.speed = speed; + if (duplex != ETHTOOL_DUPLEX_UNSPEC) + ecmd.duplex = duplex; + if ((duplex != ETHTOOL_DUPLEX_UNSPEC) || (speed != ETHTOOL_SPEED_UNSPEC)) + ecmd.autoneg = AUTONEG_DISABLE; + + ecmd.cmd = ETHTOOL_SSET; + ifr.ifr_data = (caddr_t)&ecmd; + err = ioctl(sock, SIOCETHTOOL, &ifr); + if (err < 0) { + // perror("Unable to set settings via ethtool. Not setting"); + return -1; + } + + return 0; +} + +int identifyNIC(char *iface, int seconds) { + int sock; + struct ethtool_value edata; + struct ifreq ifr; + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("Unable to create socket"); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + memset(&edata, 0, sizeof(edata)); + + strcpy(ifr.ifr_name, iface); + edata.cmd = ETHTOOL_PHYS_ID; + edata.data = seconds; + ifr.ifr_data = (caddr_t) &edata; + + if (ioctl(sock, SIOCETHTOOL, &ifr) < 0) { + perror("Unable to identify NIC"); + } + + return 0; +} diff --git a/bin/isys/ethtool.h b/bin/isys/ethtool.h new file mode 100644 index 0000000..57b4ffc --- /dev/null +++ b/bin/isys/ethtool.h @@ -0,0 +1,41 @@ +/* + * net.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ISYSNET_H +#define ISYSNET_H + +#include <linux/types.h> +#include <linux/ethtool.h> + +/* returns 1 for link, 0 for no link, -1 for unknown */ +int get_link_status(char *ifname); + +typedef enum ethtool_speed_t { ETHTOOL_SPEED_UNSPEC = -1, + ETHTOOL_SPEED_10 = SPEED_10, + ETHTOOL_SPEED_100 = SPEED_100, + ETHTOOL_SPEED_1000 = SPEED_1000 } ethtool_speed; +typedef enum ethtool_duplex_t { ETHTOOL_DUPLEX_UNSPEC = -1, + ETHTOOL_DUPLEX_HALF = DUPLEX_HALF, + ETHTOOL_DUPLEX_FULL = DUPLEX_FULL } ethtool_duplex; + +/* set ethtool settings */ +int setEthtoolSettings(char * dev, ethtool_speed speed, ethtool_duplex duplex); +int identifyNIC(char *iface, int seconds); + +#endif diff --git a/bin/isys/iface.c b/bin/isys/iface.c new file mode 100644 index 0000000..5897286 --- /dev/null +++ b/bin/isys/iface.c @@ -0,0 +1,543 @@ +/* + * iface.c - Network interface configuration API + * + * Copyright (C) 2006, 2007, 2008 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): David Cantrell <dcantrell@xxxxxxxxxx> + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/utsname.h> +#include <arpa/inet.h> +#include <dirent.h> +#include <fcntl.h> +#include <netdb.h> +#include <signal.h> +#include <netinet/in.h> + +#include <netlink/netlink.h> +#include <netlink/socket.h> +#include <netlink/route/rtnl.h> +#include <netlink/route/route.h> +#include <netlink/route/addr.h> +#include <netlink/route/link.h> + +#include <glib.h> +#include <NetworkManager.h> +#include <nm-client.h> +#include <nm-device.h> +#include <nm-ip4-config.h> +#include <nm-setting-ip4-config.h> + +#include "isys.h" +#include "iface.h" + +/* Internal-only function prototypes. */ +static struct nl_handle *_iface_get_handle(void); +static struct nl_cache *_iface_get_link_cache(struct nl_handle **); +static int _iface_have_valid_addr(void *addr, int family, int length); +static int _iface_redirect_io(char *device, int fd, int mode); + +/* + * Return a libnl handle for NETLINK_ROUTE. + */ +static struct nl_handle *_iface_get_handle(void) { + struct nl_handle *handle = NULL; + + if ((handle = nl_handle_alloc()) == NULL) { + return NULL; + } + + if (nl_connect(handle, NETLINK_ROUTE)) { + nl_handle_destroy(handle); + return NULL; + } + + return handle; +} + +/* + * Return an NETLINK_ROUTE cache. + */ +static struct nl_cache *_iface_get_link_cache(struct nl_handle **handle) { + struct nl_cache *cache = NULL; + + if ((*handle = _iface_get_handle()) == NULL) { + return NULL; + } + + if ((cache = rtnl_link_alloc_cache(*handle)) == NULL) { + nl_close(*handle); + nl_handle_destroy(*handle); + return NULL; + } + + return cache; +} + +/* + * Determine if a struct in_addr or struct in6_addr contains a valid address. + */ +static int _iface_have_valid_addr(void *addr, int family, int length) { + char buf[length+1]; + + if ((addr == NULL) || (family != AF_INET && family != AF_INET6)) { + return 0; + } + + memset(buf, '\0', sizeof(buf)); + + if (inet_ntop(family, addr, buf, length) == NULL) { + return 0; + } else { + /* check for unknown addresses */ + if (family == AF_INET) { + if (!strncmp(buf, "0.0.0.0", 7)) { + return 0; + } + } else if (family == AF_INET6) { + if (!strncmp(buf, "::", 2)) { + return 0; + } + } + } + + return 1; +} + +/* + * Redirect I/O to another device (e.g., stdout to /dev/tty5) + */ +int _iface_redirect_io(char *device, int fd, int mode) { + int io = -1; + + if ((io = open(device, mode)) == -1) { + return 1; + } + + if (close(fd) == -1) { + return 2; + } + + if (dup2(io, fd) == -1) { + return 3; + } + + if (close(io) == -1) { + return 4; + } + + return 0; +} + +/* + * Given an interface name (e.g., eth0) and address family (e.g., AF_INET), + * return the IP address in human readable format (i.e., the output from + * inet_ntop()). Return NULL for no match or error. + */ +char *iface_ip2str(char *ifname, int family) { + int i; + NMClient *client = NULL; + NMIP4Config *ip4config = NULL; + NMIP4Address *ipaddr = NULL; + NMDevice *candidate = NULL; + struct in_addr tmp_addr; + const GPtrArray *devices; + const char *iface; + char ipstr[INET_ADDRSTRLEN+1]; + + if (ifname == NULL) { + return NULL; + } + + /* DCFIXME: add IPv6 once NM gains support */ + if (family != AF_INET) { + return NULL; + } + + g_type_init(); + + client = nm_client_new(); + if (!client) { + return NULL; + } + + if (nm_client_get_state(client) != NM_STATE_CONNECTED) { + g_object_unref(client); + return NULL; + } + + devices = nm_client_get_devices(client); + for (i=0; i < devices->len; i++) { + candidate = g_ptr_array_index(devices, i); + iface = nm_device_get_iface(candidate); + + if (nm_device_get_state(candidate) != NM_DEVICE_STATE_ACTIVATED) + continue; + + if (!iface || strcmp(iface, ifname)) + continue; + + if (!(ip4config = nm_device_get_ip4_config(candidate))) + continue; + + if (!(ipaddr = nm_ip4_config_get_addresses(ip4config)->data)) + continue; + + memset(&ipstr, '\0', sizeof(ipstr)); + tmp_addr.s_addr = nm_ip4_address_get_address(ipaddr); + + if (inet_ntop(AF_INET, &tmp_addr, ipstr, INET_ADDRSTRLEN) == NULL) { + g_object_unref(client); + return NULL; + } + + g_object_unref(client); + return g_strdup(ipstr); + } + + g_object_unref(client); + return NULL; +} + +/* Given an interface's MAC address, return the name (e.g., eth0) in human + * readable format. Return NULL for no match + */ +char *iface_mac2device(char *mac) { + struct nl_handle *handle = NULL; + struct nl_cache *cache = NULL; + struct rtnl_link *link = NULL; + struct nl_addr *mac_as_nl_addr = NULL; + char *retval = NULL; + int i, n; + + if (mac == NULL) { + return NULL; + } + + if ((mac_as_nl_addr = nl_addr_parse(mac, AF_LLC)) == NULL) { + return NULL; + } + + if ((cache = _iface_get_link_cache(&handle)) == NULL) { + return NULL; + } + + n = nl_cache_nitems(cache); + for (i = 0; i <= n; i++) { + struct nl_addr *addr; + + if ((link = rtnl_link_get(cache, i)) == NULL) { + continue; + } + + addr = rtnl_link_get_addr(link); + + if (!nl_addr_cmp(mac_as_nl_addr, addr)) { + retval = strdup(rtnl_link_get_name(link)); + rtnl_link_put(link); + break; + } + + rtnl_link_put(link); + } + + nl_close(handle); + nl_handle_destroy(handle); + + return retval; +} + +/* + * Given an interface name (e.g., eth0), return the MAC address in human + * readable format (e.g., 00:11:52:12:D9:A0). Return NULL for no match. + */ +char *iface_mac2str(char *ifname) { + int buflen = 20; + char *buf = NULL; + struct nl_handle *handle = NULL; + struct nl_cache *cache = NULL; + struct rtnl_link *link = NULL; + struct nl_addr *addr = NULL; + + if (ifname == NULL) { + return NULL; + } + + if ((cache = _iface_get_link_cache(&handle)) == NULL) { + return NULL; + } + + if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) { + goto mac2str_error2; + } + + if ((addr = rtnl_link_get_addr(link)) == NULL) { + goto mac2str_error3; + } + + if ((buf = calloc(sizeof(char *), buflen)) == NULL) { + goto mac2str_error4; + } + + if ((buf = nl_addr2str(addr, buf, buflen)) != NULL) { + char *oldbuf = buf; + buf = g_ascii_strup(buf, -1); + free(oldbuf); + } + +mac2str_error4: + nl_addr_destroy(addr); +mac2str_error3: + rtnl_link_put(link); +mac2str_error2: + nl_close(handle); + nl_handle_destroy(handle); + + return buf; +} + +/* + * Convert an IPv4 CIDR prefix to a dotted-quad netmask. Return NULL on + * failure. + */ +struct in_addr *iface_prefix2netmask(int prefix) { + int mask = 0; + char *buf = NULL; + struct in_addr *ret; + + if ((buf = calloc(sizeof(char *), INET_ADDRSTRLEN + 1)) == NULL) { + return NULL; + } + + mask = htonl(~((1 << (32 - prefix)) - 1)); + + if (inet_ntop(AF_INET, (struct in_addr *) &mask, buf, + INET_ADDRSTRLEN) == NULL) { + return NULL; + } + + if ((ret = calloc(sizeof(struct in_addr), 1)) == NULL) { + return NULL; + } + + memcpy(ret, (struct in_addr *) &mask, sizeof(struct in_addr)); + return ret; +} + +/* + * Initialize a new iface_t structure to default values. + */ +void iface_init_iface_t(iface_t *iface) { + int i; + + memset(&iface->device, '\0', sizeof(iface->device)); + memset(&iface->ipaddr, 0, sizeof(iface->ipaddr)); + memset(&iface->netmask, 0, sizeof(iface->netmask)); + memset(&iface->broadcast, 0, sizeof(iface->broadcast)); + memset(&iface->ip6addr, 0, sizeof(iface->ip6addr)); + memset(&iface->gateway, 0, sizeof(iface->gateway)); + memset(&iface->gateway6, 0, sizeof(iface->gateway6)); + + for (i = 0; i < MAXNS; i++) { + iface->dns[i] = NULL; + } + + iface->macaddr = NULL; + iface->ip6prefix = 0; + iface->nextserver = NULL; + iface->bootfile = NULL; + iface->numdns = 0; + iface->hostname = NULL; + iface->domain = NULL; + iface->search = NULL; + iface->dhcptimeout = 0; + iface->vendorclass = NULL; + iface->ssid = NULL; + iface->wepkey = NULL; + iface->mtu = 0; + iface->subchannels = NULL; + iface->portname = NULL; + iface->peerid = NULL; + iface->nettype = NULL; + iface->ctcprot = NULL; + iface->layer2 = NULL; + iface->portno = NULL; + iface->flags = 0; + iface->ipv4method = IPV4_UNUSED_METHOD; + iface->ipv6method = IPV6_UNUSED_METHOD; + + return; +} + +/* + * Given a pointer to a struct in_addr, return 1 if it contains a valid + * address, 0 otherwise. + */ +int iface_have_in_addr(struct in_addr *addr) { + return _iface_have_valid_addr(addr, AF_INET, INET_ADDRSTRLEN); +} + +/* + * Given a pointer to a struct in6_addr, return 1 if it contains a valid + * address, 0 otherwise. + */ +int iface_have_in6_addr(struct in6_addr *addr6) { + return _iface_have_valid_addr(addr6, AF_INET6, INET6_ADDRSTRLEN); +} + +/* Check if NM has an active connection */ +gboolean is_nm_connected(void) { + NMState state; + NMClient *client = NULL; + + g_type_init(); + + client = nm_client_new(); + if (!client) + return FALSE; + + state = nm_client_get_state(client); + g_object_unref(client); + + if (state == NM_STATE_CONNECTED) + return TRUE; + else + return FALSE; +} + +/* Check if NM is already running */ +gboolean is_nm_running(void) { + gboolean running; + NMClient *client = NULL; + + g_type_init(); + + client = nm_client_new(); + if (!client) + return FALSE; + + running = nm_client_get_manager_running(client); + g_object_unref(client); + return running; +} + +/* + * Wait for NetworkManager to appear on the system bus + */ +int wait_for_nm(void) { + int count = 0; + + /* send message and block until a reply or error comes back */ + while (count < 45) { + if (is_nm_running()) + return 0; + + sleep(1); + count++; + } + + return 1; +} + +/* + * Start NetworkManager -- requires that you have already written out the + * control files in /etc/sysconfig for the interface. + */ +int iface_start_NetworkManager(void) { + pid_t pid; + + if (is_nm_running()) + return 0; /* already running */ + + /* Start NetworkManager */ + pid = fork(); + if (pid == 0) { + if (setpgrp() == -1) { + exit(1); + } + + if (_iface_redirect_io("/dev/null", STDIN_FILENO, O_RDONLY) || + _iface_redirect_io(OUTPUT_TERMINAL, STDOUT_FILENO, O_WRONLY) || + _iface_redirect_io(OUTPUT_TERMINAL, STDERR_FILENO, O_WRONLY)) { + exit(2); + } + + if (execl(NETWORKMANAGER, NETWORKMANAGER, + "--pid-file=/var/run/NetworkManager/NetworkManager.pid", + NULL) == -1) { + exit(3); + } + } else if (pid == -1) { + return 1; + } else { + return wait_for_nm(); + } + + return 0; +} + +/* + * Set the MTU on the specified device. + */ +int iface_set_interface_mtu(char *ifname, int mtu) { + int ret = 0; + struct nl_handle *handle = NULL; + struct nl_cache *cache = NULL; + struct rtnl_link *link = NULL; + struct rtnl_link *request = NULL; + + if (ifname == NULL) { + return -1; + } + + if (mtu <= 0) { + return -2; + } + + if ((cache = _iface_get_link_cache(&handle)) == NULL) { + return -3; + } + + if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) { + ret = -4; + goto ifacemtu_error1; + } + + request = rtnl_link_alloc(); + rtnl_link_set_mtu(request, mtu); + + if (rtnl_link_change(handle, link, request, 0)) { + ret = -5; + goto ifacemtu_error2; + } + +ifacemtu_error2: + rtnl_link_put(link); +ifacemtu_error1: + nl_close(handle); + nl_handle_destroy(handle); + + return ret; +} diff --git a/bin/isys/iface.h b/bin/isys/iface.h new file mode 100644 index 0000000..820d10b --- /dev/null +++ b/bin/isys/iface.h @@ -0,0 +1,166 @@ +/* + * iface.h - Network interface configuration API + * + * Copyright (C) 2006, 2007, 2008 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): David Cantrell <dcantrell@xxxxxxxxxx> + */ + +#ifndef ISYSIFACE_H +#define ISYSIFACE_H + +#include <resolv.h> +#include <net/if.h> +#include <netlink/cache.h> +#include <netlink/socket.h> +#include <glib.h> + +/* Enumerated types used in iface.c as well as loader's network code */ +enum { IPUNUSED = -1, IPV4, IPV6 }; + +enum { IPV4_UNUSED_METHOD, IPV4_DHCP_METHOD, IPV4_MANUAL_METHOD, IPV4_IBFT_METHOD, IPV4_IBFT_DHCP_METHOD }; +enum { IPV6_UNUSED_METHOD, IPV6_AUTO_METHOD, IPV6_DHCP_METHOD, + IPV6_MANUAL_METHOD }; + +#define IPV4_FIRST_METHOD IPV4_DHCP_METHOD +#define IPV4_LAST_METHOD IPV4_MANUAL_METHOD + +#define IPV6_FIRST_METHOD IPV6_AUTO_METHOD +#define IPV6_LAST_METHOD IPV6_MANUAL_METHOD + +/* Flags for the iface_t (do we need these?) */ +#define IFACE_FLAGS_NO_WRITE_RESOLV_CONF (((uint64_t) 1) << 0) +#define IFACE_NO_WRITE_RESOLV_CONF(a) ((a) & IFACE_FLAGS_NO_WRITE_RESOLV_CONF) + +/* Macros for starting NetworkManager */ +#define NETWORKMANAGER "/usr/sbin/NetworkManager" + +/* Per-interface configuration information */ +typedef struct _iface_t { + /* device name (e.g., eth0) */ + char device[IF_NAMESIZE]; + + /* MAC address as xx:xx:xx:xx:xx:xx */ + char *macaddr; + + /* IPv4 (store addresses in in_addr format, use inet_pton() to display) */ + struct in_addr ipaddr; + struct in_addr netmask; + struct in_addr broadcast; + + /* IPv6 (store addresses in in6_addr format, prefix is just an int) */ + struct in6_addr ip6addr; + int ip6prefix; + + /* Gateway settings */ + struct in_addr gateway; + struct in6_addr gateway6; + + /* BOOTP (these can be IPv4 or IPv6, store human-readable version as str) */ + char *nextserver; + char *bootfile; + + /* DNS (these can be IPv4 or IPv6, store human-readable version as str) */ + char *dns[MAXNS]; + int numdns; + char *hostname; + char *domain; + char *search; + + /* Misc DHCP settings */ + int dhcptimeout; + char *vendorclass; + + /* Wireless settings */ + char *ssid; + char *wepkey; + + /* s390 specifics */ + int mtu; + char *subchannels; + char *portname; + char *peerid; + char *nettype; + char *ctcprot; + char *layer2; + char *portno; + + /* flags */ + uint64_t flags; + int ipv4method; + int ipv6method; + int isiBFT; +} iface_t; + +/* Function prototypes */ + +/* + * Given an interface name (e.g., eth0) and address family (e.g., AF_INET), + * return the IP address in human readable format (i.e., the output from + * inet_ntop()). Return NULL for no match or error. + */ +char *iface_ip2str(char *, int); + +/* + * Given an interface name (e.g., eth0), return the MAC address in human + * readable format (e.g., 00:11:52:12:D9:A0). Return NULL for no match. + */ +char *iface_mac2str(char *); + +/* Given an interface's MAC address, return the name (e.g., eth0) in human + * readable format. Return NULL for no match + */ +char *iface_mac2device(char *); + +/* + * Convert an IPv4 CIDR prefix to a dotted-quad netmask. Return NULL on + * failure. + */ +struct in_addr *iface_prefix2netmask(int); + +/* + * Initialize a new iface_t structure to default values. + */ +void iface_init_iface_t(iface_t *); + +/* + * Given a pointer to a struct in_addr, return 1 if it contains a valid + * address, 0 otherwise. + */ +int iface_have_in_addr(struct in_addr *addr); + +/* + * Given a pointer to a struct in6_addr, return 1 if it contains a valid + * address, 0 otherwise. + */ +int iface_have_in6_addr(struct in6_addr *addr6); + +/* + * Checks if NetworkManager has an active connection. + */ +gboolean is_nm_connected(void); + +/* + * Start NetworkManager + */ +int iface_start_NetworkManager(void); + +/* + * Set Maximum Transfer Unit (MTU) on specified interface + */ +int iface_set_interface_mtu(char *ifname, int mtu); + +#endif /* ISYSIFACE_H */ diff --git a/bin/isys/imount.c b/bin/isys/imount.c new file mode 100644 index 0000000..ed0f5a7 --- /dev/null +++ b/bin/isys/imount.c @@ -0,0 +1,328 @@ +/* + * imount.c + * + * Copyright (C) 2007, 2008, 2009 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mount.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#include "imount.h" +#include "log.h" + +#define _(foo) foo + +static int mkdirIfNone(char * directory); + +static int readFD(int fd, char **buf) { + char *p; + size_t size = 4096; + int s, filesize = 0; + + *buf = calloc(4096, sizeof (char)); + if (*buf == NULL) + abort(); + + do { + p = &(*buf)[filesize]; + s = read(fd, p, 4096); + if (s < 0) + break; + + filesize += s; + if (s == 0) + break; + + size += s; + *buf = realloc(*buf, size); + if (*buf == NULL) + abort(); + } while (1); + + if (filesize == 0 && s < 0) { + free(*buf); + *buf = NULL; + return -1; + } + + return filesize; +} + +static size_t rstrip(char *str) { + size_t len = strlen(str); + if (len > 0 && str[len-1] == '\n') { + str[len-1] = '\0'; + --len; + } + return len; +} + +int mountCommandWrapper(int mode, char *dev, char *where, char *fs, + char *options, char **err) { + int rc, child, status; + int stdout_pipe[2], stderr_pipe[2]; + char *opts = NULL, *device = NULL, *cmd = NULL; + + switch (mode) { + case IMOUNT_MODE_MOUNT: + case IMOUNT_MODE_BIND: + cmd = "/bin/mount"; + if (mkdirChain(where)) + return IMOUNT_ERR_ERRNO; + break; + case IMOUNT_MODE_UMOUNT: + cmd = "/bin/umount"; + break; + default: + return IMOUNT_ERR_MODE; + } + + if (mode == IMOUNT_MODE_MOUNT) { + if (strstr(fs, "nfs")) { + if (options) { + if (asprintf(&opts, "%s,nolock", options) == -1) { + fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, + strerror(errno)); + fflush(stderr); + abort(); + } + } else { + opts = strdup("nolock"); + } + + device = strdup(dev); + } else { + if ((options && strstr(options, "bind") == NULL) && + strncmp(dev, "LABEL=", 6) && strncmp(dev, "UUID=", 5) && + *dev != '/') { + if (asprintf(&device, "/dev/%s", dev) == -1) { + fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, + strerror(errno)); + fflush(stderr); + abort(); + } + } else { + device = strdup(dev); + } + + if (options) + opts = strdup(options); + } + } + + if (pipe(stdout_pipe)) + return IMOUNT_ERR_ERRNO; + if (pipe(stderr_pipe)) + return IMOUNT_ERR_ERRNO; + + if (!(child = fork())) { + int tty_fd; + + close(stdout_pipe[0]); + close(stderr_pipe[0]); + + /* Pull stdin from /dev/tty5 and redirect stdout and stderr to the pipes + * so we can log the output and put error messages into exceptions. + * We'll only use these messages should mount also return an error + * code. + */ + tty_fd = open("/dev/tty5", O_RDONLY); + close(STDIN_FILENO); + dup2(tty_fd, STDIN_FILENO); + close(tty_fd); + + close(STDOUT_FILENO); + dup2(stdout_pipe[1], STDOUT_FILENO); + close(STDERR_FILENO); + dup2(stderr_pipe[1], STDERR_FILENO); + + if (mode == IMOUNT_MODE_MOUNT) { + if (opts) { + logProgramMessage(INFO, "Running... %s -n -t %s -o %s %s %s", + cmd, fs, opts, device, where); + rc = execl(cmd, cmd, + "-n", "-t", fs, "-o", opts, device, where, NULL); + exit(1); + } else { + logProgramMessage(INFO, "Running... %s -n -t %s %s %s", + cmd, fs, device, where); + rc = execl(cmd, cmd, "-n", "-t", fs, device, where, NULL); + exit(1); + } + } else if (mode == IMOUNT_MODE_BIND) { + logProgramMessage(INFO, "Running... %s --bind %s %s", + cmd, dev, where); + rc = execl(cmd, cmd, "--bind", dev, where, NULL); + exit(1); + } else if (mode == IMOUNT_MODE_UMOUNT) { + logProgramMessage(INFO, "Running... %s %s", cmd, where); + rc = execl(cmd, cmd, where, NULL); + exit(1); + } else { + logProgramMessage(ERROR, "Running... Unknown imount mode: %d\n", mode); + exit(1); + } + } + + close(stdout_pipe[1]); + close(stderr_pipe[1]); + + char *buffer = NULL; + /* In case when when the stderr pipe gets enough data to fill the kernel + * buffer we might see a deadlock as this will block the mount program on + * its next write(). The buffer size is 65kB though so we should be safe. + */ + rc = readFD(stdout_pipe[0], &buffer); + if (rc > 0) { + rstrip(buffer); + logProgramMessage(INFO, buffer); + free(buffer); + buffer = NULL; + } + rc = readFD(stderr_pipe[0], &buffer); + if (rc > 0) { + rstrip(buffer); + logProgramMessage(ERROR, buffer); + if (err != NULL) + *err = buffer; + else + free(buffer); + } + close(stdout_pipe[0]); + close(stderr_pipe[0]); + + waitpid(child, &status, 0); + + if (opts) { + free(opts); + } + + if (device) { + free(device); + } + + if (!WIFEXITED(status)) + return IMOUNT_ERR_OTHER; + else if ( (rc = WEXITSTATUS(status)) ) { + /* Refer to 'man mount' for the meaning of the error codes. */ + switch (rc) { + case 1: + return IMOUNT_ERR_PERMISSIONS; + case 2: + return IMOUNT_ERR_SYSTEM; + case 4: + return IMOUNT_ERR_MOUNTINTERNAL; + case 8: + return IMOUNT_ERR_USERINTERRUPT; + case 16: + return IMOUNT_ERR_MTAB; + case 32: + return IMOUNT_ERR_MOUNTFAILURE; + case 64: + return IMOUNT_ERR_PARTIALSUCC; + default: + return IMOUNT_ERR_OTHER; + } + } + + return 0; +} + +int doBindMount(char* path, char *where, char **err) { + return mountCommandWrapper(IMOUNT_MODE_BIND, + path, where, NULL, NULL, err); +} + +int doPwMount(char *dev, char *where, char *fs, char *options, char **err) { + return mountCommandWrapper(IMOUNT_MODE_MOUNT, + dev, where, fs, options, err); +} + +int doPwUmount(char *where, char **err) { + return mountCommandWrapper(IMOUNT_MODE_UMOUNT, + NULL, where, NULL, NULL, err); +} + +int mkdirChain(char * origChain) { + char * chain; + char * chptr; + + chain = alloca(strlen(origChain) + 1); + strcpy(chain, origChain); + chptr = chain; + + while ((chptr = strchr(chptr, '/'))) { + *chptr = '\0'; + if (mkdirIfNone(chain)) { + *chptr = '/'; + return IMOUNT_ERR_ERRNO; + } + + *chptr = '/'; + chptr++; + } + + if (mkdirIfNone(chain)) + return IMOUNT_ERR_ERRNO; + + return 0; +} + +/* Returns true iff it is possible that the mount command that have returned + * 'errno' might succeed at a later time (think e.g. not yet initialized USB + * device, etc.) */ +int mountMightSucceedLater(int mountRc) +{ + int rc; + switch (mountRc) { + case IMOUNT_ERR_MOUNTFAILURE: + rc = 1; + break; + default: + rc = 0; + } + return rc; +} + +static int mkdirIfNone(char * directory) { + int rc, mkerr; + char * chptr; + + /* If the file exists it *better* be a directory -- I'm not going to + actually check or anything */ + if (!access(directory, X_OK)) return 0; + + /* if the path is '/' we get ENOFILE not found" from mkdir, rather + then EEXIST which is weird */ + for (chptr = directory; *chptr; chptr++) + if (*chptr != '/') break; + if (!*chptr) return 0; + + rc = mkdir(directory, 0755); + mkerr = errno; + + if (!rc || mkerr == EEXIST) return 0; + + return IMOUNT_ERR_ERRNO; +} diff --git a/bin/isys/imount.h b/bin/isys/imount.h new file mode 100644 index 0000000..d1b7cf3 --- /dev/null +++ b/bin/isys/imount.h @@ -0,0 +1,50 @@ +/* + * imount.h + * + * Copyright (C) 2007, 2008, 2009 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef H_IMOUNT +#define H_IMOUNT + +#define IMOUNT_ERR_ERRNO 1 +#define IMOUNT_ERR_OTHER 2 +#define IMOUNT_ERR_MODE 3 +#define IMOUNT_ERR_PERMISSIONS 4 +#define IMOUNT_ERR_SYSTEM 5 +#define IMOUNT_ERR_MOUNTINTERNAL 6 +#define IMOUNT_ERR_USERINTERRUPT 7 +#define IMOUNT_ERR_MTAB 8 +#define IMOUNT_ERR_MOUNTFAILURE 9 +#define IMOUNT_ERR_PARTIALSUCC 10 + +#include <sys/mount.h> /* for umount() */ + +#define IMOUNT_RDONLY 1 +#define IMOUNT_BIND 2 +#define IMOUNT_REMOUNT 4 + +#define IMOUNT_MODE_MOUNT 1 +#define IMOUNT_MODE_UMOUNT 2 +#define IMOUNT_MODE_BIND 3 + +int doBindMount(char* path, char *where, char **err); +int doPwMount(char *dev, char *where, char *fs, char *options, char **err); +int doPwUmount(char *where, char **err); +int mkdirChain(char * origChain); +int mountMightSucceedLater(int mountRc); + +#endif diff --git a/bin/isys/isofs.c b/bin/isys/isofs.c new file mode 100644 index 0000000..bb5a44a --- /dev/null +++ b/bin/isys/isofs.c @@ -0,0 +1,55 @@ +/* + * isofs.c + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +#define BLOCK_SIZE 2048 + +/* returns 1 if file is an ISO, 0 otherwise */ +int fileIsIso(const char * file) { + int blkNum; + char magic[5]; + int fd; + + fd = open(file, O_RDONLY); + if (fd < 0) + return 0; + + for (blkNum = 16; blkNum < 100; blkNum++) { + if (lseek(fd, blkNum * BLOCK_SIZE + 1, SEEK_SET) < 0) { + close(fd); + return 0; + } + + if (read(fd, magic, sizeof(magic)) != sizeof(magic)) { + close(fd); + return 0; + } + + if (!strncmp(magic, "CD001", 5)) { + close(fd); + return 1; + } + } + + close(fd); + return 0; +} diff --git a/bin/isys/isys.c b/bin/isys/isys.c new file mode 100644 index 0000000..409170b --- /dev/null +++ b/bin/isys/isys.c @@ -0,0 +1,701 @@ +/* + * isys.c + * + * Copyright (C) 2007, 2008, 2009 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <Python.h> + +#include <stdio.h> +#include <dirent.h> +#include <errno.h> +#define u32 __u32 +#include <ext2fs/ext2fs.h> +#include <fcntl.h> +/* Need to tell loop.h what the actual dev_t type is. */ +#undef dev_t +#if defined(__alpha) || (defined(__sparc__) && defined(__arch64__)) +#define dev_t unsigned int +#else +#if defined(__x86_64__) +#define dev_t unsigned long +#else +#define dev_t unsigned short +#endif +#endif +#include <linux/loop.h> +#undef dev_t +#define dev_t dev_t +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/sysmacros.h> +#include <sys/time.h> +#include <sys/utsname.h> +#include <sys/vfs.h> +#include <unistd.h> +#include <resolv.h> +#include <scsi/scsi.h> +#include <scsi/scsi_ioctl.h> +#include <sys/vt.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <linux/fb.h> +#include <libintl.h> +#include <libgen.h> +#include <linux/cdrom.h> +#include <linux/major.h> +#include <linux/raid/md_u.h> +#include <linux/raid/md_p.h> +#include <signal.h> +#include <execinfo.h> + +#include <blkid/blkid.h> + +#include <X11/Xlib.h> +#include <X11/XKBlib.h> +#include <X11/keysym.h> + +#include "iface.h" +#include "isys.h" +#include "imount.h" +#include "ethtool.h" +#include "lang.h" +#include "eddsupport.h" +#include "auditd.h" +#include "imount.h" +#include "log.h" + +#ifndef CDROMEJECT +#define CDROMEJECT 0x5309 +#endif + +static PyObject * doMount(PyObject * s, PyObject * args); +static PyObject * doUMount(PyObject * s, PyObject * args); +static PyObject * doSwapon(PyObject * s, PyObject * args); +static PyObject * doSwapoff(PyObject * s, PyObject * args); +static PyObject * doLoSetup(PyObject * s, PyObject * args); +static PyObject * doUnLoSetup(PyObject * s, PyObject * args); +static PyObject * doLoChangeFd(PyObject * s, PyObject * args); +static PyObject * doWipeRaidSuperblock(PyObject * s, PyObject * args); +static PyObject * doGetRaidChunkSize(PyObject * s, PyObject * args); +static PyObject * doDevSpaceFree(PyObject * s, PyObject * args); +static PyObject * doResetResolv(PyObject * s, PyObject * args); +static PyObject * doLoadKeymap(PyObject * s, PyObject * args); +static PyObject * doExt2Dirty(PyObject * s, PyObject * args); +static PyObject * doExt2HasJournal(PyObject * s, PyObject * args); +static PyObject * doEjectCdrom(PyObject * s, PyObject * args); +static PyObject * doVtActivate(PyObject * s, PyObject * args); +static PyObject * doisPseudoTTY(PyObject * s, PyObject * args); +static PyObject * doisVioConsole(PyObject * s); +static PyObject * doSync(PyObject * s, PyObject * args); +static PyObject * doisIsoImage(PyObject * s, PyObject * args); +static PyObject * printObject(PyObject * s, PyObject * args); +static PyObject * py_bind_textdomain_codeset(PyObject * o, PyObject * args); +static PyObject * doSegvHandler(PyObject *s, PyObject *args); +static PyObject * doAuditDaemon(PyObject *s); +static PyObject * doPrefixToNetmask(PyObject *s, PyObject *args); +static PyObject * doGetBlkidData(PyObject * s, PyObject * args); +static PyObject * doIsCapsLockEnabled(PyObject * s, PyObject * args); +static PyObject * doGetLinkStatus(PyObject * s, PyObject * args); +static PyObject * doGetAnacondaVersion(PyObject * s, PyObject * args); +static PyObject * doInitLog(PyObject * s); + +static PyMethodDef isysModuleMethods[] = { + { "ejectcdrom", (PyCFunction) doEjectCdrom, METH_VARARGS, NULL }, + { "e2dirty", (PyCFunction) doExt2Dirty, METH_VARARGS, NULL }, + { "e2hasjournal", (PyCFunction) doExt2HasJournal, METH_VARARGS, NULL }, + { "devSpaceFree", (PyCFunction) doDevSpaceFree, METH_VARARGS, NULL }, + { "wiperaidsb", (PyCFunction) doWipeRaidSuperblock, METH_VARARGS, NULL }, + { "getraidchunk", (PyCFunction) doGetRaidChunkSize, METH_VARARGS, NULL }, + { "lochangefd", (PyCFunction) doLoChangeFd, METH_VARARGS, NULL }, + { "losetup", (PyCFunction) doLoSetup, METH_VARARGS, NULL }, + { "unlosetup", (PyCFunction) doUnLoSetup, METH_VARARGS, NULL }, + { "mount", (PyCFunction) doMount, METH_VARARGS, NULL }, + { "umount", (PyCFunction) doUMount, METH_VARARGS, NULL }, + { "resetresolv", (PyCFunction) doResetResolv, METH_VARARGS, NULL }, + { "swapon", (PyCFunction) doSwapon, METH_VARARGS, NULL }, + { "swapoff", (PyCFunction) doSwapoff, METH_VARARGS, NULL }, + { "loadKeymap", (PyCFunction) doLoadKeymap, METH_VARARGS, NULL }, + { "vtActivate", (PyCFunction) doVtActivate, METH_VARARGS, NULL}, + { "isPseudoTTY", (PyCFunction) doisPseudoTTY, METH_VARARGS, NULL}, + { "isVioConsole", (PyCFunction) doisVioConsole, METH_NOARGS, NULL}, + { "sync", (PyCFunction) doSync, METH_VARARGS, NULL}, + { "isisoimage", (PyCFunction) doisIsoImage, METH_VARARGS, NULL}, + { "printObject", (PyCFunction) printObject, METH_VARARGS, NULL}, + { "bind_textdomain_codeset", (PyCFunction) py_bind_textdomain_codeset, METH_VARARGS, NULL}, + { "handleSegv", (PyCFunction) doSegvHandler, METH_VARARGS, NULL }, + { "auditdaemon", (PyCFunction) doAuditDaemon, METH_NOARGS, NULL }, + { "prefix2netmask", (PyCFunction) doPrefixToNetmask, METH_VARARGS, NULL }, + { "getblkid", (PyCFunction) doGetBlkidData, METH_VARARGS, NULL }, + { "isCapsLockEnabled", (PyCFunction) doIsCapsLockEnabled, METH_VARARGS, NULL }, + { "getLinkStatus", (PyCFunction) doGetLinkStatus, METH_VARARGS, NULL }, + { "getAnacondaVersion", (PyCFunction) doGetAnacondaVersion, METH_VARARGS, NULL }, + { "initLog", (PyCFunction) doInitLog, METH_VARARGS, NULL }, + { NULL, NULL, 0, NULL } +} ; + +static PyObject * doUnLoSetup(PyObject * s, PyObject * args) { + int loopfd; + + if (!PyArg_ParseTuple(args, "i", &loopfd)) return NULL; + if (ioctl(loopfd, LOOP_CLR_FD, 0)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +/* XXX - msw */ +#ifndef LOOP_CHANGE_FD +#define LOOP_CHANGE_FD 0x4C06 +#endif + +static PyObject * doLoChangeFd(PyObject * s, PyObject * args) { + int loopfd; + int targfd; + + if (!PyArg_ParseTuple(args, "ii", &loopfd, &targfd)) + return NULL; + if (ioctl(loopfd, LOOP_CHANGE_FD, targfd)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doLoSetup(PyObject * s, PyObject * args) { + int loopfd; + int targfd; + struct loop_info loopInfo; + char * loopName; + + if (!PyArg_ParseTuple(args, "iis", &loopfd, &targfd, &loopName)) + return NULL; + if (ioctl(loopfd, LOOP_SET_FD, targfd)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + memset(&loopInfo, 0, sizeof(loopInfo)); + strncpy(loopInfo.lo_name, basename(loopName), 63); + + if (ioctl(loopfd, LOOP_SET_STATUS, &loopInfo)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doUMount(PyObject * s, PyObject * args) { + char *err = NULL, *mntpoint = NULL; + int rc; + + if (!PyArg_ParseTuple(args, "s", &mntpoint)) { + return NULL; + } + + rc = doPwUmount(mntpoint, &err); + if (rc == IMOUNT_ERR_ERRNO) { + PyErr_SetFromErrno(PyExc_SystemError); + } else if (rc) { + PyObject *tuple = PyTuple_New(2); + + PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc)); + + if (err == NULL) { + Py_INCREF(Py_None); + PyTuple_SetItem(tuple, 1, Py_None); + } else { + PyTuple_SetItem(tuple, 1, PyString_FromString(err)); + } + + PyErr_SetObject(PyExc_SystemError, tuple); + } + + if (rc) { + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doMount(PyObject * s, PyObject * args) { + char *err = NULL, *fs, *device, *mntpoint, *flags = NULL; + int rc; + + if (!PyArg_ParseTuple(args, "sss|z", &fs, &device, &mntpoint, + &flags)) return NULL; + + rc = doPwMount(device, mntpoint, fs, flags, &err); + if (rc == IMOUNT_ERR_ERRNO) + PyErr_SetFromErrno(PyExc_SystemError); + else if (rc) { + PyObject *tuple = PyTuple_New(2); + + PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc)); + + if (err == NULL) { + Py_INCREF(Py_None); + PyTuple_SetItem(tuple, 1, Py_None); + } else { + PyTuple_SetItem(tuple, 1, PyString_FromString(err)); + } + + PyErr_SetObject(PyExc_SystemError, tuple); + } + + if (rc) return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +#define BOOT_SIGNATURE 0xaa55 /* boot signature */ +#define BOOT_SIG_OFFSET 510 /* boot signature offset */ + +int swapoff(const char * path); +int swapon(const char * path, int priorty); + +static PyObject * doSwapoff (PyObject * s, PyObject * args) { + char * path; + + if (!PyArg_ParseTuple(args, "s", &path)) return NULL; + + if (swapoff (path)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doSwapon (PyObject * s, PyObject * args) { + char * path; + + if (!PyArg_ParseTuple(args, "s", &path)) return NULL; + + if (swapon (path, 0)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +void init_isys(void) { + PyObject * m, * d; + + m = Py_InitModule("_isys", isysModuleMethods); + d = PyModule_GetDict(m); + + PyDict_SetItemString(d, "MIN_RAM", PyInt_FromLong(MIN_RAM)); + PyDict_SetItemString(d, "MIN_GUI_RAM", PyInt_FromLong(MIN_GUI_RAM)); + PyDict_SetItemString(d, "URL_INSTALL_EXTRA_RAM", PyInt_FromLong(URL_INSTALL_EXTRA_RAM)); + PyDict_SetItemString(d, "EARLY_SWAP_RAM", PyInt_FromLong(EARLY_SWAP_RAM)); +} + +static PyObject * doPrefixToNetmask (PyObject * s, PyObject * args) { + int prefix = 0; + struct in_addr *mask = NULL; + char dst[INET_ADDRSTRLEN+1]; + + if (!PyArg_ParseTuple(args, "i", &prefix)) + return NULL; + + if ((mask = iface_prefix2netmask(prefix)) == NULL) + return NULL; + + if (inet_ntop(AF_INET, mask, dst, INET_ADDRSTRLEN) == NULL) + return NULL; + + return Py_BuildValue("s", dst); +} + +static PyObject * doResetResolv(PyObject * s, PyObject * args) { + if (!PyArg_ParseTuple(args, "")) { + return NULL; + } + + /* reinit the resolver so DNS changes take affect */ + res_init(); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doWipeRaidSuperblock(PyObject * s, PyObject * args) { + int fd; + unsigned long size; + struct mdp_super_t * sb; + + if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; + + if (ioctl(fd, BLKGETSIZE, &size)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + /* put the size in 1k blocks */ + size >>= 1; + + if (lseek64(fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), SEEK_SET) < 0) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + sb = malloc(sizeof(mdp_super_t)); + sb = memset(sb, '\0', sizeof(mdp_super_t)); + + if (write(fd, sb, sizeof(sb)) != sizeof(sb)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + return Py_None; +} + +static PyObject * doGetRaidChunkSize(PyObject * s, PyObject * args) { + int fd; + unsigned long size; + mdp_super_t sb; + + if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; + + if (ioctl(fd, BLKGETSIZE, &size)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + /* put the size in 1k blocks */ + size >>= 1; + + if (lseek64(fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), SEEK_SET) < 0) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + if (sb.md_magic != MD_SB_MAGIC) { + PyErr_SetString(PyExc_ValueError, "bad md magic on device"); + return NULL; + } + + return Py_BuildValue("i", sb.chunk_size / 1024); +} + +static int get_bits(unsigned long long v) { + int b = 0; + + if ( v & 0xffffffff00000000LLU ) { b += 32; v >>= 32; } + if ( v & 0xffff0000LLU ) { b += 16; v >>= 16; } + if ( v & 0xff00LLU ) { b += 8; v >>= 8; } + if ( v & 0xf0LLU ) { b += 4; v >>= 4; } + if ( v & 0xcLLU ) { b += 2; v >>= 2; } + if ( v & 0x2LLU ) b++; + + return v ? b + 1 : b; +} + +static PyObject * doDevSpaceFree(PyObject * s, PyObject * args) { + char * path; + struct statfs sb; + unsigned long long size; + + if (!PyArg_ParseTuple(args, "s", &path)) return NULL; + + if (statfs(path, &sb)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + /* Calculate a saturated addition to prevent oveflow. */ + if ( get_bits(sb.f_bfree) + get_bits(sb.f_bsize) <= 64 ) + size = (unsigned long long)sb.f_bfree * sb.f_bsize; + else + size = ~0LLU; + + return PyLong_FromUnsignedLongLong(size>>20); +} + +static PyObject * doLoadKeymap (PyObject * s, PyObject * args) { + char * keymap; + int ret; + + if (!PyArg_ParseTuple(args, "s", &keymap)) return NULL; + + ret = isysLoadKeymap (keymap); + if (ret) { + errno = -ret; + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doExt2Dirty(PyObject * s, PyObject * args) { + char * device; + ext2_filsys fsys; + int rc; + int clean; + + if (!PyArg_ParseTuple(args, "s", &device)) return NULL; + + rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, + &fsys); + if (rc) { + Py_INCREF(Py_None); + return Py_None; + } + + clean = fsys->super->s_state & EXT2_VALID_FS; + + ext2fs_close(fsys); + + return Py_BuildValue("i", !clean); +} +static PyObject * doExt2HasJournal(PyObject * s, PyObject * args) { + char * device; + ext2_filsys fsys; + int rc; + int hasjournal; + + if (!PyArg_ParseTuple(args, "s", &device)) return NULL; + rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, + &fsys); + if (rc) { + Py_INCREF(Py_None); + return Py_None; + } + + hasjournal = fsys->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL; + + ext2fs_close(fsys); + + return Py_BuildValue("i", hasjournal); +} + +static PyObject * doEjectCdrom(PyObject * s, PyObject * args) { + int fd; + + if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; + + /* Ask it to unlock the door and then eject the disc. There's really + * nothing to do if unlocking doesn't work, so just eject without + * worrying about it. -- pjones + */ + ioctl(fd, CDROM_LOCKDOOR, 0); + if (ioctl(fd, CDROMEJECT, 1)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doVtActivate(PyObject * s, PyObject * args) { + int vtnum; + + if (!PyArg_ParseTuple(args, "i", &vtnum)) return NULL; + + if (ioctl(0, VT_ACTIVATE, vtnum)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doisPseudoTTY(PyObject * s, PyObject * args) { + int fd; + struct stat sb; + + if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; + fstat(fd, &sb); + + /* XXX close enough for now */ + return Py_BuildValue("i", ((major(sb.st_rdev) >= 136) && (major(sb.st_rdev) <= 143))); +} + +static PyObject * doisVioConsole(PyObject * s) { + return Py_BuildValue("i", isVioConsole()); +} + +static PyObject * doSync(PyObject * s, PyObject * args) { + int fd; + + if (!PyArg_ParseTuple(args, "", &fd)) return NULL; + sync(); + + Py_INCREF(Py_None); + return Py_None; +} + +int fileIsIso(const char * file); + +static PyObject * doisIsoImage(PyObject * s, PyObject * args) { + char * fn; + int rc; + + if (!PyArg_ParseTuple(args, "s", &fn)) return NULL; + + rc = fileIsIso(fn); + + return Py_BuildValue("i", rc); +} + +static PyObject * printObject (PyObject * o, PyObject * args) { + PyObject * obj; + char buf[256]; + + if (!PyArg_ParseTuple(args, "O", &obj)) + return NULL; + + snprintf(buf, 256, "<%s object at %lx>", obj->ob_type->tp_name, + (long) obj); + + return PyString_FromString(buf); +} + +static PyObject * +py_bind_textdomain_codeset(PyObject * o, PyObject * args) { + char *domain, *codeset, *ret; + + if (!PyArg_ParseTuple(args, "ss", &domain, &codeset)) + return NULL; + + ret = bind_textdomain_codeset(domain, codeset); + + if (ret) + return PyString_FromString(ret); + + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; +} + +static PyObject * doSegvHandler(PyObject *s, PyObject *args) { + void *array[20]; + size_t size; + char **strings; + size_t i; + + signal(SIGSEGV, SIG_DFL); /* back to default */ + + size = backtrace (array, 20); + strings = backtrace_symbols (array, size); + + printf ("Anaconda received SIGSEGV!. Backtrace:\n"); + for (i = 0; i < size; i++) + printf ("%s\n", strings[i]); + + free (strings); + exit(1); +} + +static PyObject * doAuditDaemon(PyObject *s) { + audit_daemonize(); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doGetBlkidData(PyObject * s, PyObject * args) { + char * dev, * key; + blkid_cache cache; + blkid_dev bdev = NULL; + blkid_tag_iterate titer; + const char * type, * data; + + if (!PyArg_ParseTuple(args, "ss", &dev, &key)) return NULL; + + blkid_get_cache(&cache, NULL); + + bdev = blkid_get_dev(cache, dev, BLKID_DEV_NORMAL); + if (bdev == NULL) + goto out; + titer = blkid_tag_iterate_begin(bdev); + while (blkid_tag_next(titer, &type, &data) >= 0) { + if (!strcmp(type, key)) { + blkid_tag_iterate_end(titer); + return Py_BuildValue("s", data); + } + } + blkid_tag_iterate_end(titer); + + out: + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * doIsCapsLockEnabled(PyObject * s, PyObject * args) { + Display *d = NULL; + XkbStateRec state; + + if ((d = XOpenDisplay(NULL)) == NULL) { + return NULL; + } + + memset(&state, 0, sizeof(state)); + XkbGetState(d, XkbUseCoreKbd, &state); + + if (XCloseDisplay(d)) { + return NULL; + } + + return PyBool_FromLong(state.locked_mods & LockMask); +} + +static PyObject * doGetLinkStatus(PyObject * s, PyObject * args) { + char *dev = NULL; + + if (!PyArg_ParseTuple(args, "s", &dev)) { + return NULL; + } + + if (get_link_status(dev) == 1) { + return PyBool_FromLong(1); + } + + return PyBool_FromLong(0); +} + +static PyObject * doGetAnacondaVersion(PyObject * s, PyObject * args) { + return Py_BuildValue("s", VERSION); +} + +static PyObject * doInitLog(PyObject * s) { + openLog(); + Py_INCREF(Py_None); + return Py_None; +} + +/* vim:set shiftwidth=4 softtabstop=4: */ diff --git a/bin/isys/isys.h b/bin/isys/isys.h new file mode 100644 index 0000000..e3cb1fc --- /dev/null +++ b/bin/isys/isys.h @@ -0,0 +1,39 @@ +/* + * isys.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef H_ISYS +#define H_ISYS + +#define MIN_RAM 262144 // 256 MB +#define MIN_GUI_RAM 524288 // 512 MB +#define URL_INSTALL_EXTRA_RAM 131072 // 128 MB +#define EARLY_SWAP_RAM 524288 + +#define OUTPUT_TERMINAL "/dev/tty5" + +int insmod(char * modName, char * path, char ** args); +int rmmod(char * modName); + +/* returns 0 for true, !0 for false */ +int fileIsIso(const char * file); + +/* returns 1 if on an iSeries vio console, 0 otherwise */ +int isVioConsole(void); + +#endif diff --git a/bin/isys/lang.c b/bin/isys/lang.c new file mode 100644 index 0000000..b6e2a36 --- /dev/null +++ b/bin/isys/lang.c @@ -0,0 +1,207 @@ +/* + * lang.c + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <alloca.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <linux/keyboard.h> +#ifdef NR_KEYS +#undef NR_KEYS +#define NR_KEYS 128 +#endif + +#include "linux/kd.h" + +#include "cpio.h" +#include "isys.h" +#include "lang.h" +#include "stubs.h" + +int isysLoadFont(void) { + unsigned char font[65536]; + struct console_font_op cfo; + unsigned short map[E_TABSZ]; + struct unimapdesc d; + struct unimapinit u; + struct unipair desc[2048]; + gzFile stream; + int rc; + +#if defined (__s390__) || defined (__s390x__) + return 0; +#endif + stream = gunzip_open("/etc/screenfont.gz"); + if (!stream) + return -EACCES; + + gunzip_read(stream, &cfo, sizeof(cfo)); + gunzip_read(stream, font, sizeof(font)); + gunzip_read(stream, map, sizeof(map)); + gunzip_read(stream, &d.entry_ct, sizeof(d.entry_ct)); + d.entries = desc; + gunzip_read(stream, desc, d.entry_ct * sizeof(desc[0])); + gunzip_close(stream); + + cfo.data = font; + cfo.op = KD_FONT_OP_SET; + + rc = ioctl(1, KDFONTOP, &cfo); + if (rc) return rc; + rc = ioctl(1, PIO_UNIMAPCLR, &u); + if (rc) return rc; + rc = ioctl(1, PIO_UNIMAP, &d); + if (rc) return rc; + rc = ioctl(1, PIO_UNISCRNMAP, map); + if (rc) return rc; + /* activate the font map */ + fprintf(stderr, "\033(K"); + return 0; +} + +int isysSetUnicodeKeymap(void) { + int console; + +#if defined (__s390__) || defined (__s390x__) + return 0; +#endif + console = open("/dev/console", O_RDWR); + if (console < 0) + return -EACCES; + + /* place keyboard in unicode mode */ + ioctl(console, KDSKBMODE, K_UNICODE); + close(console); + return 0; +} + +/* the file pointer must be at the beginning of the section already! */ +int loadKeymap(gzFile stream) { + int console; + int kmap, key; + struct kbentry entry; + int keymaps[MAX_NR_KEYMAPS]; + int count = 0; + unsigned int magic; + short keymap[NR_KEYS]; + struct stat sb; + +#if defined (__s390__) || defined (__s390x__) + return 0; +#endif + if (isVioConsole()) + return 0; + + /* assume that if we're already on a pty loading a keymap is silly */ + fstat(0, &sb); + if (major(sb.st_rdev) == 3 || major(sb.st_rdev) == 136) + return 0; + + if (gunzip_read(stream, &magic, sizeof(magic)) != sizeof(magic)) + return -EIO; + + if (magic != KMAP_MAGIC) return -EINVAL; + + if (gunzip_read(stream, keymaps, sizeof(keymaps)) != sizeof(keymaps)) + return -EINVAL; + + console = open("/dev/tty0", O_RDWR); + if (console < 0) + return -EACCES; + + for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) { + if (!keymaps[kmap]) continue; + + if (gunzip_read(stream, keymap, sizeof(keymap)) != sizeof(keymap)) { + close(console); + return -EIO; + } + + count++; + for (key = 0; key < NR_KEYS; key++) { + entry.kb_index = key; + entry.kb_table = kmap; + entry.kb_value = keymap[key]; + if (KTYP(entry.kb_value) != KT_SPEC) { + if (ioctl(console, KDSKBENT, &entry)) { + int ret = errno; + close(console); + return ret; + } + } + } + } + close(console); + return 0; +} + +int isysLoadKeymap(char * keymap) { + int num = -1; + int rc; + gzFile f; + struct kmapHeader hdr; + struct kmapInfo * infoTable; + char buf[16384]; /* I hope this is big enough */ + int i; + + f = gunzip_open("/etc/keymaps.gz"); + if (!f) return -EACCES; + + if (gunzip_read(f, &hdr, sizeof(hdr)) != sizeof(hdr)) { + gunzip_close(f); + return -EINVAL; + } + + i = hdr.numEntries * sizeof(*infoTable); + infoTable = alloca(i); + if (gunzip_read(f, infoTable, i) != i) { + gunzip_close(f); + return -EIO; + } + + for (i = 0; i < hdr.numEntries; i++) + if (!strcmp(infoTable[i].name, keymap)) { + num = i; + break; + } + + if (num == -1) { + gunzip_close(f); + return -ENOENT; + } + + for (i = 0; i < num; i++) { + if (gunzip_read(f, buf, infoTable[i].size) != infoTable[i].size) { + gunzip_close(f); + return -EIO; + } + } + + rc = loadKeymap(f); + + gunzip_close(f); + + return rc; +} diff --git a/bin/isys/lang.h b/bin/isys/lang.h new file mode 100644 index 0000000..a08adbd --- /dev/null +++ b/bin/isys/lang.h @@ -0,0 +1,44 @@ +/* + * lang.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ISYS_LANG_H +#define ISYS_LANG_H + +#include "stubs.h" + +/* define ask johnsonm@xxxxxxxxxx where this came from */ +#define KMAP_MAGIC 0x8B39C07F +#define KMAP_NAMELEN 40 /* including '\0' */ + +struct kmapHeader { + int magic; + int numEntries; +}; + +struct kmapInfo { + int size; + char name[KMAP_NAMELEN]; +}; + +int loadKeymap(gzFile stream); +int isysLoadFont(void); +int isysLoadKeymap(char * keymap); +int isysSetUnicodeKeymap(void); + +#endif diff --git a/bin/isys/linkdetect.c b/bin/isys/linkdetect.c new file mode 100644 index 0000000..f97a291 --- /dev/null +++ b/bin/isys/linkdetect.c @@ -0,0 +1,202 @@ +/* + * linkdetect.c - simple link detection + * + * pulls code from mii-tool.c in net-toools and ethtool so + * that we can do everything that jgarzik says we should check + * + * Copyright (C) 2002, 2003 Red Hat, Inc. All rights reserved. + * Portions Copyright (C) 2000 David A. Hinds -- dhinds@xxxxxxxxxxxxxxxxxxxxxx + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Jeremy Katz <katzj@xxxxxxxxxx> + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <sys/ioctl.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> + +#include <sys/socket.h> +#include <sys/types.h> +#include <net/if.h> + +#include <linux/sockios.h> +#include <linux/mii.h> +#include <linux/ethtool.h> +#include "ethtool.h" + +static struct ifreq ifr; + +static int mdio_read(int skfd, uint16_t location) +{ + struct mii_ioctl_data mii; + + memset(&mii, 0, sizeof(mii)); + memcpy(&mii, &ifr.ifr_data, sizeof(mii)); + mii.reg_num = location; + memcpy(&ifr.ifr_data, &mii, sizeof(mii)); + + if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) { +#ifdef STANDALONE + fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name, + strerror(errno)); +#endif + return -1; + } else { + memcpy(&mii, &ifr.ifr_data, sizeof(mii)); + } + + return mii.val_out; +} + +/* we don't need writing right now */ +#if 0 +static void mdio_write(int skfd, int location, int value) +{ + struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr.ifr_data; + mii->reg_num = location; + mii->val_in = value; + if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) { +#ifdef STANDALONE + fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name, + strerror(errno)); +#endif + } +} +#endif + + + +static int get_mii_link_status(int sock) { + int i, mii_val[32]; + + if (ioctl(sock, SIOCGMIIPHY, &ifr) < 0) { + if (errno != ENODEV) +#ifdef STANDALONE + fprintf(stderr, "SIOCGMIIPHY on '%s' failed: %s\n", + ifr.ifr_name, strerror(errno)); +#endif + return -1; + } + + /* Some bits in the BMSR are latched, but we can't rely on being + the only reader, so only the current values are meaningful */ + mdio_read(sock, MII_BMSR); + for (i = 0; i < 8; i++) + mii_val[i] = mdio_read(sock, i); + + if (mii_val[MII_BMCR] == 0xffff) { +#ifdef STANDALONE + fprintf(stderr, " No MII transceiver present!.\n"); +#endif + return -1; + } + + if (mii_val[MII_BMSR] & BMSR_LSTATUS) + return 1; + else + return 0; +} + +static int get_ethtool_link_status(int sock) { + struct ethtool_value edata; + int rc; + + edata.cmd = ETHTOOL_GLINK; + ifr.ifr_data = (caddr_t)&edata; + rc = ioctl(sock, SIOCETHTOOL, &ifr); + if (rc == 0) { + return edata.data; + } else if (errno != EOPNOTSUPP) { +#ifdef STANDALONE + fprintf(stderr, "Cannot get link status (%d): %s\n", errno, strerror(errno)); +#endif + } + + return -1; +} + + + +int get_link_status(char * devname) { + int sock, rc; + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { +#ifdef STANDALONE + fprintf(stderr, "Error creating socket: %s\n", strerror(errno)); +#endif + return -1; + } + + /* make sure interface is up and activated */ + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, devname); + + if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { + return -1; + } + + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + + if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) { + return -1; + } + + /* Setup our control structures. */ + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, devname); + + /* check for link with both ethtool and mii registers. ethtool is + * supposed to be the One True Way (tm), but it seems to not work + * with much yet :/ */ + + rc = get_ethtool_link_status(sock); +#ifdef STANDALONE + printf("ethtool link status of %s is: %d\n", devname, rc); +#endif + if (rc == 1) { + close(sock); + return 1; + } + + rc = get_mii_link_status(sock); +#ifdef STANDALONE + printf("MII link status of %s is: %d\n", devname, rc); +#endif + if (rc == 1) { + close(sock); + return 1; + } + + return 0; +} + +#ifdef STANDALONE +/* hooray for stupid test programs! */ +int main(int argc, char **argv) { + char * dev; + + if (argc >= 2) + dev = argv[1]; + else + dev = strdup("eth0"); + + printf("link status of %s is %d\n", dev, get_link_status(dev)); + return 0; +} +#endif diff --git a/bin/isys/log.c b/bin/isys/log.c new file mode 100644 index 0000000..da39c7b --- /dev/null +++ b/bin/isys/log.c @@ -0,0 +1,224 @@ +/* + * log.c - logging functionality + * + * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Erik Troan <ewt@xxxxxxxxxx> + * Matt Wilson <msw@xxxxxxxxxx> + * Michael Fulbright <msf@xxxxxxxxxx> + * Jeremy Katz <katzj@xxxxxxxxxx> + */ + +#include <fcntl.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> +#include <sys/time.h> +#include <syslog.h> + +#include "log.h" + +static FILE * main_log_tty = NULL; +static FILE * main_log_file = NULL; +static FILE * program_log_file = NULL; +static int minLevel = INFO; +static const char * main_tag = "loader"; +static const char * program_tag = "program"; +static const int syslog_facility = LOG_LOCAL0; + +/* maps our loglevel to syslog loglevel */ +static int mapLogLevel(int level) +{ + switch (level) { + case DEBUGLVL: + return LOG_DEBUG; + case INFO: + return LOG_INFO; + case WARNING: + return LOG_WARNING; + case CRITICAL: + return LOG_CRIT; + case ERROR: + default: + /* if someone called us with an invalid level value, log it as an error + too. */ + return LOG_ERR; + } +} + +static void printLogHeader(int level, const char *tag, FILE *outfile) { + struct timeval current_time; + struct tm *t; + int msecs; + + gettimeofday(¤t_time, NULL); + t = gmtime(¤t_time.tv_sec); + msecs = current_time.tv_usec / 1000; + switch (level) { + case DEBUGLVL: + fprintf (outfile, "%02d:%02d:%02d,%03d DEBUG %s: ", t->tm_hour, + t->tm_min, t->tm_sec, msecs, tag); + break; + + case INFO: + fprintf (outfile, "%02d:%02d:%02d,%03d INFO %s: ", t->tm_hour, + t->tm_min, t->tm_sec, msecs, tag); + break; + + case WARNING: + fprintf (outfile, "%02d:%02d:%02d,%03d WARNING %s: ", t->tm_hour, + t->tm_min, t->tm_sec, msecs, tag); + break; + + case ERROR: + fprintf (outfile, "%02d:%02d:%02d,%03d ERROR %s: ", t->tm_hour, + t->tm_min, t->tm_sec, msecs, tag); + break; + + case CRITICAL: + fprintf (outfile, "%02d:%02d:%02d,%03d CRITICAL %s: ", t->tm_hour, + t->tm_min, t->tm_sec, msecs, tag); + break; + } +} + +static void printLogMessage(int level, const char *tag, FILE *outfile, const char *s, va_list ap) +{ + printLogHeader(level, tag, outfile); + + va_list apc; + va_copy(apc, ap); + vfprintf(outfile, s, apc); + va_end(apc); + + fprintf(outfile, "\n"); + fflush(outfile); +} + +static void retagSyslog(const char* new_tag) +{ + closelog(); + openlog(new_tag, 0, syslog_facility); +} + +void logMessageV(enum logger_t logger, int level, const char * s, va_list ap) { + FILE *log_tty = main_log_tty; + FILE *log_file = main_log_file; + const char *tag = main_tag; + if (logger == PROGRAM_LOG) { + /* tty output is done directly for programs */ + log_tty = NULL; + log_file = program_log_file; + tag = program_tag; + /* close and reopen syslog so we get the tagging right */ + retagSyslog(tag); + } + + va_list apc; + /* Log everything into syslog */ + va_copy(apc, ap); + vsyslog(mapLogLevel(level), s, apc); + va_end(apc); + + /* Only log to the screen things that are above the minimum level. */ + if (main_log_tty && level >= minLevel && log_tty) { + printLogMessage(level, tag, log_tty, s, ap); + } + + /* But log everything to the file. */ + if (main_log_file) { + printLogMessage(level, tag, log_file, s, ap); + } + + /* change the syslog tag back to the default again */ + if (logger == PROGRAM_LOG) + retagSyslog(main_tag); +} + +void logMessage(int level, const char * s, ...) { + va_list args; + + va_start(args, s); + logMessageV(MAIN_LOG, level, s, args); + va_end(args); +} + +void logProgramMessage(int level, const char * s, ...) { + va_list args; + + va_start(args, s); + logMessageV(PROGRAM_LOG, level, s, args); + va_end(args); +} + +int tty_logfd = -1; +int file_logfd = -1; + +void openLog() { + /* init syslog logging (so loader messages can also be forwarded to a remote + syslog daemon */ + openlog(main_tag, 0, syslog_facility); + + int flags; + main_log_tty = fopen("/dev/tty3", "a"); + main_log_file = fopen("/tmp/anaconda.log", "a"); + program_log_file = fopen("/tmp/program.log", "a"); + + if (main_log_tty) { + tty_logfd = fileno(main_log_tty); + flags = fcntl(tty_logfd, F_GETFD, 0) | FD_CLOEXEC; + fcntl(tty_logfd, F_SETFD, flags); + } + + if (main_log_file) { + file_logfd = fileno(main_log_file); + flags = fcntl(file_logfd, F_GETFD, 0) | FD_CLOEXEC; + fcntl(file_logfd, F_SETFD, flags); + } + + if (program_log_file) { + int fd; + fd = fileno(program_log_file); + flags = fcntl(fd, F_GETFD, 0) | FD_CLOEXEC; + fcntl(file_logfd, F_SETFD, flags); + } +} + +void closeLog(void) { + if (main_log_tty) + fclose(main_log_tty); + if (main_log_file) + fclose(main_log_file); + if (program_log_file) + fclose(program_log_file); + + /* close syslog logger */ + closelog(); +} + +/* set the level. higher means you see more verbosity */ +void setLogLevel(int level) { + minLevel = level; +} + +int getLogLevel(void) { + return minLevel; +} + +/* vim:set shiftwidth=4 softtabstop=4: */ diff --git a/bin/isys/log.h b/bin/isys/log.h new file mode 100644 index 0000000..51de2de --- /dev/null +++ b/bin/isys/log.h @@ -0,0 +1,51 @@ +/* + * log.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _LOG_H_ +#define _LOG_H_ + +#include <stdio.h> +#include <stdarg.h> + +#define DEBUGLVL 10 +#define INFO 20 +#define WARNING 30 +#define ERROR 40 +#define CRITICAL 50 + +enum logger_t { + MAIN_LOG = 1, + PROGRAM_LOG = 2 +}; + +void logMessageV(enum logger_t logger, int level, const char * s, va_list ap) + __attribute__ ((format (printf, 3, 0))); +void logMessage(int level, const char * s, ...) + __attribute__ ((format (printf, 2, 3))); +void logProgramMessage(int level, const char * s, ...) + __attribute__ ((format (printf, 2, 3))); +void openLog(); +void closeLog(void); +void setLogLevel(int minLevel); +int getLogLevel(void); + +extern int tty_logfd; +extern int file_logfd; + +#endif /* _LOG_H_ */ diff --git a/bin/isys/stubs.h b/bin/isys/stubs.h new file mode 100644 index 0000000..40ecb22 --- /dev/null +++ b/bin/isys/stubs.h @@ -0,0 +1,44 @@ +/* + * stubs.h + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* we use gzlib when linked against dietlibc, but otherwise, we should use + zlib. it would make more sense to do the defines in the other direction, + but that causes symbol wackiness because both gunzip_open and gzip_open in + gzlib are gzopen from zlib +*/ + +#ifndef ISYS_STUB +#define ISYS_STUB + +#ifndef GZLIB +#include <zlib.h> + +#define gunzip_open(x) gzopen(x, "r") +#define gunzip_dopen gzdopen(x, "r") +#define gunzip_close gzclose +#define gunzip_read gzread +#define gzip_write gzwrite +#define gzip_open(x, y, z) gzopen(x, "w") + +#else +#include "gzlib/gzlib.h" + +#endif + +#endif diff --git a/bin/isys/uncpio.c b/bin/isys/uncpio.c new file mode 100644 index 0000000..171eb6b --- /dev/null +++ b/bin/isys/uncpio.c @@ -0,0 +1,798 @@ +/* + * uncpio.c + * + * Copyright (C) 2007 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#define HAVE_ALLOCA_H 1 +#define MAJOR_IN_SYSMACROS 1 + +#if HAVE_ALLOCA_H +# include <alloca.h> +#endif + +#define _(foo) (foo) + +#include <errno.h> +#include <fcntl.h> +#include <fnmatch.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <utime.h> + +#include "cpio.h" +#include "stubs.h" + +#if MAJOR_IN_SYSMACROS +#include <sys/sysmacros.h> +#elif MAJOR_IN_MKDEV +#include <sys/mkdev.h> +#endif + +#define CPIO_NEWC_MAGIC "070701" +#define CPIO_CRC_MAGIC "070702" +#define TRAILER "TRAILER!!!" + +/* FIXME: We don't translate between cpio and system mode bits! These + should both be the same, but really odd things are going to happen if + that's not true! */ + +/* We need to maintain our oun file pointer to allow padding */ +struct ourfd { + gzFile fd; + size_t pos; +}; + +struct hardLink { + struct hardLink * next; + char ** files; /* there are nlink of these, used by install */ + int * fileMaps; /* used by build */ + dev_t dev; + ino_t inode; + int nlink; + int linksLeft; + int createdPath; + struct stat sb; +}; + +struct cpioCrcPhysicalHeader { + char magic[6]; + char inode[8]; + char mode[8]; + char uid[8]; + char gid[8]; + char nlink[8]; + char mtime[8]; + char filesize[8]; + char devMajor[8]; + char devMinor[8]; + char rdevMajor[8]; + char rdevMinor[8]; + char namesize[8]; + char checksum[8]; /* ignored !! */ +}; + +#define PHYS_HDR_SIZE 110 /* don't depend on sizeof(struct) */ + +struct cpioHeader { + ino_t inode; + mode_t mode; + uid_t uid; + gid_t gid; + int nlink; + time_t mtime; + unsigned long size; + dev_t dev, rdev; + char * path; +}; + +static inline off_t ourread(struct ourfd * thefd, void * buf, size_t size) { + off_t i; + + i = gunzip_read(thefd->fd, buf, size); + thefd->pos += i; + + return i; +} + +static inline void padinfd(struct ourfd * fd, int modulo) { + int buf[10]; + int amount; + + amount = (modulo - fd->pos % modulo) % modulo; + ourread(fd, buf, amount); +} + +static inline int padoutfd(struct ourfd * fd, size_t * where, int modulo) { + /*static int buf[10] = { '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0' };*/ + int amount; + static int buf[512]; + + amount = (modulo - *where % modulo) % modulo; + *where += amount; + + if (gzip_write(fd->fd, buf, amount) != amount) + return CPIOERR_WRITE_FAILED; + + return 0; +} + +static int strntoul(const char * str, char ** endptr, int base, int num) { + char * buf, * end; + unsigned long ret; + + buf = alloca(num + 1); + strncpy(buf, str, num); + buf[num] = '\0'; + + ret = strtoul(buf, &end, base); + if (*end) + *endptr = (char *)(str + (end - buf)); /* XXX discards const */ + else + *endptr = ""; + + return strtoul(buf, endptr, base); +} + +#define GET_NUM_FIELD(phys, log) \ + log = strntoul(phys, &end, 16, sizeof(phys)); \ + if (*end) return CPIOERR_BAD_HEADER; +#define SET_NUM_FIELD(phys, val, space) \ + sprintf(space, "%8.8lx", (unsigned long) (val)); \ + memcpy(phys, space, 8); + +static int getNextHeader(struct ourfd * fd, struct cpioHeader * chPtr, + struct cpioCrcPhysicalHeader * physHeaderPtr) { + struct cpioCrcPhysicalHeader physHeader; + int nameSize; + char * end; + int major, minor; + + if (ourread(fd, &physHeader, PHYS_HDR_SIZE) != PHYS_HDR_SIZE) + return CPIOERR_READ_FAILED; + + if (physHeaderPtr) + memcpy(physHeaderPtr, &physHeader, PHYS_HDR_SIZE); + + if (strncmp(CPIO_CRC_MAGIC, physHeader.magic, strlen(CPIO_CRC_MAGIC)) && + strncmp(CPIO_NEWC_MAGIC, physHeader.magic, strlen(CPIO_NEWC_MAGIC))) + return CPIOERR_BAD_MAGIC; + + GET_NUM_FIELD(physHeader.inode, chPtr->inode); + GET_NUM_FIELD(physHeader.mode, chPtr->mode); + GET_NUM_FIELD(physHeader.uid, chPtr->uid); + GET_NUM_FIELD(physHeader.gid, chPtr->gid); + GET_NUM_FIELD(physHeader.nlink, chPtr->nlink); + GET_NUM_FIELD(physHeader.mtime, chPtr->mtime); + GET_NUM_FIELD(physHeader.filesize, chPtr->size); + + GET_NUM_FIELD(physHeader.devMajor, major); + GET_NUM_FIELD(physHeader.devMinor, minor); + chPtr->dev = makedev(major, minor); + + GET_NUM_FIELD(physHeader.rdevMajor, major); + GET_NUM_FIELD(physHeader.rdevMinor, minor); + chPtr->rdev = makedev(major, minor); + + GET_NUM_FIELD(physHeader.namesize, nameSize); + + chPtr->path = malloc(nameSize + 1); + if (ourread(fd, chPtr->path, nameSize) != nameSize) { + free(chPtr->path); + return CPIOERR_BAD_HEADER; + } + + /* this is unecessary chPtr->path[nameSize] = '\0'; */ + + padinfd(fd, 4); + + return 0; +} + +int myCpioFileMapCmp(const void * a, const void * b) { + const struct cpioFileMapping * first = a; + const struct cpioFileMapping * second = b; + + return (strcmp(first->archivePath, second->archivePath)); +} + +/* This could trash files in the path! I'm not sure that's a good thing */ +static int createDirectory(char * path, mode_t perms) { + struct stat sb; + int dounlink; + + if (!lstat(path, &sb)) { + if (S_ISDIR(sb.st_mode)) { + return 0; + } else if (S_ISLNK(sb.st_mode)) { + if (stat(path, &sb)) { + if (errno != ENOENT) + return CPIOERR_STAT_FAILED; + dounlink = 1; + } else { + if (S_ISDIR(sb.st_mode)) + return 0; + dounlink = 1; + } + } else { + dounlink = 1; + } + + if (dounlink && unlink(path)) { + return CPIOERR_UNLINK_FAILED; + } + } + + if (mkdir(path, 000)) + return CPIOERR_MKDIR_FAILED; + + if (chmod(path, perms)) + return CPIOERR_CHMOD_FAILED; + + return 0; +} + +static int setInfo(struct cpioHeader * hdr) { + int rc = 0; + struct utimbuf stamp; + + stamp.actime = hdr->mtime; + stamp.modtime = hdr->mtime; + + if (!S_ISLNK(hdr->mode)) { + if (!getuid() && chown(hdr->path, hdr->uid, hdr->gid)) + rc = CPIOERR_CHOWN_FAILED; + if (!rc && chmod(hdr->path, hdr->mode & 07777)) + rc = CPIOERR_CHMOD_FAILED; + if (!rc && utime(hdr->path, &stamp)) + rc = CPIOERR_UTIME_FAILED; + } else { +# if ! CHOWN_FOLLOWS_SYMLINK + if (!getuid() && !rc && lchown(hdr->path, hdr->uid, hdr->gid)) + rc = CPIOERR_CHOWN_FAILED; +# endif + } + + return rc; +} + +static int checkDirectory(char * filename) { + static char * lastDir = NULL; + static int lastDirLength = 0; + static int lastDirAlloced = 0; + int length = strlen(filename); + char * buf; + char * chptr; + int rc = 0; + + buf = alloca(length + 1); + strcpy(buf, filename); + + for (chptr = buf + length - 1; chptr > buf; chptr--) { + if (*chptr == '/') break; + } + + if (chptr == buf) return 0; /* /filename - no directories */ + + *chptr = '\0'; /* buffer is now just directories */ + + length = strlen(buf); + if (lastDirLength == length && !strcmp(buf, lastDir)) return 0; + + if (lastDirAlloced < (length + 1)) { + lastDirAlloced = length + 100; + lastDir = realloc(lastDir, lastDirAlloced); + } + + strcpy(lastDir, buf); + lastDirLength = length; + + for (chptr = buf + 1; *chptr; chptr++) { + if (*chptr == '/') { + *chptr = '\0'; + rc = createDirectory(buf, 0755); + *chptr = '/'; + if (rc) return rc; + } + } + rc = createDirectory(buf, 0755); + + return rc; +} + +static int expandRegular(struct ourfd * fd, struct cpioHeader * hdr, + cpioCallback cb, void * cbData) { + int out; + char buf[8192]; + int bytesRead; + unsigned long left = hdr->size; + int rc = 0; + struct cpioCallbackInfo cbInfo; + struct stat sb; + + if (!lstat(hdr->path, &sb)) + if (unlink(hdr->path)) + return CPIOERR_UNLINK_FAILED; + + out = open(hdr->path, O_CREAT | O_WRONLY, 0); + if (out < 0) + return CPIOERR_OPEN_FAILED; + + cbInfo.file = hdr->path; + cbInfo.fileSize = hdr->size; + + while (left) { + bytesRead = ourread(fd, buf, left < sizeof(buf) ? left : sizeof(buf)); + if (bytesRead <= 0) { + rc = CPIOERR_READ_FAILED; + break; + } + + if (write(out, buf, bytesRead) != bytesRead) { + rc = CPIOERR_COPY_FAILED; + break; + } + + left -= bytesRead; + + /* don't call this with fileSize == fileComplete */ + if (!rc && cb && left) { + cbInfo.fileComplete = hdr->size - left; + cbInfo.bytesProcessed = fd->pos; + cb(&cbInfo, cbData); + } + } + + close(out); + + return rc; +} + +static int expandSymlink(struct ourfd * fd, struct cpioHeader * hdr) { + char buf[2048], buf2[2048]; + struct stat sb; + int len; + + if ((hdr->size + 1)> sizeof(buf)) + return CPIOERR_INTERNAL; + + if (ourread(fd, buf, hdr->size) != hdr->size) + return CPIOERR_READ_FAILED; + + buf[hdr->size] = '\0'; + + if (!lstat(hdr->path, &sb)) { + if (S_ISLNK(sb.st_mode)) { + len = readlink(hdr->path, buf2, sizeof(buf2) - 1); + if (len > 0) { + buf2[len] = '\0'; + if (!strcmp(buf, buf2)) return 0; + } + } + + if (unlink(hdr->path)) + return CPIOERR_UNLINK_FAILED; + } + + if (symlink(buf, hdr->path) < 0) + return CPIOERR_SYMLINK_FAILED; + + return 0; +} + +static int expandFifo(struct ourfd * fd, struct cpioHeader * hdr) { + struct stat sb; + + if (!lstat(hdr->path, &sb)) { + if (S_ISFIFO(sb.st_mode)) return 0; + + if (unlink(hdr->path)) + return CPIOERR_UNLINK_FAILED; + } + + if (mkfifo(hdr->path, 0)) + return CPIOERR_MKFIFO_FAILED; + + return 0; +} + +static int expandDevice(struct ourfd * fd, struct cpioHeader * hdr) { + struct stat sb; + + if (!lstat(hdr->path, &sb)) { + if ((S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) && + (sb.st_rdev == hdr->rdev)) + return 0; + if (unlink(hdr->path)) + return CPIOERR_UNLINK_FAILED; + } + + if (mknod(hdr->path, hdr->mode & (~0777), hdr->rdev)) + return CPIOERR_MKNOD_FAILED; + + return 0; +} + +static void freeLink(struct hardLink * li) { + int i; + + for (i = 0; i < li->nlink; i++) { + if (li->files[i]) free(li->files[i]); + } + free(li->files); +} + +static int createLinks(struct hardLink * li, const char ** failedFile) { + int i; + struct stat sb; + + for (i = 0; i < li->nlink; i++) { + if (i == li->createdPath) continue; + if (!li->files[i]) continue; + + if (!lstat(li->files[i], &sb)) { + if (unlink(li->files[i])) { + *failedFile = strdup(li->files[i]); + return CPIOERR_UNLINK_FAILED; + } + } + + if (link(li->files[li->createdPath], li->files[i])) { + *failedFile = strdup(li->files[i]); + return CPIOERR_LINK_FAILED; + } + + free(li->files[i]); + li->files[i] = NULL; + li->linksLeft--; + } + + return 0; +} + +static int eatBytes(struct ourfd * fd, unsigned long amount) { + char buf[4096]; + unsigned long bite; + + while (amount) { + bite = (amount > sizeof(buf)) ? sizeof(buf) : amount; + if (ourread(fd, buf, bite) != bite) + return CPIOERR_READ_FAILED; + amount -= bite; + } + + return 0; +} + +int myCpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings, + int numMappings, cpioCallback cb, void * cbData, + const char ** failedFile) { + struct cpioHeader ch; + struct ourfd fd; + int rc = 0; + int linkNum = 0; + struct cpioFileMapping * map = NULL; + struct cpioFileMapping needle; + mode_t cpioMode; + int olderr; + struct cpioCallbackInfo cbInfo; + struct hardLink * links = NULL; + struct hardLink * li = NULL; + + fd.fd = stream; + fd.pos = 0; + + *failedFile = NULL; + + do { + if ((rc = getNextHeader(&fd, &ch, NULL))) { + fprintf(stderr, _("error %d reading header: %s\n"), rc, + myCpioStrerror(rc)); + return CPIOERR_BAD_HEADER; + } + + if (!strcmp(ch.path, TRAILER)) { + free(ch.path); + break; + } + + if (mappings) { + needle.archivePath = ch.path; + map = bsearch(&needle, mappings, numMappings, sizeof(needle), + myCpioFileMapCmp); + } + + if (mappings && !map) { + eatBytes(&fd, ch.size); + } else { + cpioMode = ch.mode; + + if (map) { + if (map->mapFlags & CPIO_MAP_PATH) { + free(ch.path); + ch.path = strdup(map->fsPath); + } + + if (map->mapFlags & CPIO_MAP_MODE) + ch.mode = map->finalMode; + if (map->mapFlags & CPIO_MAP_UID) + ch.uid = map->finalUid; + if (map->mapFlags & CPIO_MAP_GID) + ch.gid = map->finalGid; + } + + /* This won't get hard linked symlinks right, but I can't seem + to create those anyway */ + + if (S_ISREG(ch.mode) && ch.nlink > 1) { + li = links; + for (li = links; li; li = li->next) { + if (li->inode == ch.inode && li->dev == ch.dev) break; + } + + if (!li) { + li = malloc(sizeof(*li)); + li->inode = ch.inode; + li->dev = ch.dev; + li->nlink = ch.nlink; + li->linksLeft = ch.nlink; + li->createdPath = -1; + li->files = calloc(sizeof(char *), li->nlink); + li->next = links; + links = li; + } + + for (linkNum = 0; linkNum < li->nlink; linkNum++) + if (!li->files[linkNum]) break; + li->files[linkNum] = strdup(ch.path); + } + + if ((ch.nlink > 1) && S_ISREG(ch.mode) && !ch.size && + li->createdPath == -1) { + /* defer file creation */ + } else if ((ch.nlink > 1) && S_ISREG(ch.mode) && + (li->createdPath != -1)) { + createLinks(li, failedFile); + + /* this only happens for cpio archives which contain + hardlinks w/ the contents of each hardlink being + listed (intead of the data being given just once. This + shouldn't happen, but I've made it happen w/ buggy + code, so what the heck? GNU cpio handles this well fwiw */ + if (ch.size) eatBytes(&fd, ch.size); + } else { + rc = checkDirectory(ch.path); + + if (!rc) { + if (S_ISREG(ch.mode)) + rc = expandRegular(&fd, &ch, cb, cbData); + else if (S_ISDIR(ch.mode)) + rc = createDirectory(ch.path, 000); + else if (S_ISLNK(ch.mode)) + rc = expandSymlink(&fd, &ch); + else if (S_ISFIFO(ch.mode)) + rc = expandFifo(&fd, &ch); + else if (S_ISCHR(ch.mode) || S_ISBLK(ch.mode)) + rc = expandDevice(&fd, &ch); + else if (S_ISSOCK(ch.mode)) { + /* this mimicks cpio but probably isnt' right */ + rc = expandFifo(&fd, &ch); + } else { + rc = CPIOERR_INTERNAL; + } + } + + if (!rc) + rc = setInfo(&ch); + + if (S_ISREG(ch.mode) && ch.nlink > 1) { + li->createdPath = linkNum; + li->linksLeft--; + rc = createLinks(li, failedFile); + } + } + + if (rc && !*failedFile) { + *failedFile = strdup(ch.path); + + olderr = errno; + unlink(ch.path); + errno = olderr; + } + } + + padinfd(&fd, 4); + + if (!rc && cb) { + cbInfo.file = ch.path; + cbInfo.fileSize = ch.size; + cbInfo.fileComplete = ch.size; + cbInfo.bytesProcessed = fd.pos; + cb(&cbInfo, cbData); + } + + free(ch.path); + } while (1 && !rc); + + li = links; + while (li && !rc) { + if (li->linksLeft) { + if (li->createdPath == -1) + rc = CPIOERR_INTERNAL; + else + rc = createLinks(li, failedFile); + } + + freeLink(li); + + links = li; + li = li->next; + free(links); + links = li; + } + + li = links; + /* if an error got us here links will still be eating some memory */ + while (li) { + freeLink(li); + links = li; + li = li->next; + free(links); + } + + return rc; +} + +const char * myCpioStrerror(int rc) +{ + static char msg[256]; + char *s; + int l, myerrno = errno; + + strcpy(msg, "cpio: "); + switch (rc) { + default: + s = msg + strlen(msg); + sprintf(s, _("(error 0x%x)"), rc); + s = NULL; + break; + case CPIOERR_BAD_MAGIC: s = _("Bad magic"); break; + case CPIOERR_BAD_HEADER: s = _("Bad header"); break; + + case CPIOERR_OPEN_FAILED: s = "open"; break; + case CPIOERR_CHMOD_FAILED: s = "chmod"; break; + case CPIOERR_CHOWN_FAILED: s = "chown"; break; + case CPIOERR_WRITE_FAILED: s = "write"; break; + case CPIOERR_UTIME_FAILED: s = "utime"; break; + case CPIOERR_UNLINK_FAILED: s = "unlink"; break; + case CPIOERR_SYMLINK_FAILED: s = "symlink"; break; + case CPIOERR_STAT_FAILED: s = "stat"; break; + case CPIOERR_MKDIR_FAILED: s = "mkdir"; break; + case CPIOERR_MKNOD_FAILED: s = "mknod"; break; + case CPIOERR_MKFIFO_FAILED: s = "mkfifo"; break; + case CPIOERR_LINK_FAILED: s = "link"; break; + case CPIOERR_READLINK_FAILED: s = "readlink"; break; + case CPIOERR_READ_FAILED: s = "read"; break; + case CPIOERR_COPY_FAILED: s = "copy"; break; + + case CPIOERR_INTERNAL: s = _("Internal error"); break; + case CPIOERR_HDR_SIZE: s = _("Header size too big"); break; + case CPIOERR_UNKNOWN_FILETYPE: s = _("Unknown file type"); break; + } + + l = sizeof(msg) - strlen(msg) - 1; + if (s != NULL) { + if (l > 0) strncat(msg, s, l); + l -= strlen(s); + } + if (rc & CPIOERR_CHECK_ERRNO) { + s = _(" failed - "); + if (l > 0) strncat(msg, s, l); + l -= strlen(s); + if (l > 0) strncat(msg, strerror(myerrno), l); + } + return msg; +} + +static int copyFile(struct ourfd * inFd, struct ourfd * outFd, + struct cpioHeader * chp, struct cpioCrcPhysicalHeader * pHdr) { + char buf[8192]; + int amount; + size_t size = chp->size; + + amount = strlen(chp->path) + 1; + memcpy(pHdr->magic, CPIO_NEWC_MAGIC, sizeof(pHdr->magic)); + + gzip_write(outFd->fd, pHdr, PHYS_HDR_SIZE); + gzip_write(outFd->fd, chp->path, amount); + + outFd->pos += PHYS_HDR_SIZE + amount; + + padoutfd(outFd, &outFd->pos, 4); + + while (size) { + amount = ourread(inFd, buf, size > sizeof(buf) ? sizeof(buf) : size); + gzip_write(outFd->fd, buf, amount); + size -= amount; + } + + outFd->pos += chp->size; + + padoutfd(outFd, &outFd->pos, 4); + + return 0; +} + +int myCpioFilterArchive(gzFile inStream, gzFile outStream, char ** patterns) { + struct ourfd inFd, outFd; + char ** aPattern; + struct cpioHeader ch; + int rc; + struct cpioCrcPhysicalHeader pHeader; + + inFd.fd = inStream; + inFd.pos = 0; + outFd.fd = outStream; + outFd.pos = 0; + + do { + if ((rc = getNextHeader(&inFd, &ch, &pHeader))) { + fprintf(stderr, _("error %d reading header: %s\n"), rc, + myCpioStrerror(rc)); + return CPIOERR_BAD_HEADER; + } + + if (!strcmp(ch.path, TRAILER)) { + free(ch.path); + break; + } + + for (aPattern = patterns; *aPattern; aPattern++) + if (!fnmatch(*aPattern, ch.path, FNM_PATHNAME | FNM_PERIOD)) + break; + + if (!*aPattern) + eatBytes(&inFd, ch.size); + else + copyFile(&inFd, &outFd, &ch, &pHeader); + + padinfd(&inFd, 4); + + free(ch.path); + } while (1 && !rc); + + memset(&pHeader, '0', sizeof(pHeader)); + memcpy(pHeader.magic, CPIO_NEWC_MAGIC, sizeof(pHeader.magic)); + memcpy(pHeader.nlink, "00000001", 8); + memcpy(pHeader.namesize, "0000000b", 8); + gzip_write(outFd.fd, &pHeader, PHYS_HDR_SIZE); + gzip_write(outFd.fd, "TRAILER!!!", 11); + + outFd.pos += PHYS_HDR_SIZE + 11; + + if ((rc = padoutfd(&outFd, &outFd.pos, 4))) + return rc; + + if ((rc = padoutfd(&outFd, &outFd.pos, 512))) + return rc; + + return 0; +} diff --git a/bin/isys/vio.c b/bin/isys/vio.c new file mode 100644 index 0000000..9b06a3e --- /dev/null +++ b/bin/isys/vio.c @@ -0,0 +1,106 @@ +/* + * vio.c - probing for vio devices on the iSeries (viocd and viodasd) + * + * Copyright (C) 2003 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Jeremy Katz <katzj@xxxxxxxxxx> + */ + +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#if defined(__powerpc__) +static int readFD (int fd, char **buf) +{ + char *p; + size_t size = 4096; + int s, filesize; + + *buf = malloc (size); + if (*buf == 0) + return -1; + + filesize = 0; + do { + p = &(*buf) [filesize]; + s = read (fd, p, 4096); + if (s < 0) + break; + filesize += s; + if (s == 0) + break; + size += 4096; + *buf = realloc (*buf, size); + } while (1); + + if (filesize == 0 && s < 0) { + free (*buf); + *buf = NULL; + return -1; + } + + return filesize; +} +#endif + +int isVioConsole(void) { +#if !defined(__powerpc__) + return 0; +#else + int fd, i; + char *buf, *start; + char driver[50], device[50]; + static int isviocons = -1; + + if (isviocons != -1) + return isviocons; + + fd = open("/proc/tty/drivers", O_RDONLY); + if (fd < 0) { + fprintf(stderr, "failed to open /proc/tty/drivers!\n"); + return 0; + } + i = readFD(fd, &buf); + if (i < 1) { + close(fd); + fprintf(stderr, "error reading /proc/tty/drivers!\n"); + return 0; + } + close(fd); + buf[i] = '\0'; + + isviocons = 0; + start = buf; + while (start && *start) { + if (sscanf(start, "%s %s", (char *) &driver, (char *) &device) == 2) { + if (!strcmp(driver, "vioconsole") && !strcmp(device, "/dev/tty")) { + isviocons = 1; + break; + } + } + start = strchr(start, '\n'); + if (start) + start++; + } + free(buf); + return isviocons; +#endif +} diff --git a/bin/loader/Makefile.am b/bin/loader/Makefile.am index 18f1fbe..b42361b 100644 --- a/bin/loader/Makefile.am +++ b/bin/loader/Makefile.am @@ -47,7 +47,7 @@ loader_CFLAGS = $(COMMON_CFLAGS) $(GLIB_CFLAGS) $(LIBNM_GLIB_CFLAGS) \ loader_LDADD = $(NEWT_LIBS) $(GLIB_LIBS) $(LIBNL_LIBS) \ $(LIBNM_GLIB_LIBS) $(CHECKISOMD5_LIBS) \ $(LIBCURL_LIBS) $(LIBARCHIVE_LIBS) $(RPM_LIBS) \ - $(ISCSI_LIBS) $(top_srcdir)/isys/libisys.la -lm + $(ISCSI_LIBS) $(top_srcdir)/bin/isys/libisys.la -lm loader_SOURCES = loader.c copy.c moduleinfo.c loadermisc.c \ modules.c windows.c lang.c kbd.c driverdisk.c \ selinux.c mediacheck.c kickstart.c driverselect.c \ @@ -102,8 +102,8 @@ keymaps-override-$(ARCH): keymaps-$(ARCH) ctype.c: mkctype $(mkctype_verbose)./mkctype > ctype.c -loader.tr: $(top_srcdir)/lang-table loader.po - @LANGS="`cut -f 2 $(top_srcdir)/lang-table | egrep -v '(^en$$)'`" ; \ +loader.tr: $(top_srcdir)/data/lang-table loader.po + @LANGS="`cut -f 2 $(top_srcdir)/data/lang-table | egrep -v '(^en$$)'`" ; \ if [ ! -d tr ]; then \ mkdir -p tr ; \ fi ; \ diff --git a/bin/loader/modules.c b/bin/loader/modules.c index 89f956c..b408092 100644 --- a/bin/loader/modules.c +++ b/bin/loader/modules.c @@ -430,7 +430,7 @@ int processModuleLines(GTree *data, int (*f)(gchar**, GTree*)){ if (getline(&line, &linesize, file) < 0) break; - if (*line == NULL) + if (line == NULL) break; lineparts = g_strsplit_set(line, " ", 4); diff --git a/configure.ac b/configure.ac index 54c4084..ec57c38 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ AC_PREREQ([2.63]) AC_INIT([anaconda], [14.5], [anaconda-devel-list@xxxxxxxxxx]) AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-bzip2]) -AC_CONFIG_SRCDIR([loader/loader.c]) +AC_CONFIG_SRCDIR([bin/loader/loader.c]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) @@ -261,13 +261,25 @@ AC_CONFIG_FILES([Makefile bin/Makefile bin/gptsync/Makefile pyanaconda/installclasses/Makefile - pyanaconda/isys/Makefile + bin/isys/Makefile pyanaconda/iw/Makefile data/liveinst/Makefile data/liveinst/console.apps/Makefile data/liveinst/pam.d/Makefile bin/loader/Makefile data/pixmaps/Makefile + data/icons/Makefile + data/icons/hicolor/Makefile + data/icons/hicolor/16x16/Makefile + data/icons/hicolor/16x16/apps/Makefile + data/icons/hicolor/22x22/Makefile + data/icons/hicolor/22x22/apps/Makefile + data/icons/hicolor/24x24/Makefile + data/icons/hicolor/24x24/apps/Makefile + data/icons/hicolor/32x32/Makefile + data/icons/hicolor/32x32/apps/Makefile + data/icons/hicolor/48x48/Makefile + data/icons/hicolor/48x48/apps/Makefile po/Makefile.in scripts/Makefile pyanaconda/Makefile @@ -275,6 +287,7 @@ AC_CONFIG_FILES([Makefile pyanaconda/storage/devicelibs/Makefile pyanaconda/storage/formats/Makefile tests/Makefile + tests/mock/Makefile tests/kickstart_test/Makefile tests/storage_test/Makefile tests/storage_test/devicelibs_test/Makefile diff --git a/data/Makefile.am b/data/Makefile.am index 841d340..cf87810 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -32,5 +32,5 @@ dist_lang_DATA = lang-table MAINTAINERCLEANFILES = Makefile.in lang-names: lang-table - PYTHONPATH="../" $(PYTHON) scripts/getlangnames.py > lang-names + PYTHONPATH="$(top_srcdir)/:$(top_srcdir)/bin:$(top_srcdir)/bin/isys/.libs" $(PYTHON) ../scripts/getlangnames.py > lang-names diff --git a/po/POTFILES.in b/po/POTFILES.in index 382f878..1609f17 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -3,152 +3,152 @@ # Main anaconda source files anaconda -backend.py -bootloader.py -cmdline.py -compssort.py -constants.py -firewall.py -gui.py -image.py -installclass.py -installinterfacebase.py -iutil.py -kickstart.py -livecd.py -network.py -packages.py -partIntfHelpers.py -platform.py -rescue.py -text.py -upgrade.py -vnc.py -yuminstall.py +pyanaconda/backend.py +pyanaconda/bootloader.py +pyanaconda/cmdline.py +pyanaconda/compssort.py +pyanaconda/constants.py +pyanaconda/firewall.py +pyanaconda/gui.py +pyanaconda/image.py +pyanaconda/installclass.py +pyanaconda/installinterfacebase.py +pyanaconda/iutil.py +pyanaconda/kickstart.py +pyanaconda/livecd.py +pyanaconda/network.py +pyanaconda/packages.py +pyanaconda/partIntfHelpers.py +pyanaconda/platform.py +pyanaconda/rescue.py +pyanaconda/text.py +pyanaconda/upgrade.py +pyanaconda/vnc.py +pyanaconda/yuminstall.py # Install class definitions -installclasses/fedora.py -installclasses/rhel.py +pyanaconda/installclasses/fedora.py +pyanaconda/installclasses/rhel.py # Graphical user interface source files -iw/DeviceSelector.py -iw/GroupSelector.py -iw/account_gui.py -iw/advanced_storage.py -iw/autopart_type.py -iw/blpasswidget.py -iw/bootloader_main_gui.py -iw/checklist.py -iw/cleardisks_gui.py -iw/congrats_gui.py -iw/datacombo.py -iw/examine_gui.py -iw/filter_gui.py -iw/filter_type.py -iw/iw_gui.py -iw/language_gui.py -iw/lvm_dialog_gui.py -iw/netconfig_dialog.py -iw/network_gui.py -iw/osbootwidget.py -iw/package_gui.py -iw/partition_dialog_gui.py -iw/partition_gui.py -iw/partition_ui_helpers_gui.py -iw/pixmapRadioButtonGroup_gui.py -iw/raid_dialog_gui.py -iw/task_gui.py -iw/timezone_gui.py -iw/upgrade_bootloader_gui.py -iw/upgrade_migratefs_gui.py -iw/upgrade_swap_gui.py -iw/welcome_gui.py -iw/zipl_gui.py +pyanaconda/iw/DeviceSelector.py +pyanaconda/iw/GroupSelector.py +pyanaconda/iw/account_gui.py +pyanaconda/iw/advanced_storage.py +pyanaconda/iw/autopart_type.py +pyanaconda/iw/blpasswidget.py +pyanaconda/iw/bootloader_main_gui.py +pyanaconda/iw/checklist.py +pyanaconda/iw/cleardisks_gui.py +pyanaconda/iw/congrats_gui.py +pyanaconda/iw/datacombo.py +pyanaconda/iw/examine_gui.py +pyanaconda/iw/filter_gui.py +pyanaconda/iw/filter_type.py +pyanaconda/iw/iw_gui.py +pyanaconda/iw/language_gui.py +pyanaconda/iw/lvm_dialog_gui.py +pyanaconda/iw/netconfig_dialog.py +pyanaconda/iw/network_gui.py +pyanaconda/iw/osbootwidget.py +pyanaconda/iw/package_gui.py +pyanaconda/iw/partition_dialog_gui.py +pyanaconda/iw/partition_gui.py +pyanaconda/iw/partition_ui_helpers_gui.py +pyanaconda/iw/pixmapRadioButtonGroup_gui.py +pyanaconda/iw/raid_dialog_gui.py +pyanaconda/iw/task_gui.py +pyanaconda/iw/timezone_gui.py +pyanaconda/iw/upgrade_bootloader_gui.py +pyanaconda/iw/upgrade_migratefs_gui.py +pyanaconda/iw/upgrade_swap_gui.py +pyanaconda/iw/welcome_gui.py +pyanaconda/iw/zipl_gui.py # Loader source files -loader/cdinstall.c -loader/copy.c -loader/dirbrowser.c -loader/driverdisk.c -loader/driverselect.c -loader/hdinstall.c -loader/kbd.c -loader/kickstart.c -loader/lang.c -loader/loader.c -loader/mediacheck.c -loader/method.c -loader/modules.c -loader/net.c -loader/nfsinstall.c -loader/telnetd.c -loader/urlinstall.c -loader/urls.c -loader/windows.c +bin/loader/cdinstall.c +bin/loader/copy.c +bin/loader/dirbrowser.c +bin/loader/driverdisk.c +bin/loader/driverselect.c +bin/loader/hdinstall.c +bin/loader/kbd.c +bin/loader/kickstart.c +bin/loader/lang.c +bin/loader/loader.c +bin/loader/mediacheck.c +bin/loader/method.c +bin/loader/modules.c +bin/loader/net.c +bin/loader/nfsinstall.c +bin/loader/telnetd.c +bin/loader/urlinstall.c +bin/loader/urls.c +bin/loader/windows.c # Storage module source files -storage/__init__.py -storage/dasd.py -storage/deviceaction.py -storage/devicelibs/crypto.py -storage/devicelibs/dm.py -storage/devicelibs/lvm.py -storage/devicelibs/mdraid.py -storage/devicelibs/swap.py -storage/devices.py -storage/devicetree.py -storage/fcoe.py -storage/formats/__init__.py -storage/formats/disklabel.py -storage/formats/dmraid.py -storage/formats/fs.py -storage/formats/luks.py -storage/formats/lvmpv.py -storage/formats/mdraid.py -storage/formats/multipath.py -storage/formats/swap.py -storage/iscsi.py -storage/partitioning.py -storage/zfcp.py +pyanaconda/storage/__init__.py +pyanaconda/storage/dasd.py +pyanaconda/storage/deviceaction.py +pyanaconda/storage/devicelibs/crypto.py +pyanaconda/storage/devicelibs/dm.py +pyanaconda/storage/devicelibs/lvm.py +pyanaconda/storage/devicelibs/mdraid.py +pyanaconda/storage/devicelibs/swap.py +pyanaconda/storage/devices.py +pyanaconda/storage/devicetree.py +pyanaconda/storage/fcoe.py +pyanaconda/storage/formats/__init__.py +pyanaconda/storage/formats/disklabel.py +pyanaconda/storage/formats/dmraid.py +pyanaconda/storage/formats/fs.py +pyanaconda/storage/formats/luks.py +pyanaconda/storage/formats/lvmpv.py +pyanaconda/storage/formats/mdraid.py +pyanaconda/storage/formats/multipath.py +pyanaconda/storage/formats/swap.py +pyanaconda/storage/iscsi.py +pyanaconda/storage/partitioning.py +pyanaconda/storage/zfcp.py # Text mode user interface source files -textw/complete_text.py -textw/constants_text.py -textw/keyboard_text.py -textw/language_text.py -textw/netconfig_text.py -textw/partition_text.py -textw/progress_text.py -textw/timezone_text.py -textw/upgrade_bootloader_text.py -textw/upgrade_text.py -textw/userauth_text.py -textw/welcome_text.py -textw/zipl_text.py +pyanaconda/textw/complete_text.py +pyanaconda/textw/constants_text.py +pyanaconda/textw/keyboard_text.py +pyanaconda/textw/language_text.py +pyanaconda/textw/netconfig_text.py +pyanaconda/textw/partition_text.py +pyanaconda/textw/progress_text.py +pyanaconda/textw/timezone_text.py +pyanaconda/textw/upgrade_bootloader_text.py +pyanaconda/textw/upgrade_text.py +pyanaconda/textw/userauth_text.py +pyanaconda/textw/welcome_text.py +pyanaconda/textw/zipl_text.py # liveinst source files -liveinst/liveinst.desktop.in.h -liveinst/console.apps/liveinst.h +data/liveinst/liveinst.desktop.in.h +data/liveinst/console.apps/liveinst.h # Glade definition files -ui/GroupSelector.glade.h -ui/account.glade.h -ui/adddrive.glade.h -ui/addrepo.glade.h -ui/anaconda.glade.h -ui/autopart.glade.h -ui/blwhere.glade.h -ui/cleardisks.glade.h -ui/create-storage.glade.h -ui/detailed-dialog.glade.h -ui/fcoe-config.glade.h -ui/filter.glade.h -ui/iscsi-config.glade.h -ui/lukspassphrase.glade.h -ui/netconfig.glade.h -ui/network.glade.h -ui/tasksel.glade.h -ui/zfcp-config.glade.h +data/ui/GroupSelector.glade.h +data/ui/account.glade.h +data/ui/adddrive.glade.h +data/ui/addrepo.glade.h +data/ui/anaconda.glade.h +data/ui/autopart.glade.h +data/ui/blwhere.glade.h +data/ui/cleardisks.glade.h +data/ui/create-storage.glade.h +data/ui/detailed-dialog.glade.h +data/ui/fcoe-config.glade.h +data/ui/filter.glade.h +data/ui/iscsi-config.glade.h +data/ui/lukspassphrase.glade.h +data/ui/netconfig.glade.h +data/ui/network.glade.h +data/ui/tasksel.glade.h +data/ui/zfcp-config.glade.h # lang-table -lang-table.h +data/lang-table.h diff --git a/pyanaconda/Makefile.am b/pyanaconda/Makefile.am index f156057..0b9df77 100644 --- a/pyanaconda/Makefile.am +++ b/pyanaconda/Makefile.am @@ -17,7 +17,7 @@ # # Author: Martin Sivak <msivak@xxxxxxxxxx> -SUBDIRS = installclasses iw iw textw storage +SUBDIRS = installclasses iw textw storage MAINTAINERCLEANFILES = Makefile.in diff --git a/pyanaconda/isys/.gitignore b/pyanaconda/isys/.gitignore deleted file mode 100644 index 0b04e81..0000000 --- a/pyanaconda/isys/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -*.pyc -.depend -*.lo -*.do -nfs_mountversion.h -auditd diff --git a/pyanaconda/isys/Makefile.am b/pyanaconda/isys/Makefile.am deleted file mode 100644 index 8b5dd00..0000000 --- a/pyanaconda/isys/Makefile.am +++ /dev/null @@ -1,56 +0,0 @@ -# isys/Makefile.am for anaconda -# -# Copyright (C) 2009 Red Hat, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -# Author: David Cantrell <dcantrell@xxxxxxxxxx> - -pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME) - -ISYS_SRCS = devices.c imount.c cpio.c uncpio.c lang.c \ - isofs.c linkdetect.c vio.c ethtool.c eddsupport.c iface.c \ - auditd.c log.c - -dist_noinst_HEADERS = *.h - -ISYS_CFLAGS = -DVERSION='"$(PACKAGE_VERSION)"' $(NFS_CFLAGS) \ - $(NETWORKMANAGER_CFLAGS) $(LIBNL_CFLAGS) $(LIBNM_GLIB_CFLAGS) \ - $(SELINUX_CFLAGS) -ISYS_LIBS = $(RESOLV_LIBS) $(EXT2FS_LIBS) $(ZLIB_LIBS) \ - $(DEVMAPPER_LIBS) $(BLKID_LIBS) $(X11_LIBS) $(SELINUX_LIBS) \ - $(LIBNL_LIBS) $(LIBNM_GLIB_LIBS) - -isysdir = $(pkgpyexecdir)/isys -isys_PYTHON = *.py - -pkgpyexec_LTLIBRARIES = _isys.la -_isys_la_CFLAGS = $(PYTHON_INCLUDES) $(ISYS_CFLAGS) -_isys_la_LDFLAGS = -module -avoid-version $(PYTHON_LDFLAGS) -_isys_la_LIBADD = $(PYTHON_LIBS) $(ISYS_LIBS) -_isys_la_SOURCES = isys.c $(ISYS_SRCS) - -noinst_LTLIBRARIES = libisys.la -libisys_la_CFLAGS = $(ISYS_CFLAGS) -libisys_la_LDFLAGS = -static -libisys_la_LIBADD = $(ISYS_LIBS) -libisys_la_SOURCES = $(ISYS_SRCS) - -auditddir = $(libexecdir)/$(PACKAGE_NAME) -auditd_PROGRAMS = auditd -auditd_SOURCES = auditd.c -auditd_CFLAGS = -DSTANDALONE $(SELINUX_CFLAGS) -auditd_LDADD = $(SELINUX_LIBS) $(LIBNL_LIBS) - -MAINTAINERCLEANFILES = Makefile.in diff --git a/pyanaconda/isys/__init__.py b/pyanaconda/isys/__init__.py deleted file mode 100755 index d340bf3..0000000 --- a/pyanaconda/isys/__init__.py +++ /dev/null @@ -1,560 +0,0 @@ -# -# isys.py - installer utility functions and glue for C module -# -# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. -# All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -# Author(s): Matt Wilson <msw@xxxxxxxxxx> -# Erik Troan <ewt@xxxxxxxxxx> -# Jeremy Katz <katzj@xxxxxxxxxx> -# - -import _isys -import string -import os -import os.path -import socket -import stat -import posix -import sys -import ..iutil -import warnings -import resource -import re -import struct -import block -import dbus -import selinux - -import ..logging -log = logging.getLogger("anaconda") - -NM_SERVICE = "org.freedesktop.NetworkManager" -NM_MANAGER_PATH = "/org/freedesktop/NetworkManager" -NM_MANAGER_IFACE = "org.freedesktop.NetworkManager" -NM_ACTIVE_CONNECTION_IFACE = "org.freedesktop.NetworkManager.Connection.Active" -NM_CONNECTION_IFACE = "org.freedesktop.NetworkManagerSettings.Connection" -NM_DEVICE_IFACE = "org.freedesktop.NetworkManager.Device" - -NM_STATE_UNKNOWN = 0 -NM_STATE_ASLEEP = 1 -NM_STATE_CONNECTING = 2 -NM_STATE_CONNECTED = 3 -NM_STATE_DISCONNECTED = 4 - -DBUS_PROPS_IFACE = "org.freedesktop.DBus.Properties" - -mountCount = {} - -MIN_RAM = _isys.MIN_RAM -MIN_GUI_RAM = _isys.MIN_GUI_RAM -URL_INSTALL_EXTRA_RAM = _isys.URL_INSTALL_EXTRA_RAM -EARLY_SWAP_RAM = _isys.EARLY_SWAP_RAM - -## Get the amount of free space available under a directory path. -# @param path The directory path to check. -# @return The amount of free space available, in -def pathSpaceAvailable(path): - return _isys.devSpaceFree(path) - -## Set up an already existing device node to be used as a loopback device. -# @param device The full path to a device node to set up as a loopback device. -# @param file The file to mount as loopback on device. -# @param readOnly Should this loopback device be used read-only? -def losetup(device, file, readOnly = 0): - # FIXME: implement this as a storage.devices.Device subclass - if readOnly: - mode = os.O_RDONLY - else: - mode = os.O_RDWR - targ = os.open(file, mode) - loop = os.open(device, mode) - try: - _isys.losetup(loop, targ, file) - finally: - os.close(loop) - os.close(targ) - -def lochangefd(device, file): - # FIXME: implement this as a storage.devices.Device subclass - loop = os.open(device, os.O_RDONLY) - targ = os.open(file, os.O_RDONLY) - try: - _isys.lochangefd(loop, targ) - finally: - os.close(loop) - os.close(targ) - -## Disable a previously setup loopback device. -# @param device The full path to an existing loopback device node. -def unlosetup(device): - # FIXME: implement this as a storage.devices.Device subclass - loop = os.open(device, os.O_RDONLY) - try: - _isys.unlosetup(loop) - finally: - os.close(loop) - -## Mount a filesystem, similar to the mount system call. -# @param device The device to mount. If bindMount is True, this should be an -# already mounted directory. Otherwise, it should be a device -# name. -# @param location The path to mount device on. -# @param fstype The filesystem type on device. This can be disk filesystems -# such as vfat or ext3, or pseudo filesystems such as proc or -# selinuxfs. -# @param readOnly Should this filesystem be mounted readonly? -# @param bindMount Is this a bind mount? (see the mount(8) man page) -# @param remount Are we mounting an already mounted filesystem? -# @return The return value from the mount system call. -def mount(device, location, fstype = "ext2", readOnly = False, - bindMount = False, remount = False, options = None): - flags = None - location = os.path.normpath(location) - if not options: - opts = ["defaults"] - else: - opts = options.split(",") - - # We don't need to create device nodes for devices that start with '/' - # (like '/usbdevfs') and also some special fake devices like 'proc'. - # First try to make a device node and if that fails, assume we can - # mount without making a device node. If that still fails, the caller - # will have to deal with the exception. - # We note whether or not we created a node so we can clean up later. - - if mountCount.has_key(location) and mountCount[location] > 0: - mountCount[location] = mountCount[location] + 1 - return - - if readOnly or bindMount or remount: - if readOnly: - opts.append("ro") - if bindMount: - opts.append("bind") - if remount: - opts.append("remount") - - flags = ",".join(opts) - - log.debug("isys.py:mount()- going to mount %s on %s as %s with options %s" %(device, location, fstype, flags)) - rc = _isys.mount(fstype, device, location, flags) - - if not rc: - mountCount[location] = 1 - - return rc - -## Unmount a filesystem, similar to the umount system call. -# @param what The directory to be unmounted. This does not need to be the -# absolute path. -# @param removeDir Should the mount point be removed after being unmounted? -# @return The return value from the umount system call. -def umount(what, removeDir = True): - what = os.path.normpath(what) - - if not os.path.isdir(what): - raise ValueError, "isys.umount() can only umount by mount point" - - if mountCount.has_key(what) and mountCount[what] > 1: - mountCount[what] = mountCount[what] - 1 - return - - log.debug("isys.py:umount()- going to unmount %s, removeDir = %s" % (what, removeDir)) - rc = _isys.umount(what) - - if removeDir and os.path.isdir(what): - try: - os.rmdir(what) - except: - pass - - if not rc and mountCount.has_key(what): - del mountCount[what] - - return rc - -## Disable swap. -# @param path The full path of the swap device to disable. -def swapoff (path): - return _isys.swapoff (path) - -## Enable swap. -# @param path The full path of the swap device to enable. -def swapon (path): - return _isys.swapon (path) - -## Load a keyboard layout for text mode installs. -# @param keymap The keyboard layout to load. This must be one of the values -# from rhpl.KeyboardModels. -def loadKeymap(keymap): - return _isys.loadKeymap (keymap) - -def resetResolv(): - return _isys.resetresolv() - -def readFSUuid(device): - if not os.path.exists(device): - device = "/dev/%s" % device - - label = _isys.getblkid(device, "UUID") - return label - -def readFSLabel(device): - if not os.path.exists(device): - device = "/dev/%s" % device - - label = _isys.getblkid(device, "LABEL") - return label - -def readFSType(device): - if not os.path.exists(device): - device = "/dev/%s" % device - - fstype = _isys.getblkid(device, "TYPE") - if fstype is None: - # FIXME: libblkid doesn't show physical volumes as having a filesystem - # so let's sniff for that.(#409321) - try: - fd = os.open(device, os.O_RDONLY) - buf = os.read(fd, 2048) - except: - return fstype - finally: - try: - os.close(fd) - except: - pass - - if buf.startswith("HM"): - return "physical volume (LVM)" - for sec in range(0, 4): - off = (sec * 512) + 24 - if len(buf) < off: - continue - if buf[off:].startswith("LVM2"): - return "physical volume (LVM)" - elif fstype == "lvm2pv": - return "physical volume (LVM)" - return fstype - -def ext2IsDirty(device): - label = _isys.e2dirty(device) - return label - -def ext2HasJournal(device): - hasjournal = _isys.e2hasjournal(device) - return hasjournal - -def modulesWithPaths(): - mods = [] - for modline in open("/proc/modules", "r"): - modName = modline.split(" ", 1)[0] - modInfo = iutil.execWithCapture("modinfo", - ["-F", "filename", modName]).splitlines() - modPaths = [ line.strip() for line in modInfo if line!="" ] - mods.extend(modPaths) - return mods - -def driveUsesModule(device, modules): - """Returns true if a drive is using a prticular module. Only works - for SCSI devices right now.""" - - if not isinstance(modules, ().__class__) and not \ - isinstance(modules, [].__class__): - modules = [modules] - - if device[:2] == "hd": - return False - rc = False - if os.access("/tmp/scsidisks", os.R_OK): - sdlist=open("/tmp/scsidisks", "r") - sdlines = sdlist.readlines() - sdlist.close() - for l in sdlines: - try: - # each line has format of: <device> <module> - (sddev, sdmod) = string.split(l) - - if sddev == device: - if sdmod in modules: - rc = True - break - except: - pass - return rc - -def vtActivate (num): - if iutil.isS390(): - return - _isys.vtActivate (num) - -def isPseudoTTY (fd): - return _isys.isPseudoTTY (fd) - -## Flush filesystem buffers. -def sync (): - return _isys.sync () - -## Determine if a file is an ISO image or not. -# @param file The full path to a file to check. -# @return True if ISO image, False otherwise. -def isIsoImage(file): - return _isys.isisoimage(file) - -# Return number of network devices -def getNetworkDeviceCount(): - bus = dbus.SystemBus() - nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH) - devlist = nm.get_dbus_method("GetDevices")() - return len(devlist) - -# Get a D-Bus interface for the specified device's (e.g., eth0) properties. -# If dev=None, return a hash of the form 'hash[dev] = props_iface' that -# contains all device properties for all interfaces that NetworkManager knows -# about. -def getDeviceProperties(dev=None): - bus = dbus.SystemBus() - nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH) - devlist = nm.get_dbus_method("GetDevices")() - all = {} - - for path in devlist: - device = bus.get_object(NM_SERVICE, path) - device_props_iface = dbus.Interface(device, DBUS_PROPS_IFACE) - - device_interface = str(device_props_iface.Get(NM_MANAGER_IFACE, "Interface")) - - if dev is None: - all[device_interface] = device_props_iface - elif device_interface == dev: - return device_props_iface - - if dev is None: - return all - else: - return None - -# Return true if method is currently 'dhcp' for the specified device. -def isDeviceDHCP(dev=None): - if dev is None: - return False - - bus = dbus.SystemBus() - nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH) - nm_props_iface = dbus.Interface(nm, DBUS_PROPS_IFACE) - active_connections = nm_props_iface.Get(NM_MANAGER_IFACE, "ActiveConnections") - - for path in active_connections: - active = bus.get_object(NM_SERVICE, path) - active_props_iface = dbus.Interface(active, DBUS_PROPS_IFACE) - - active_service_name = active_props_iface.Get(NM_ACTIVE_CONNECTION_IFACE, "ServiceName") - active_path = active_props_iface.Get(NM_ACTIVE_CONNECTION_IFACE, "Connection") - active_devices = active_props_iface.Get(NM_ACTIVE_CONNECTION_IFACE, "Devices") - - device = bus.get_object(NM_SERVICE, active_devices[0]) - device_props_iface = dbus.Interface(device, DBUS_PROPS_IFACE) - iface = device_props_iface.Get(NM_DEVICE_IFACE, "Interface") - - if iface != dev: - continue - - connection = bus.get_object(active_service_name, active_path) - connection_iface = dbus.Interface(connection, NM_CONNECTION_IFACE) - settings = connection_iface.GetSettings() - - ip4_setting = settings.get('ipv4') - if not ip4_setting or not ip4_setting['method'] or ip4_setting['method'] == 'auto': - return True - - return False - -# Get the MAC address for a network device. -def getMacAddress(dev): - if dev == '' or dev is None: - return False - - device_props_iface = getDeviceProperties(dev=dev) - if device_props_iface is None: - return None - - device_macaddr = None - try: - device_macaddr = device_props_iface.Get(NM_MANAGER_IFACE, "HwAddress").upper() - except dbus.exceptions.DBusException as e: - if e.get_dbus_name() != 'org.freedesktop.DBus.Error.InvalidArgs': - raise - return device_macaddr - -# Get a description string for a network device (e.g., eth0) -def getNetDevDesc(dev): - from baseudev import udev_get_device - desc = "Network Interface" - - if dev == '' or dev is None: - return desc - - bus = dbus.SystemBus() - nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH) - devlist = nm.get_dbus_method("GetDevices")() - - for path in devlist: - device = bus.get_object(NM_SERVICE, path) - device_iface = dbus.Interface(device, DBUS_PROPS_IFACE) - device_props = device_iface.get_dbus_method("GetAll")(NM_DEVICE_IFACE) - - if dev == device_props['Interface']: - # This is the sysfs path (for now). - udev_path = device_props['Udi'] - dev = udev_get_device(udev_path[4:]) - - if dev is None: - log.debug("weird, we have a None dev with path %s" % path) - elif dev.has_key("ID_VENDOR_ENC") and dev.has_key("ID_MODEL_ENC"): - desc = "%s %s" % (dev["ID_VENDOR_ENC"], dev["ID_MODEL_ENC"]) - elif dev.has_key("ID_VENDOR_FROM_DATABASE") and dev.has_key("ID_MODEL_FROM_DATABASE"): - desc = "%s %s" % (dev["ID_VENDOR_FROM_DATABASE"], dev["ID_MODEL_FROM_DATABASE"]) - - return desc - - return desc - -# Determine if a network device is a wireless device. -def isWireless(dev): - if dev == '' or dev is None: - return False - - device_props_iface = getDeviceProperties(dev=dev) - if device_props_iface is None: - return None - - device_type = int(device_props_iface.Get(NM_MANAGER_IFACE, "DeviceType")) - - # from include/NetworkManager.h in the NM source code - # 0 == NM_DEVICE_TYPE_UNKNOWN - # 1 == NM_DEVICE_TYPE_ETHERNET - # 2 == NM_DEVICE_TYPE_WIFI - # 3 == NM_DEVICE_TYPE_GSM - # 4 == NM_DEVICE_TYPE_CDMA - if device_type == 2: - return True - else: - return False - -# Get the IP address for a network device. -def getIPAddress(dev): - if dev == '' or dev is None: - return None - - device_props_iface = getDeviceProperties(dev=dev) - if device_props_iface is None: - return None - - # XXX: add support for IPv6 addresses when NM can do that - device_ip4addr = device_props_iface.Get(NM_MANAGER_IFACE, "Ip4Address") - - try: - tmp = struct.pack('I', device_ip4addr) - address = socket.inet_ntop(socket.AF_INET, tmp) - except ValueError, e: - return None - - return address - -## Get the correct context for a file from loaded policy. -# @param fn The filename to query. -def matchPathContext(fn): - con = None - try: - con = selinux.matchpathcon(os.path.normpath(fn), 0)[1] - except OSError as e: - log.info("failed to get default SELinux context for %s: %s" % (fn, e)) - return con - -## Set the SELinux file context of a file -# @param fn The filename to fix. -# @param con The context to use. -# @param instroot An optional root filesystem to look under for fn. -def setFileContext(fn, con, instroot = '/'): - full_path = os.path.normpath("%s/%s" % (instroot, fn)) - rc = False - if con is not None and os.access(full_path, os.F_OK): - try: - rc = (selinux.lsetfilecon(full_path, con) == 0) - except OSError as e: - log.info("failed to set SELinux context for %s: %s" % (full_path, e)) - return rc - -## Restore the SELinux file context of a file to its default. -# @param fn The filename to fix. -# @param instroot An optional root filesystem to look under for fn. -def resetFileContext(fn, instroot = '/'): - con = matchPathContext(fn) - if con: - if setFileContext(fn, con, instroot): - return con - return None - -def prefix2netmask(prefix): - return _isys.prefix2netmask(prefix) - -def netmask2prefix (netmask): - prefix = 0 - - while prefix < 33: - if (prefix2netmask(prefix) == netmask): - return prefix - - prefix += 1 - - return prefix - -isPAE = None -def isPaeAvailable(): - global isPAE - if isPAE is not None: - return isPAE - - isPAE = False - if not iutil.isX86(): - return isPAE - - f = open("/proc/cpuinfo", "r") - lines = f.readlines() - f.close() - - for line in lines: - if line.startswith("flags") and line.find("pae") != -1: - isPAE = True - break - - return isPAE - -def getLinkStatus(dev): - return _isys.getLinkStatus(dev) - -def getAnacondaVersion(): - return _isys.getAnacondaVersion() - -auditDaemon = _isys.auditdaemon - -handleSegv = _isys.handleSegv - -printObject = _isys.printObject -bind_textdomain_codeset = _isys.bind_textdomain_codeset -isVioConsole = _isys.isVioConsole -initLog = _isys.initLog diff --git a/pyanaconda/isys/auditd.c b/pyanaconda/isys/auditd.c deleted file mode 100644 index 2ca6d04..0000000 --- a/pyanaconda/isys/auditd.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * auditd.c: This is a simple audit daemon that throws all messages away. - * - * Copyright (C) 2006 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Author(s): Peter Jones <pjones@xxxxxxxxxx> - */ - -#define _GNU_SOURCE 1 - -#include <sys/types.h> -#include <sys/syscall.h> -#include <sys/poll.h> -#include <unistd.h> -#include <fcntl.h> -#include <signal.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> - -#include <libaudit.h> - -#include "auditd.h" - -#ifdef USESELINUX -static int done; - -static void sig_done(int sig) -{ - done = 1; -} - -static void do_auditd(int fd) { - struct audit_reply rep; - sigset_t sigs; - struct sigaction sa; - struct pollfd pds = { - .events = POLLIN, - .revents = 0, - .fd = fd, - }; - - if (audit_set_pid(fd, getpid(), WAIT_YES) < 0) - return; - - if (audit_set_enabled(fd, 1) < 0) - return; - - memset(&sa, '\0', sizeof (sa)); - sa.sa_handler = sig_done; - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - sigaction(SIGHUP, &sa, NULL); - - sigfillset(&sigs); - sigdelset(&sigs, SIGTERM); - sigdelset(&sigs, SIGINT); - sigdelset(&sigs, SIGHUP); - - while (1) { - int retval; - - memset(&rep, 0, sizeof(rep)); - - do { - retval = ppoll(&pds, 1, NULL, &sigs); - } while (retval == -1 && errno == EINTR && !done); - - if (done) - break; - - if (audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0) > 0) { - /* we don't actually want to do anything here. */ - ; - } - } - return; -} -#endif /* USESELINUX */ - -int audit_daemonize(void) { -#ifdef USESELINUX - int fd; - pid_t child; - int i; - if ((child = fork()) > 0) - return 0; - -#ifndef STANDALONE - for (i = 0; i < getdtablesize(); i++) - close(i); - signal(SIGTTOU, SIG_IGN); - signal(SIGTTIN, SIG_IGN); - signal(SIGTSTP, SIG_IGN); -#endif /* !defined(STANDALONE) */ - - if ((fd = open("/proc/self/oom_adj", O_RDWR)) >= 0) { - i = write(fd, "-17", 3); - close(fd); - } - fd = audit_open(); - do_auditd(fd); - audit_close(fd); - -#ifndef STANDALONE - exit(0); -#endif /* !defined(STANDALONE) */ - -#endif /* USESELINUX */ - return 0; -} - -#ifdef STANDALONE -int main(void) { - return audit_daemonize(); -} -#endif /* STANDALONE */ - -/* - * vim:ts=8:sw=4:sts=4:et - */ diff --git a/pyanaconda/isys/auditd.h b/pyanaconda/isys/auditd.h deleted file mode 100644 index 55ec5ce..0000000 --- a/pyanaconda/isys/auditd.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * auditd.h: This is a simple audit daemon that throws all messages away. - * - * Copyright (C) 2006 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Author(s): Peter Jones <pjones@xxxxxxxxxx> - */ - -#ifndef ISYS_AUDIT_H -#define ISYS_AUDIT_H 1 - -extern int audit_daemonize(void); - -#endif /* ISYS_AUDIT_H */ -/* - * vim:ts=8:sw=4:sts=4:et - */ diff --git a/pyanaconda/isys/cpio.c b/pyanaconda/isys/cpio.c deleted file mode 100644 index fd83605..0000000 --- a/pyanaconda/isys/cpio.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * cpio.c - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include "cpio.h" - -int installCpioFile(gzFile fd, char * cpioName, char * outName, int inWin) { - struct cpioFileMapping map; - int rc; - const char * failedFile; - - if (outName) { - map.archivePath = cpioName; - map.fsPath = outName; - map.mapFlags = CPIO_MAP_PATH; - } - - rc = myCpioInstallArchive(fd, outName ? &map : NULL, 1, NULL, NULL, - &failedFile); - - if (rc || access(outName, R_OK)) { - return -1; - } - - return 0; -} diff --git a/pyanaconda/isys/cpio.h b/pyanaconda/isys/cpio.h deleted file mode 100644 index 4cbb7c0..0000000 --- a/pyanaconda/isys/cpio.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * cpio.h - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef H_CPIO -#define H_CPIO - -#include <sys/types.h> - -#include "stubs.h" - -/* Note the CPIO_CHECK_ERRNO bit is set only if errno is valid. These have to - be positive numbers or this setting the high bit stuff is a bad idea. */ -#define CPIOERR_CHECK_ERRNO 0x80000000 - -#define CPIOERR_BAD_MAGIC (2 ) -#define CPIOERR_BAD_HEADER (3 ) -#define CPIOERR_OPEN_FAILED (4 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_CHMOD_FAILED (5 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_CHOWN_FAILED (6 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_WRITE_FAILED (7 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_UTIME_FAILED (8 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_UNLINK_FAILED (9 | CPIOERR_CHECK_ERRNO) - -#define CPIOERR_SYMLINK_FAILED (11 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_STAT_FAILED (12 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_MKDIR_FAILED (13 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_MKNOD_FAILED (14 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_MKFIFO_FAILED (15 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_LINK_FAILED (16 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_READLINK_FAILED (17 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_READ_FAILED (18 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_COPY_FAILED (19 | CPIOERR_CHECK_ERRNO) -#define CPIOERR_INTERNAL (20 ) -#define CPIOERR_HDR_SIZE (21 ) -#define CPIOERR_UNKNOWN_FILETYPE (22 ) - - -/* Don't think this behaves just like standard cpio. It's pretty close, but - it has some behaviors which are more to RPM's liking. I tried to document - them inline in cpio.c, but I may have missed some. */ - -#define CPIO_MAP_PATH (1 << 0) -#define CPIO_MAP_MODE (1 << 1) -#define CPIO_MAP_UID (1 << 2) -#define CPIO_MAP_GID (1 << 3) -#define CPIO_FOLLOW_SYMLINKS (1 << 4) /* only for building */ - -struct cpioFileMapping { - char * archivePath; - char * fsPath; - mode_t finalMode; - uid_t finalUid; - gid_t finalGid; - int mapFlags; -}; - -/* on cpio building, only "file" is filled in */ -struct cpioCallbackInfo { - char * file; - long fileSize; /* total file size */ - long fileComplete; /* amount of file unpacked */ - long bytesProcessed; /* bytes in archive read */ -}; - -typedef void (*cpioCallback)(struct cpioCallbackInfo * filespec, void * data); - -/* If no mappings are passed, this installs everything! If one is passed - it should be sorted according to cpioFileMapCmp() and only files included - in the map are installed. Files are installed relative to the current - directory unless a mapping is given which specifies an absolute - directory. The mode mapping is only used for the permission bits, not - for the file type. The owner/group mappings are ignored for the nonroot - user. If *failedFile is non-NULL on return, it should be free()d. */ -int myCpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings, - int numMappings, cpioCallback cb, void * cbData, - const char ** failedFile); -int myCpioFilterArchive(gzFile inStream, gzFile outStream, char ** pattern); - -/* This is designed to be qsort/bsearch compatible */ -int myCpioFileMapCmp(const void * a, const void * b); - -const char *myCpioStrerror(int rc); - -int installCpioFile(gzFile fd, char * cpioName, char * outName, int inWin); - -#endif diff --git a/pyanaconda/isys/devices.c b/pyanaconda/isys/devices.c deleted file mode 100644 index 53130d1..0000000 --- a/pyanaconda/isys/devices.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * devices.c - various hardware probing functionality - * - * Copyright (C) 2007 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Author(s): Bill Nottingham <notting@xxxxxxxxxx> - */ - -#include <ctype.h> -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <limits.h> - -#include "devices.h" - -/* for 'disks', to filter out weird stuff */ -#define MINIMUM_INTERESTING_SIZE 32*1024 /* 32MB */ - -/* from genhd.h, kernel side */ -#define GENHD_FL_REMOVABLE 1 -#define GENHD_FL_DRIVERFS 2 -#define GENHD_FL_MEDIA_CHANGE_NOTIFY 4 -#define GENHD_FL_CD 8 -#define GENHD_FL_UP 16 -#define GENHD_FL_SUPPRESS_PARTITION_INFO 32 -#define GENHD_FL_FAIL 64 - - -struct device **getDevices(enum deviceType type) { - struct device **ret = NULL; - struct device *new; - int numdevices = 0; - - if (type & (DEVICE_DISK | DEVICE_CDROM)) { - DIR *dir; - struct dirent *ent; - - dir = opendir("/sys/block"); - - if (!dir) goto storagedone; - - while ((ent = readdir(dir))) { - char path[64]; - char buf[64]; - int fd, caps, devtype; - - snprintf(path, 64, "/sys/block/%s/capability", ent->d_name); - fd = open(path, O_RDONLY); - if (fd == -1) - continue; - if (read(fd, buf, 63) <= 0) { - close(fd); - continue; - } - - close(fd); - errno = 0; - caps = strtol(buf, NULL, 16); - - if ((errno == ERANGE && (caps == LONG_MIN || caps == LONG_MAX)) || - (errno != 0 && caps == 0)) { - return NULL; - } - - if (caps & GENHD_FL_CD) - devtype = DEVICE_CDROM; - else - devtype = DEVICE_DISK; - if (!(devtype & type)) - continue; - - if (devtype == DEVICE_DISK && !(caps & GENHD_FL_REMOVABLE)) { - int size; - - snprintf(path, 64, "/sys/block/%s/size", ent->d_name); - fd = open(path, O_RDONLY); - - if (fd == -1) - continue; - if (read(fd, buf, 63) <= 0) { - close(fd); - continue; - } - - close(fd); - errno = 0; - size = strtol(buf, NULL, 10); - - if ((errno == ERANGE && (size == LONG_MIN || - size == LONG_MAX)) || - (errno != 0 && size == 0)) { - return NULL; - } - - if (size < MINIMUM_INTERESTING_SIZE) - continue; - } - - new = calloc(1, sizeof(struct device)); - new->device = strdup(ent->d_name); - /* FIXME */ - if (asprintf(&new->description, "Storage device %s", - new->device) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } - new->type = devtype; - if (caps & GENHD_FL_REMOVABLE) { - new->priv.removable = 1; - } - ret = realloc(ret, (numdevices+2) * sizeof(struct device)); - ret[numdevices] = new; - ret[numdevices+1] = NULL; - numdevices++; - } - - closedir(dir); - } -storagedone: - - if (type & DEVICE_NETWORK) { - DIR *dir; - struct dirent *ent; - - dir = opendir("/sys/class/net"); - - if (!dir) goto netdone; - - while ((ent = readdir(dir))) { - char path[64]; - int fd, type; - char buf[64]; - - snprintf(path, 64, "/sys/class/net/%s/type", ent->d_name); - fd = open(path, O_RDONLY); - if (fd == -1) - continue; - if (read(fd, buf, 63) <= 0) { - close(fd); - continue; - } - - close(fd); - errno = 0; - type = strtol(buf, NULL, 10); - - if ((errno == ERANGE && (type == LONG_MIN || type == LONG_MAX)) || - (errno != 0 && type == 0)) { - return NULL; - } - - if (type != 1) - continue; - - new = calloc(1, sizeof(struct device)); - new->device = strdup(ent->d_name); - /* FIXME */ - snprintf(path, 64, "/sys/class/net/%s/address", ent->d_name); - fd = open(path, O_RDONLY); - if (fd != -1) { - memset(buf, '\0', 64); - if (read(fd, buf, 63) > 0) { - int i; - for (i = (strlen(buf)-1); isspace(buf[i]); i--) - buf[i] = '\0'; - new->priv.hwaddr = strdup(buf); - } - } - - if (new->priv.hwaddr) { - if (asprintf(&new->description, "Ethernet device %s - %s", - new->device, new->priv.hwaddr) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } - } else { - if (asprintf(&new->description, "Ethernet device %s", - new->device) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } - } - - ret = realloc(ret, (numdevices+2) * sizeof(struct device)); - ret[numdevices] = new; - ret[numdevices+1] = NULL; - numdevices++; - } - - closedir(dir); - } -netdone: - return ret; -} - diff --git a/pyanaconda/isys/devices.h b/pyanaconda/isys/devices.h deleted file mode 100644 index 9428a77..0000000 --- a/pyanaconda/isys/devices.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * devices.h - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef DEVICES_H -#define DEVICES_H - -enum deviceType { - DEVICE_ANY = ~0, - DEVICE_NETWORK = (1 << 0), - DEVICE_DISK = (1 << 1), - DEVICE_CDROM = (1 << 2) -}; - -struct device { - char *device; - char *description; - enum deviceType type; - union { - char *hwaddr; - int removable; - } priv; -}; - -struct device **getDevices(enum deviceType type); - -#endif diff --git a/pyanaconda/isys/eddsupport.c b/pyanaconda/isys/eddsupport.c deleted file mode 100644 index c50278e..0000000 --- a/pyanaconda/isys/eddsupport.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * eddsupport.c - handling of mapping disk drives in Linux to disk drives - * according to the BIOS using the edd kernel module - * - * Copyright (C) 2004 Dell, Inc. All rights reserved. - * Copyright (C) 2004 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Author(s): Rezwanul_Kabir@xxxxxxxx - * Jeremy Katz <katzj@xxxxxxxxxx> - */ - -#include <ctype.h> -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/stat.h> -#include <sys/reboot.h> -#include <sys/types.h> -#include <linux/types.h> - - -#include "eddsupport.h" -#include "devices.h" -#include "isys.h" - -#define EDD_DIR "/sys/firmware/edd" -#define SIG_FILE "mbr_signature" -#define MBRSIG_OFFSET 0x1b8 - -#define HASH_TABLE_SIZE 17 - - -struct diskMapEntry{ - uint32_t key; - char *diskname; - struct diskMapEntry *next; -}; - -struct diskMapTable { - struct diskMapEntry **table; - int tableSize; -}; - -static struct diskMapTable *mbrSigToName = NULL; -static int diskHashInit = 0; - - - -static struct diskMapTable* initializeHashTable(int); -static int insertHashItem(struct diskMapTable *, struct diskMapEntry *); -static struct diskMapEntry* lookupHashItem(struct diskMapTable *, uint32_t); -static int addToHashTable(struct diskMapTable *, uint32_t , char *); -static struct device ** createDiskList(); -static int mapBiosDisks(struct device ** , const char *); -static int readDiskSig(char *, uint32_t *); -static int readMbrSig(char *, uint32_t *); - -/* This is the top level function that creates a disk list present in the - * system, checks to see if unique signatures exist on the disks at offset - * 0x1b8. If a unique signature exists then it will map BIOS disks to their - * corresponding hd/sd device names. Otherwise, we'll avoid mapping drives. - */ - -int probeBiosDisks() { - struct device ** devices = NULL; - - devices = createDiskList(); - if(!devices){ -#ifdef STANDALONE - fprintf(stderr, "No disks!\n"); -#endif - return -1; - } - - if(!mapBiosDisks(devices, EDD_DIR)){ -#ifdef STANDALONE - fprintf(stderr, "WARNING: couldn't map BIOS disks\n"); -#endif - return -1; - } - return 0; -} - - -static struct device ** createDiskList(){ - return getDevices (DEVICE_DISK); -} - -static int readDiskSig(char *device, uint32_t *disksig) { - int fd, rc; - char devnodeName[64]; - - snprintf(devnodeName, sizeof(devnodeName), "/dev/%s", device); - fd = open(devnodeName, O_RDONLY); - if (fd < 0) { -#ifdef STANDALONE - fprintf(stderr, "Error opening device %s: %s\n ", device, - strerror(errno)); -#endif - return -errno; - } - - rc = lseek(fd, MBRSIG_OFFSET, SEEK_SET); - if (rc < 0){ - close(fd); - -#ifdef STANDALONE - fprintf(stderr, "Error seeking to MBRSIG_OFFSET in %s: %s\n", - device, strerror(errno)); -#endif - return -1; - } - - rc = read(fd, disksig, sizeof(uint32_t)); - if (rc < sizeof(uint32_t)) { - close(fd); - -#ifdef STANDALONE - fprintf(stderr, "Failed to read signature from %s\n", device); -#endif - return -1; - } - - close(fd); - return 0; -} - -static int mapBiosDisks(struct device** devices,const char *path) { - DIR *dirHandle; - struct dirent *entry; - char * sigFileName; - uint32_t mbrSig, biosNum, currentSig; - struct device **currentDev, **foundDisk; - int i, rc, ret, dm_nr, highest_dm; - - dirHandle = opendir(path); - if(!dirHandle){ -#ifdef STANDALONE - fprintf(stderr, "Failed to open directory %s: %s\n", path, - strerror(errno)); -#endif - return 0; - } - - mbrSigToName = initializeHashTable(HASH_TABLE_SIZE); - if(!mbrSigToName){ -#ifdef STANDALONE - fprintf(stderr, "Error initializing mbrSigToName table\n"); -#endif - closedir(dirHandle); - return 0; - } - - while ((entry = readdir(dirHandle)) != NULL) { - if(!strncmp(entry->d_name,".",1) || !strncmp(entry->d_name,"..",2)) { - continue; - } - ret = sscanf((entry->d_name+9), "%x", &biosNum); - - sigFileName = malloc(strlen(path) + strlen(entry->d_name) + 20); - sprintf(sigFileName, "%s/%s/%s", path, entry->d_name, SIG_FILE); - if (readMbrSig(sigFileName, &mbrSig) == 0) { - for (currentDev = devices, i = 0, foundDisk=NULL, highest_dm=-1; - (*currentDev) != NULL; - currentDev++) { - if (!(*currentDev)->device) - continue; - - if ((rc=readDiskSig((*currentDev)->device, ¤tSig)) < 0) { - if (rc == -ENOMEDIUM || rc == -ENXIO) - continue; - closedir(dirHandle); - return 0; - } - - if (mbrSig == currentSig) { - /* When we have a fakeraid setup we will find multiple hits - a number for the raw disks (1 when striping, 2 when - mirroring, more with raid on raid like raid 01 or 10) - and a number for the dm devices (normally only one dm - device will match, but more with raid on raid). - Since with raid on raid the last dm device created - will be the top layer raid, we want the highest matching - dm device. */ - if (!strncmp((*currentDev)->device, "dm-", 3) && - sscanf((*currentDev)->device+3, "%d", &dm_nr) == 1) { - if (dm_nr > highest_dm) { - highest_dm = dm_nr; - foundDisk=currentDev; - i = 1; - } - } else if (!foundDisk || - strncmp((*foundDisk)->device, "dm-", 3)) { - foundDisk=currentDev; - i++; - } - } - } - - if (i==1) { - if(!addToHashTable(mbrSigToName, (uint32_t)biosNum, - (*foundDisk)->device)) { - closedir(dirHandle); - return 0; - } - } - } - } - closedir(dirHandle); - return 1; -} - - -static int readMbrSig(char *filename, uint32_t *int_sig){ - FILE* fh; - - fh = fopen(filename,"r"); - if(fh == NULL) { -#ifdef STANDALONE - fprintf(stderr, "Error opening mbr_signature file %s: %s\n", filename, - strerror(errno)); -#endif - return -1; - } - fseek(fh, 0, SEEK_SET); - if (fscanf(fh, "%x", int_sig) != 1) { -#ifdef STANDALONE - fprintf(stderr, "Error reading %s\n", filename); -#endif - fclose(fh); - return -1; - } - - fclose(fh); - return 0; -} - - -static struct diskMapTable* initializeHashTable(int size) { - struct diskMapTable *hashTable; - - hashTable = malloc(sizeof(struct diskMapTable)); - hashTable->tableSize = size; - hashTable->table = malloc(sizeof(struct diskMapEntry *) * size); - memset(hashTable->table,0,(sizeof(struct diskMapEntry *) * size)); - return hashTable; -} - - -static int insertHashItem(struct diskMapTable *hashTable, - struct diskMapEntry *hashItem) { - int index; - - index = (hashItem->key) % (hashTable->tableSize); - - if(hashTable->table[index] == NULL){ - hashTable->table[index] = hashItem; - return index; - } else { - hashItem->next = hashTable->table[index]; - hashTable->table[index] = hashItem; - return index; - } -} - - -static struct diskMapEntry * lookupHashItem(struct diskMapTable *hashTable, - uint32_t itemKey) { - int index; - struct diskMapEntry *hashItem; - - index = itemKey % (hashTable->tableSize); - for (hashItem = hashTable->table[index]; - (hashItem != NULL) && (hashItem->key != itemKey); - hashItem = hashItem->next) { - ; - } - return hashItem; -} - - -static int addToHashTable(struct diskMapTable *hashTable, - uint32_t itemKey, char *diskName) { - int index; - struct diskMapEntry *diskSigToNameEntry; - - diskSigToNameEntry = malloc(sizeof(struct diskMapEntry)); - diskSigToNameEntry->next = NULL; - diskSigToNameEntry->key = itemKey; - diskSigToNameEntry->diskname = diskName; - - if ((index = insertHashItem(hashTable, diskSigToNameEntry)) < 0){ -#ifdef STANDALONE - fprintf(stderr, "Unable to insert item\n"); -#endif - return 0; - } else { - return 1; - } -} - - -char * getBiosDisk(char *biosStr) { - uint32_t biosNum; - struct diskMapEntry * disk; - int ret; - - if (diskHashInit == 0) { - probeBiosDisks(); - diskHashInit = 1; - } - - if (mbrSigToName == NULL) - return NULL; - - ret = sscanf(biosStr,"%x",&biosNum); - disk = lookupHashItem(mbrSigToName, biosNum); - if (disk) return disk->diskname; - - return NULL; -} diff --git a/pyanaconda/isys/eddsupport.h b/pyanaconda/isys/eddsupport.h deleted file mode 100644 index 77fc4c4..0000000 --- a/pyanaconda/isys/eddsupport.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * eddsupport.h - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef EDDSUPPORT_H -#define EDDSUPPORT_H - -int probeBiosDisks(); -char* getBiosDisk(char *); - -#endif - - diff --git a/pyanaconda/isys/ethtool.c b/pyanaconda/isys/ethtool.c deleted file mode 100644 index 871f1d4..0000000 --- a/pyanaconda/isys/ethtool.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * ethtool.c - setting of basic ethtool options - * - * Copyright (C) 2003 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Author(s): Jeremy Katz <katzj@xxxxxxxxxx> - */ - -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> - -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <net/if.h> - -#include <linux/sockios.h> -#include "ethtool.h" - -static int set_intf_up(struct ifreq ifr, int sock) { - if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { - return (-1); - } - ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); - if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) { - fprintf(stderr, "failed to bring up interface %s: %s", ifr.ifr_name, - strerror(errno)); - return -1; - } - return (0); -} - -int setEthtoolSettings(char * dev, ethtool_speed speed, - ethtool_duplex duplex) { - int sock, err; - struct ethtool_cmd ecmd; - struct ifreq ifr; - - if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("Unable to create socket"); - return -1; - } - - /* Setup our control structures. */ - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, dev); - - if (set_intf_up(ifr, sock) == -1) { - fprintf(stderr, "unable to bring up interface %s: %s", dev, - strerror(errno)); - return -1; - } - - ecmd.cmd = ETHTOOL_GSET; - ifr.ifr_data = (caddr_t)&ecmd; - err = ioctl(sock, SIOCETHTOOL, &ifr); - if (err < 0) { - perror("Unable to get settings via ethtool. Not setting"); - return -1; - } - - if (speed != ETHTOOL_SPEED_UNSPEC) - ecmd.speed = speed; - if (duplex != ETHTOOL_DUPLEX_UNSPEC) - ecmd.duplex = duplex; - if ((duplex != ETHTOOL_DUPLEX_UNSPEC) || (speed != ETHTOOL_SPEED_UNSPEC)) - ecmd.autoneg = AUTONEG_DISABLE; - - ecmd.cmd = ETHTOOL_SSET; - ifr.ifr_data = (caddr_t)&ecmd; - err = ioctl(sock, SIOCETHTOOL, &ifr); - if (err < 0) { - // perror("Unable to set settings via ethtool. Not setting"); - return -1; - } - - return 0; -} - -int identifyNIC(char *iface, int seconds) { - int sock; - struct ethtool_value edata; - struct ifreq ifr; - - if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("Unable to create socket"); - return -1; - } - - memset(&ifr, 0, sizeof(ifr)); - memset(&edata, 0, sizeof(edata)); - - strcpy(ifr.ifr_name, iface); - edata.cmd = ETHTOOL_PHYS_ID; - edata.data = seconds; - ifr.ifr_data = (caddr_t) &edata; - - if (ioctl(sock, SIOCETHTOOL, &ifr) < 0) { - perror("Unable to identify NIC"); - } - - return 0; -} diff --git a/pyanaconda/isys/ethtool.h b/pyanaconda/isys/ethtool.h deleted file mode 100644 index 57b4ffc..0000000 --- a/pyanaconda/isys/ethtool.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * net.h - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef ISYSNET_H -#define ISYSNET_H - -#include <linux/types.h> -#include <linux/ethtool.h> - -/* returns 1 for link, 0 for no link, -1 for unknown */ -int get_link_status(char *ifname); - -typedef enum ethtool_speed_t { ETHTOOL_SPEED_UNSPEC = -1, - ETHTOOL_SPEED_10 = SPEED_10, - ETHTOOL_SPEED_100 = SPEED_100, - ETHTOOL_SPEED_1000 = SPEED_1000 } ethtool_speed; -typedef enum ethtool_duplex_t { ETHTOOL_DUPLEX_UNSPEC = -1, - ETHTOOL_DUPLEX_HALF = DUPLEX_HALF, - ETHTOOL_DUPLEX_FULL = DUPLEX_FULL } ethtool_duplex; - -/* set ethtool settings */ -int setEthtoolSettings(char * dev, ethtool_speed speed, ethtool_duplex duplex); -int identifyNIC(char *iface, int seconds); - -#endif diff --git a/pyanaconda/isys/iface.c b/pyanaconda/isys/iface.c deleted file mode 100644 index 5897286..0000000 --- a/pyanaconda/isys/iface.c +++ /dev/null @@ -1,543 +0,0 @@ -/* - * iface.c - Network interface configuration API - * - * Copyright (C) 2006, 2007, 2008 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Author(s): David Cantrell <dcantrell@xxxxxxxxxx> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/utsname.h> -#include <arpa/inet.h> -#include <dirent.h> -#include <fcntl.h> -#include <netdb.h> -#include <signal.h> -#include <netinet/in.h> - -#include <netlink/netlink.h> -#include <netlink/socket.h> -#include <netlink/route/rtnl.h> -#include <netlink/route/route.h> -#include <netlink/route/addr.h> -#include <netlink/route/link.h> - -#include <glib.h> -#include <NetworkManager.h> -#include <nm-client.h> -#include <nm-device.h> -#include <nm-ip4-config.h> -#include <nm-setting-ip4-config.h> - -#include "isys.h" -#include "iface.h" - -/* Internal-only function prototypes. */ -static struct nl_handle *_iface_get_handle(void); -static struct nl_cache *_iface_get_link_cache(struct nl_handle **); -static int _iface_have_valid_addr(void *addr, int family, int length); -static int _iface_redirect_io(char *device, int fd, int mode); - -/* - * Return a libnl handle for NETLINK_ROUTE. - */ -static struct nl_handle *_iface_get_handle(void) { - struct nl_handle *handle = NULL; - - if ((handle = nl_handle_alloc()) == NULL) { - return NULL; - } - - if (nl_connect(handle, NETLINK_ROUTE)) { - nl_handle_destroy(handle); - return NULL; - } - - return handle; -} - -/* - * Return an NETLINK_ROUTE cache. - */ -static struct nl_cache *_iface_get_link_cache(struct nl_handle **handle) { - struct nl_cache *cache = NULL; - - if ((*handle = _iface_get_handle()) == NULL) { - return NULL; - } - - if ((cache = rtnl_link_alloc_cache(*handle)) == NULL) { - nl_close(*handle); - nl_handle_destroy(*handle); - return NULL; - } - - return cache; -} - -/* - * Determine if a struct in_addr or struct in6_addr contains a valid address. - */ -static int _iface_have_valid_addr(void *addr, int family, int length) { - char buf[length+1]; - - if ((addr == NULL) || (family != AF_INET && family != AF_INET6)) { - return 0; - } - - memset(buf, '\0', sizeof(buf)); - - if (inet_ntop(family, addr, buf, length) == NULL) { - return 0; - } else { - /* check for unknown addresses */ - if (family == AF_INET) { - if (!strncmp(buf, "0.0.0.0", 7)) { - return 0; - } - } else if (family == AF_INET6) { - if (!strncmp(buf, "::", 2)) { - return 0; - } - } - } - - return 1; -} - -/* - * Redirect I/O to another device (e.g., stdout to /dev/tty5) - */ -int _iface_redirect_io(char *device, int fd, int mode) { - int io = -1; - - if ((io = open(device, mode)) == -1) { - return 1; - } - - if (close(fd) == -1) { - return 2; - } - - if (dup2(io, fd) == -1) { - return 3; - } - - if (close(io) == -1) { - return 4; - } - - return 0; -} - -/* - * Given an interface name (e.g., eth0) and address family (e.g., AF_INET), - * return the IP address in human readable format (i.e., the output from - * inet_ntop()). Return NULL for no match or error. - */ -char *iface_ip2str(char *ifname, int family) { - int i; - NMClient *client = NULL; - NMIP4Config *ip4config = NULL; - NMIP4Address *ipaddr = NULL; - NMDevice *candidate = NULL; - struct in_addr tmp_addr; - const GPtrArray *devices; - const char *iface; - char ipstr[INET_ADDRSTRLEN+1]; - - if (ifname == NULL) { - return NULL; - } - - /* DCFIXME: add IPv6 once NM gains support */ - if (family != AF_INET) { - return NULL; - } - - g_type_init(); - - client = nm_client_new(); - if (!client) { - return NULL; - } - - if (nm_client_get_state(client) != NM_STATE_CONNECTED) { - g_object_unref(client); - return NULL; - } - - devices = nm_client_get_devices(client); - for (i=0; i < devices->len; i++) { - candidate = g_ptr_array_index(devices, i); - iface = nm_device_get_iface(candidate); - - if (nm_device_get_state(candidate) != NM_DEVICE_STATE_ACTIVATED) - continue; - - if (!iface || strcmp(iface, ifname)) - continue; - - if (!(ip4config = nm_device_get_ip4_config(candidate))) - continue; - - if (!(ipaddr = nm_ip4_config_get_addresses(ip4config)->data)) - continue; - - memset(&ipstr, '\0', sizeof(ipstr)); - tmp_addr.s_addr = nm_ip4_address_get_address(ipaddr); - - if (inet_ntop(AF_INET, &tmp_addr, ipstr, INET_ADDRSTRLEN) == NULL) { - g_object_unref(client); - return NULL; - } - - g_object_unref(client); - return g_strdup(ipstr); - } - - g_object_unref(client); - return NULL; -} - -/* Given an interface's MAC address, return the name (e.g., eth0) in human - * readable format. Return NULL for no match - */ -char *iface_mac2device(char *mac) { - struct nl_handle *handle = NULL; - struct nl_cache *cache = NULL; - struct rtnl_link *link = NULL; - struct nl_addr *mac_as_nl_addr = NULL; - char *retval = NULL; - int i, n; - - if (mac == NULL) { - return NULL; - } - - if ((mac_as_nl_addr = nl_addr_parse(mac, AF_LLC)) == NULL) { - return NULL; - } - - if ((cache = _iface_get_link_cache(&handle)) == NULL) { - return NULL; - } - - n = nl_cache_nitems(cache); - for (i = 0; i <= n; i++) { - struct nl_addr *addr; - - if ((link = rtnl_link_get(cache, i)) == NULL) { - continue; - } - - addr = rtnl_link_get_addr(link); - - if (!nl_addr_cmp(mac_as_nl_addr, addr)) { - retval = strdup(rtnl_link_get_name(link)); - rtnl_link_put(link); - break; - } - - rtnl_link_put(link); - } - - nl_close(handle); - nl_handle_destroy(handle); - - return retval; -} - -/* - * Given an interface name (e.g., eth0), return the MAC address in human - * readable format (e.g., 00:11:52:12:D9:A0). Return NULL for no match. - */ -char *iface_mac2str(char *ifname) { - int buflen = 20; - char *buf = NULL; - struct nl_handle *handle = NULL; - struct nl_cache *cache = NULL; - struct rtnl_link *link = NULL; - struct nl_addr *addr = NULL; - - if (ifname == NULL) { - return NULL; - } - - if ((cache = _iface_get_link_cache(&handle)) == NULL) { - return NULL; - } - - if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) { - goto mac2str_error2; - } - - if ((addr = rtnl_link_get_addr(link)) == NULL) { - goto mac2str_error3; - } - - if ((buf = calloc(sizeof(char *), buflen)) == NULL) { - goto mac2str_error4; - } - - if ((buf = nl_addr2str(addr, buf, buflen)) != NULL) { - char *oldbuf = buf; - buf = g_ascii_strup(buf, -1); - free(oldbuf); - } - -mac2str_error4: - nl_addr_destroy(addr); -mac2str_error3: - rtnl_link_put(link); -mac2str_error2: - nl_close(handle); - nl_handle_destroy(handle); - - return buf; -} - -/* - * Convert an IPv4 CIDR prefix to a dotted-quad netmask. Return NULL on - * failure. - */ -struct in_addr *iface_prefix2netmask(int prefix) { - int mask = 0; - char *buf = NULL; - struct in_addr *ret; - - if ((buf = calloc(sizeof(char *), INET_ADDRSTRLEN + 1)) == NULL) { - return NULL; - } - - mask = htonl(~((1 << (32 - prefix)) - 1)); - - if (inet_ntop(AF_INET, (struct in_addr *) &mask, buf, - INET_ADDRSTRLEN) == NULL) { - return NULL; - } - - if ((ret = calloc(sizeof(struct in_addr), 1)) == NULL) { - return NULL; - } - - memcpy(ret, (struct in_addr *) &mask, sizeof(struct in_addr)); - return ret; -} - -/* - * Initialize a new iface_t structure to default values. - */ -void iface_init_iface_t(iface_t *iface) { - int i; - - memset(&iface->device, '\0', sizeof(iface->device)); - memset(&iface->ipaddr, 0, sizeof(iface->ipaddr)); - memset(&iface->netmask, 0, sizeof(iface->netmask)); - memset(&iface->broadcast, 0, sizeof(iface->broadcast)); - memset(&iface->ip6addr, 0, sizeof(iface->ip6addr)); - memset(&iface->gateway, 0, sizeof(iface->gateway)); - memset(&iface->gateway6, 0, sizeof(iface->gateway6)); - - for (i = 0; i < MAXNS; i++) { - iface->dns[i] = NULL; - } - - iface->macaddr = NULL; - iface->ip6prefix = 0; - iface->nextserver = NULL; - iface->bootfile = NULL; - iface->numdns = 0; - iface->hostname = NULL; - iface->domain = NULL; - iface->search = NULL; - iface->dhcptimeout = 0; - iface->vendorclass = NULL; - iface->ssid = NULL; - iface->wepkey = NULL; - iface->mtu = 0; - iface->subchannels = NULL; - iface->portname = NULL; - iface->peerid = NULL; - iface->nettype = NULL; - iface->ctcprot = NULL; - iface->layer2 = NULL; - iface->portno = NULL; - iface->flags = 0; - iface->ipv4method = IPV4_UNUSED_METHOD; - iface->ipv6method = IPV6_UNUSED_METHOD; - - return; -} - -/* - * Given a pointer to a struct in_addr, return 1 if it contains a valid - * address, 0 otherwise. - */ -int iface_have_in_addr(struct in_addr *addr) { - return _iface_have_valid_addr(addr, AF_INET, INET_ADDRSTRLEN); -} - -/* - * Given a pointer to a struct in6_addr, return 1 if it contains a valid - * address, 0 otherwise. - */ -int iface_have_in6_addr(struct in6_addr *addr6) { - return _iface_have_valid_addr(addr6, AF_INET6, INET6_ADDRSTRLEN); -} - -/* Check if NM has an active connection */ -gboolean is_nm_connected(void) { - NMState state; - NMClient *client = NULL; - - g_type_init(); - - client = nm_client_new(); - if (!client) - return FALSE; - - state = nm_client_get_state(client); - g_object_unref(client); - - if (state == NM_STATE_CONNECTED) - return TRUE; - else - return FALSE; -} - -/* Check if NM is already running */ -gboolean is_nm_running(void) { - gboolean running; - NMClient *client = NULL; - - g_type_init(); - - client = nm_client_new(); - if (!client) - return FALSE; - - running = nm_client_get_manager_running(client); - g_object_unref(client); - return running; -} - -/* - * Wait for NetworkManager to appear on the system bus - */ -int wait_for_nm(void) { - int count = 0; - - /* send message and block until a reply or error comes back */ - while (count < 45) { - if (is_nm_running()) - return 0; - - sleep(1); - count++; - } - - return 1; -} - -/* - * Start NetworkManager -- requires that you have already written out the - * control files in /etc/sysconfig for the interface. - */ -int iface_start_NetworkManager(void) { - pid_t pid; - - if (is_nm_running()) - return 0; /* already running */ - - /* Start NetworkManager */ - pid = fork(); - if (pid == 0) { - if (setpgrp() == -1) { - exit(1); - } - - if (_iface_redirect_io("/dev/null", STDIN_FILENO, O_RDONLY) || - _iface_redirect_io(OUTPUT_TERMINAL, STDOUT_FILENO, O_WRONLY) || - _iface_redirect_io(OUTPUT_TERMINAL, STDERR_FILENO, O_WRONLY)) { - exit(2); - } - - if (execl(NETWORKMANAGER, NETWORKMANAGER, - "--pid-file=/var/run/NetworkManager/NetworkManager.pid", - NULL) == -1) { - exit(3); - } - } else if (pid == -1) { - return 1; - } else { - return wait_for_nm(); - } - - return 0; -} - -/* - * Set the MTU on the specified device. - */ -int iface_set_interface_mtu(char *ifname, int mtu) { - int ret = 0; - struct nl_handle *handle = NULL; - struct nl_cache *cache = NULL; - struct rtnl_link *link = NULL; - struct rtnl_link *request = NULL; - - if (ifname == NULL) { - return -1; - } - - if (mtu <= 0) { - return -2; - } - - if ((cache = _iface_get_link_cache(&handle)) == NULL) { - return -3; - } - - if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) { - ret = -4; - goto ifacemtu_error1; - } - - request = rtnl_link_alloc(); - rtnl_link_set_mtu(request, mtu); - - if (rtnl_link_change(handle, link, request, 0)) { - ret = -5; - goto ifacemtu_error2; - } - -ifacemtu_error2: - rtnl_link_put(link); -ifacemtu_error1: - nl_close(handle); - nl_handle_destroy(handle); - - return ret; -} diff --git a/pyanaconda/isys/iface.h b/pyanaconda/isys/iface.h deleted file mode 100644 index 820d10b..0000000 --- a/pyanaconda/isys/iface.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * iface.h - Network interface configuration API - * - * Copyright (C) 2006, 2007, 2008 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Author(s): David Cantrell <dcantrell@xxxxxxxxxx> - */ - -#ifndef ISYSIFACE_H -#define ISYSIFACE_H - -#include <resolv.h> -#include <net/if.h> -#include <netlink/cache.h> -#include <netlink/socket.h> -#include <glib.h> - -/* Enumerated types used in iface.c as well as loader's network code */ -enum { IPUNUSED = -1, IPV4, IPV6 }; - -enum { IPV4_UNUSED_METHOD, IPV4_DHCP_METHOD, IPV4_MANUAL_METHOD, IPV4_IBFT_METHOD, IPV4_IBFT_DHCP_METHOD }; -enum { IPV6_UNUSED_METHOD, IPV6_AUTO_METHOD, IPV6_DHCP_METHOD, - IPV6_MANUAL_METHOD }; - -#define IPV4_FIRST_METHOD IPV4_DHCP_METHOD -#define IPV4_LAST_METHOD IPV4_MANUAL_METHOD - -#define IPV6_FIRST_METHOD IPV6_AUTO_METHOD -#define IPV6_LAST_METHOD IPV6_MANUAL_METHOD - -/* Flags for the iface_t (do we need these?) */ -#define IFACE_FLAGS_NO_WRITE_RESOLV_CONF (((uint64_t) 1) << 0) -#define IFACE_NO_WRITE_RESOLV_CONF(a) ((a) & IFACE_FLAGS_NO_WRITE_RESOLV_CONF) - -/* Macros for starting NetworkManager */ -#define NETWORKMANAGER "/usr/sbin/NetworkManager" - -/* Per-interface configuration information */ -typedef struct _iface_t { - /* device name (e.g., eth0) */ - char device[IF_NAMESIZE]; - - /* MAC address as xx:xx:xx:xx:xx:xx */ - char *macaddr; - - /* IPv4 (store addresses in in_addr format, use inet_pton() to display) */ - struct in_addr ipaddr; - struct in_addr netmask; - struct in_addr broadcast; - - /* IPv6 (store addresses in in6_addr format, prefix is just an int) */ - struct in6_addr ip6addr; - int ip6prefix; - - /* Gateway settings */ - struct in_addr gateway; - struct in6_addr gateway6; - - /* BOOTP (these can be IPv4 or IPv6, store human-readable version as str) */ - char *nextserver; - char *bootfile; - - /* DNS (these can be IPv4 or IPv6, store human-readable version as str) */ - char *dns[MAXNS]; - int numdns; - char *hostname; - char *domain; - char *search; - - /* Misc DHCP settings */ - int dhcptimeout; - char *vendorclass; - - /* Wireless settings */ - char *ssid; - char *wepkey; - - /* s390 specifics */ - int mtu; - char *subchannels; - char *portname; - char *peerid; - char *nettype; - char *ctcprot; - char *layer2; - char *portno; - - /* flags */ - uint64_t flags; - int ipv4method; - int ipv6method; - int isiBFT; -} iface_t; - -/* Function prototypes */ - -/* - * Given an interface name (e.g., eth0) and address family (e.g., AF_INET), - * return the IP address in human readable format (i.e., the output from - * inet_ntop()). Return NULL for no match or error. - */ -char *iface_ip2str(char *, int); - -/* - * Given an interface name (e.g., eth0), return the MAC address in human - * readable format (e.g., 00:11:52:12:D9:A0). Return NULL for no match. - */ -char *iface_mac2str(char *); - -/* Given an interface's MAC address, return the name (e.g., eth0) in human - * readable format. Return NULL for no match - */ -char *iface_mac2device(char *); - -/* - * Convert an IPv4 CIDR prefix to a dotted-quad netmask. Return NULL on - * failure. - */ -struct in_addr *iface_prefix2netmask(int); - -/* - * Initialize a new iface_t structure to default values. - */ -void iface_init_iface_t(iface_t *); - -/* - * Given a pointer to a struct in_addr, return 1 if it contains a valid - * address, 0 otherwise. - */ -int iface_have_in_addr(struct in_addr *addr); - -/* - * Given a pointer to a struct in6_addr, return 1 if it contains a valid - * address, 0 otherwise. - */ -int iface_have_in6_addr(struct in6_addr *addr6); - -/* - * Checks if NetworkManager has an active connection. - */ -gboolean is_nm_connected(void); - -/* - * Start NetworkManager - */ -int iface_start_NetworkManager(void); - -/* - * Set Maximum Transfer Unit (MTU) on specified interface - */ -int iface_set_interface_mtu(char *ifname, int mtu); - -#endif /* ISYSIFACE_H */ diff --git a/pyanaconda/isys/imount.c b/pyanaconda/isys/imount.c deleted file mode 100644 index ed0f5a7..0000000 --- a/pyanaconda/isys/imount.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * imount.c - * - * Copyright (C) 2007, 2008, 2009 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/mount.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include "imount.h" -#include "log.h" - -#define _(foo) foo - -static int mkdirIfNone(char * directory); - -static int readFD(int fd, char **buf) { - char *p; - size_t size = 4096; - int s, filesize = 0; - - *buf = calloc(4096, sizeof (char)); - if (*buf == NULL) - abort(); - - do { - p = &(*buf)[filesize]; - s = read(fd, p, 4096); - if (s < 0) - break; - - filesize += s; - if (s == 0) - break; - - size += s; - *buf = realloc(*buf, size); - if (*buf == NULL) - abort(); - } while (1); - - if (filesize == 0 && s < 0) { - free(*buf); - *buf = NULL; - return -1; - } - - return filesize; -} - -static size_t rstrip(char *str) { - size_t len = strlen(str); - if (len > 0 && str[len-1] == '\n') { - str[len-1] = '\0'; - --len; - } - return len; -} - -int mountCommandWrapper(int mode, char *dev, char *where, char *fs, - char *options, char **err) { - int rc, child, status; - int stdout_pipe[2], stderr_pipe[2]; - char *opts = NULL, *device = NULL, *cmd = NULL; - - switch (mode) { - case IMOUNT_MODE_MOUNT: - case IMOUNT_MODE_BIND: - cmd = "/bin/mount"; - if (mkdirChain(where)) - return IMOUNT_ERR_ERRNO; - break; - case IMOUNT_MODE_UMOUNT: - cmd = "/bin/umount"; - break; - default: - return IMOUNT_ERR_MODE; - } - - if (mode == IMOUNT_MODE_MOUNT) { - if (strstr(fs, "nfs")) { - if (options) { - if (asprintf(&opts, "%s,nolock", options) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } - } else { - opts = strdup("nolock"); - } - - device = strdup(dev); - } else { - if ((options && strstr(options, "bind") == NULL) && - strncmp(dev, "LABEL=", 6) && strncmp(dev, "UUID=", 5) && - *dev != '/') { - if (asprintf(&device, "/dev/%s", dev) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } - } else { - device = strdup(dev); - } - - if (options) - opts = strdup(options); - } - } - - if (pipe(stdout_pipe)) - return IMOUNT_ERR_ERRNO; - if (pipe(stderr_pipe)) - return IMOUNT_ERR_ERRNO; - - if (!(child = fork())) { - int tty_fd; - - close(stdout_pipe[0]); - close(stderr_pipe[0]); - - /* Pull stdin from /dev/tty5 and redirect stdout and stderr to the pipes - * so we can log the output and put error messages into exceptions. - * We'll only use these messages should mount also return an error - * code. - */ - tty_fd = open("/dev/tty5", O_RDONLY); - close(STDIN_FILENO); - dup2(tty_fd, STDIN_FILENO); - close(tty_fd); - - close(STDOUT_FILENO); - dup2(stdout_pipe[1], STDOUT_FILENO); - close(STDERR_FILENO); - dup2(stderr_pipe[1], STDERR_FILENO); - - if (mode == IMOUNT_MODE_MOUNT) { - if (opts) { - logProgramMessage(INFO, "Running... %s -n -t %s -o %s %s %s", - cmd, fs, opts, device, where); - rc = execl(cmd, cmd, - "-n", "-t", fs, "-o", opts, device, where, NULL); - exit(1); - } else { - logProgramMessage(INFO, "Running... %s -n -t %s %s %s", - cmd, fs, device, where); - rc = execl(cmd, cmd, "-n", "-t", fs, device, where, NULL); - exit(1); - } - } else if (mode == IMOUNT_MODE_BIND) { - logProgramMessage(INFO, "Running... %s --bind %s %s", - cmd, dev, where); - rc = execl(cmd, cmd, "--bind", dev, where, NULL); - exit(1); - } else if (mode == IMOUNT_MODE_UMOUNT) { - logProgramMessage(INFO, "Running... %s %s", cmd, where); - rc = execl(cmd, cmd, where, NULL); - exit(1); - } else { - logProgramMessage(ERROR, "Running... Unknown imount mode: %d\n", mode); - exit(1); - } - } - - close(stdout_pipe[1]); - close(stderr_pipe[1]); - - char *buffer = NULL; - /* In case when when the stderr pipe gets enough data to fill the kernel - * buffer we might see a deadlock as this will block the mount program on - * its next write(). The buffer size is 65kB though so we should be safe. - */ - rc = readFD(stdout_pipe[0], &buffer); - if (rc > 0) { - rstrip(buffer); - logProgramMessage(INFO, buffer); - free(buffer); - buffer = NULL; - } - rc = readFD(stderr_pipe[0], &buffer); - if (rc > 0) { - rstrip(buffer); - logProgramMessage(ERROR, buffer); - if (err != NULL) - *err = buffer; - else - free(buffer); - } - close(stdout_pipe[0]); - close(stderr_pipe[0]); - - waitpid(child, &status, 0); - - if (opts) { - free(opts); - } - - if (device) { - free(device); - } - - if (!WIFEXITED(status)) - return IMOUNT_ERR_OTHER; - else if ( (rc = WEXITSTATUS(status)) ) { - /* Refer to 'man mount' for the meaning of the error codes. */ - switch (rc) { - case 1: - return IMOUNT_ERR_PERMISSIONS; - case 2: - return IMOUNT_ERR_SYSTEM; - case 4: - return IMOUNT_ERR_MOUNTINTERNAL; - case 8: - return IMOUNT_ERR_USERINTERRUPT; - case 16: - return IMOUNT_ERR_MTAB; - case 32: - return IMOUNT_ERR_MOUNTFAILURE; - case 64: - return IMOUNT_ERR_PARTIALSUCC; - default: - return IMOUNT_ERR_OTHER; - } - } - - return 0; -} - -int doBindMount(char* path, char *where, char **err) { - return mountCommandWrapper(IMOUNT_MODE_BIND, - path, where, NULL, NULL, err); -} - -int doPwMount(char *dev, char *where, char *fs, char *options, char **err) { - return mountCommandWrapper(IMOUNT_MODE_MOUNT, - dev, where, fs, options, err); -} - -int doPwUmount(char *where, char **err) { - return mountCommandWrapper(IMOUNT_MODE_UMOUNT, - NULL, where, NULL, NULL, err); -} - -int mkdirChain(char * origChain) { - char * chain; - char * chptr; - - chain = alloca(strlen(origChain) + 1); - strcpy(chain, origChain); - chptr = chain; - - while ((chptr = strchr(chptr, '/'))) { - *chptr = '\0'; - if (mkdirIfNone(chain)) { - *chptr = '/'; - return IMOUNT_ERR_ERRNO; - } - - *chptr = '/'; - chptr++; - } - - if (mkdirIfNone(chain)) - return IMOUNT_ERR_ERRNO; - - return 0; -} - -/* Returns true iff it is possible that the mount command that have returned - * 'errno' might succeed at a later time (think e.g. not yet initialized USB - * device, etc.) */ -int mountMightSucceedLater(int mountRc) -{ - int rc; - switch (mountRc) { - case IMOUNT_ERR_MOUNTFAILURE: - rc = 1; - break; - default: - rc = 0; - } - return rc; -} - -static int mkdirIfNone(char * directory) { - int rc, mkerr; - char * chptr; - - /* If the file exists it *better* be a directory -- I'm not going to - actually check or anything */ - if (!access(directory, X_OK)) return 0; - - /* if the path is '/' we get ENOFILE not found" from mkdir, rather - then EEXIST which is weird */ - for (chptr = directory; *chptr; chptr++) - if (*chptr != '/') break; - if (!*chptr) return 0; - - rc = mkdir(directory, 0755); - mkerr = errno; - - if (!rc || mkerr == EEXIST) return 0; - - return IMOUNT_ERR_ERRNO; -} diff --git a/pyanaconda/isys/imount.h b/pyanaconda/isys/imount.h deleted file mode 100644 index d1b7cf3..0000000 --- a/pyanaconda/isys/imount.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * imount.h - * - * Copyright (C) 2007, 2008, 2009 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef H_IMOUNT -#define H_IMOUNT - -#define IMOUNT_ERR_ERRNO 1 -#define IMOUNT_ERR_OTHER 2 -#define IMOUNT_ERR_MODE 3 -#define IMOUNT_ERR_PERMISSIONS 4 -#define IMOUNT_ERR_SYSTEM 5 -#define IMOUNT_ERR_MOUNTINTERNAL 6 -#define IMOUNT_ERR_USERINTERRUPT 7 -#define IMOUNT_ERR_MTAB 8 -#define IMOUNT_ERR_MOUNTFAILURE 9 -#define IMOUNT_ERR_PARTIALSUCC 10 - -#include <sys/mount.h> /* for umount() */ - -#define IMOUNT_RDONLY 1 -#define IMOUNT_BIND 2 -#define IMOUNT_REMOUNT 4 - -#define IMOUNT_MODE_MOUNT 1 -#define IMOUNT_MODE_UMOUNT 2 -#define IMOUNT_MODE_BIND 3 - -int doBindMount(char* path, char *where, char **err); -int doPwMount(char *dev, char *where, char *fs, char *options, char **err); -int doPwUmount(char *where, char **err); -int mkdirChain(char * origChain); -int mountMightSucceedLater(int mountRc); - -#endif diff --git a/pyanaconda/isys/isofs.c b/pyanaconda/isys/isofs.c deleted file mode 100644 index bb5a44a..0000000 --- a/pyanaconda/isys/isofs.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * isofs.c - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <fcntl.h> -#include <string.h> -#include <unistd.h> - -#define BLOCK_SIZE 2048 - -/* returns 1 if file is an ISO, 0 otherwise */ -int fileIsIso(const char * file) { - int blkNum; - char magic[5]; - int fd; - - fd = open(file, O_RDONLY); - if (fd < 0) - return 0; - - for (blkNum = 16; blkNum < 100; blkNum++) { - if (lseek(fd, blkNum * BLOCK_SIZE + 1, SEEK_SET) < 0) { - close(fd); - return 0; - } - - if (read(fd, magic, sizeof(magic)) != sizeof(magic)) { - close(fd); - return 0; - } - - if (!strncmp(magic, "CD001", 5)) { - close(fd); - return 1; - } - } - - close(fd); - return 0; -} diff --git a/pyanaconda/isys/isys.c b/pyanaconda/isys/isys.c deleted file mode 100644 index 409170b..0000000 --- a/pyanaconda/isys/isys.c +++ /dev/null @@ -1,701 +0,0 @@ -/* - * isys.c - * - * Copyright (C) 2007, 2008, 2009 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <Python.h> - -#include <stdio.h> -#include <dirent.h> -#include <errno.h> -#define u32 __u32 -#include <ext2fs/ext2fs.h> -#include <fcntl.h> -/* Need to tell loop.h what the actual dev_t type is. */ -#undef dev_t -#if defined(__alpha) || (defined(__sparc__) && defined(__arch64__)) -#define dev_t unsigned int -#else -#if defined(__x86_64__) -#define dev_t unsigned long -#else -#define dev_t unsigned short -#endif -#endif -#include <linux/loop.h> -#undef dev_t -#define dev_t dev_t -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <sys/sysmacros.h> -#include <sys/time.h> -#include <sys/utsname.h> -#include <sys/vfs.h> -#include <unistd.h> -#include <resolv.h> -#include <scsi/scsi.h> -#include <scsi/scsi_ioctl.h> -#include <sys/vt.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#include <linux/fb.h> -#include <libintl.h> -#include <libgen.h> -#include <linux/cdrom.h> -#include <linux/major.h> -#include <linux/raid/md_u.h> -#include <linux/raid/md_p.h> -#include <signal.h> -#include <execinfo.h> - -#include <blkid/blkid.h> - -#include <X11/Xlib.h> -#include <X11/XKBlib.h> -#include <X11/keysym.h> - -#include "iface.h" -#include "isys.h" -#include "imount.h" -#include "ethtool.h" -#include "lang.h" -#include "eddsupport.h" -#include "auditd.h" -#include "imount.h" -#include "log.h" - -#ifndef CDROMEJECT -#define CDROMEJECT 0x5309 -#endif - -static PyObject * doMount(PyObject * s, PyObject * args); -static PyObject * doUMount(PyObject * s, PyObject * args); -static PyObject * doSwapon(PyObject * s, PyObject * args); -static PyObject * doSwapoff(PyObject * s, PyObject * args); -static PyObject * doLoSetup(PyObject * s, PyObject * args); -static PyObject * doUnLoSetup(PyObject * s, PyObject * args); -static PyObject * doLoChangeFd(PyObject * s, PyObject * args); -static PyObject * doWipeRaidSuperblock(PyObject * s, PyObject * args); -static PyObject * doGetRaidChunkSize(PyObject * s, PyObject * args); -static PyObject * doDevSpaceFree(PyObject * s, PyObject * args); -static PyObject * doResetResolv(PyObject * s, PyObject * args); -static PyObject * doLoadKeymap(PyObject * s, PyObject * args); -static PyObject * doExt2Dirty(PyObject * s, PyObject * args); -static PyObject * doExt2HasJournal(PyObject * s, PyObject * args); -static PyObject * doEjectCdrom(PyObject * s, PyObject * args); -static PyObject * doVtActivate(PyObject * s, PyObject * args); -static PyObject * doisPseudoTTY(PyObject * s, PyObject * args); -static PyObject * doisVioConsole(PyObject * s); -static PyObject * doSync(PyObject * s, PyObject * args); -static PyObject * doisIsoImage(PyObject * s, PyObject * args); -static PyObject * printObject(PyObject * s, PyObject * args); -static PyObject * py_bind_textdomain_codeset(PyObject * o, PyObject * args); -static PyObject * doSegvHandler(PyObject *s, PyObject *args); -static PyObject * doAuditDaemon(PyObject *s); -static PyObject * doPrefixToNetmask(PyObject *s, PyObject *args); -static PyObject * doGetBlkidData(PyObject * s, PyObject * args); -static PyObject * doIsCapsLockEnabled(PyObject * s, PyObject * args); -static PyObject * doGetLinkStatus(PyObject * s, PyObject * args); -static PyObject * doGetAnacondaVersion(PyObject * s, PyObject * args); -static PyObject * doInitLog(PyObject * s); - -static PyMethodDef isysModuleMethods[] = { - { "ejectcdrom", (PyCFunction) doEjectCdrom, METH_VARARGS, NULL }, - { "e2dirty", (PyCFunction) doExt2Dirty, METH_VARARGS, NULL }, - { "e2hasjournal", (PyCFunction) doExt2HasJournal, METH_VARARGS, NULL }, - { "devSpaceFree", (PyCFunction) doDevSpaceFree, METH_VARARGS, NULL }, - { "wiperaidsb", (PyCFunction) doWipeRaidSuperblock, METH_VARARGS, NULL }, - { "getraidchunk", (PyCFunction) doGetRaidChunkSize, METH_VARARGS, NULL }, - { "lochangefd", (PyCFunction) doLoChangeFd, METH_VARARGS, NULL }, - { "losetup", (PyCFunction) doLoSetup, METH_VARARGS, NULL }, - { "unlosetup", (PyCFunction) doUnLoSetup, METH_VARARGS, NULL }, - { "mount", (PyCFunction) doMount, METH_VARARGS, NULL }, - { "umount", (PyCFunction) doUMount, METH_VARARGS, NULL }, - { "resetresolv", (PyCFunction) doResetResolv, METH_VARARGS, NULL }, - { "swapon", (PyCFunction) doSwapon, METH_VARARGS, NULL }, - { "swapoff", (PyCFunction) doSwapoff, METH_VARARGS, NULL }, - { "loadKeymap", (PyCFunction) doLoadKeymap, METH_VARARGS, NULL }, - { "vtActivate", (PyCFunction) doVtActivate, METH_VARARGS, NULL}, - { "isPseudoTTY", (PyCFunction) doisPseudoTTY, METH_VARARGS, NULL}, - { "isVioConsole", (PyCFunction) doisVioConsole, METH_NOARGS, NULL}, - { "sync", (PyCFunction) doSync, METH_VARARGS, NULL}, - { "isisoimage", (PyCFunction) doisIsoImage, METH_VARARGS, NULL}, - { "printObject", (PyCFunction) printObject, METH_VARARGS, NULL}, - { "bind_textdomain_codeset", (PyCFunction) py_bind_textdomain_codeset, METH_VARARGS, NULL}, - { "handleSegv", (PyCFunction) doSegvHandler, METH_VARARGS, NULL }, - { "auditdaemon", (PyCFunction) doAuditDaemon, METH_NOARGS, NULL }, - { "prefix2netmask", (PyCFunction) doPrefixToNetmask, METH_VARARGS, NULL }, - { "getblkid", (PyCFunction) doGetBlkidData, METH_VARARGS, NULL }, - { "isCapsLockEnabled", (PyCFunction) doIsCapsLockEnabled, METH_VARARGS, NULL }, - { "getLinkStatus", (PyCFunction) doGetLinkStatus, METH_VARARGS, NULL }, - { "getAnacondaVersion", (PyCFunction) doGetAnacondaVersion, METH_VARARGS, NULL }, - { "initLog", (PyCFunction) doInitLog, METH_VARARGS, NULL }, - { NULL, NULL, 0, NULL } -} ; - -static PyObject * doUnLoSetup(PyObject * s, PyObject * args) { - int loopfd; - - if (!PyArg_ParseTuple(args, "i", &loopfd)) return NULL; - if (ioctl(loopfd, LOOP_CLR_FD, 0)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - -/* XXX - msw */ -#ifndef LOOP_CHANGE_FD -#define LOOP_CHANGE_FD 0x4C06 -#endif - -static PyObject * doLoChangeFd(PyObject * s, PyObject * args) { - int loopfd; - int targfd; - - if (!PyArg_ParseTuple(args, "ii", &loopfd, &targfd)) - return NULL; - if (ioctl(loopfd, LOOP_CHANGE_FD, targfd)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * doLoSetup(PyObject * s, PyObject * args) { - int loopfd; - int targfd; - struct loop_info loopInfo; - char * loopName; - - if (!PyArg_ParseTuple(args, "iis", &loopfd, &targfd, &loopName)) - return NULL; - if (ioctl(loopfd, LOOP_SET_FD, targfd)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - memset(&loopInfo, 0, sizeof(loopInfo)); - strncpy(loopInfo.lo_name, basename(loopName), 63); - - if (ioctl(loopfd, LOOP_SET_STATUS, &loopInfo)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * doUMount(PyObject * s, PyObject * args) { - char *err = NULL, *mntpoint = NULL; - int rc; - - if (!PyArg_ParseTuple(args, "s", &mntpoint)) { - return NULL; - } - - rc = doPwUmount(mntpoint, &err); - if (rc == IMOUNT_ERR_ERRNO) { - PyErr_SetFromErrno(PyExc_SystemError); - } else if (rc) { - PyObject *tuple = PyTuple_New(2); - - PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc)); - - if (err == NULL) { - Py_INCREF(Py_None); - PyTuple_SetItem(tuple, 1, Py_None); - } else { - PyTuple_SetItem(tuple, 1, PyString_FromString(err)); - } - - PyErr_SetObject(PyExc_SystemError, tuple); - } - - if (rc) { - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * doMount(PyObject * s, PyObject * args) { - char *err = NULL, *fs, *device, *mntpoint, *flags = NULL; - int rc; - - if (!PyArg_ParseTuple(args, "sss|z", &fs, &device, &mntpoint, - &flags)) return NULL; - - rc = doPwMount(device, mntpoint, fs, flags, &err); - if (rc == IMOUNT_ERR_ERRNO) - PyErr_SetFromErrno(PyExc_SystemError); - else if (rc) { - PyObject *tuple = PyTuple_New(2); - - PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc)); - - if (err == NULL) { - Py_INCREF(Py_None); - PyTuple_SetItem(tuple, 1, Py_None); - } else { - PyTuple_SetItem(tuple, 1, PyString_FromString(err)); - } - - PyErr_SetObject(PyExc_SystemError, tuple); - } - - if (rc) return NULL; - - Py_INCREF(Py_None); - return Py_None; -} - -#define BOOT_SIGNATURE 0xaa55 /* boot signature */ -#define BOOT_SIG_OFFSET 510 /* boot signature offset */ - -int swapoff(const char * path); -int swapon(const char * path, int priorty); - -static PyObject * doSwapoff (PyObject * s, PyObject * args) { - char * path; - - if (!PyArg_ParseTuple(args, "s", &path)) return NULL; - - if (swapoff (path)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * doSwapon (PyObject * s, PyObject * args) { - char * path; - - if (!PyArg_ParseTuple(args, "s", &path)) return NULL; - - if (swapon (path, 0)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - -void init_isys(void) { - PyObject * m, * d; - - m = Py_InitModule("_isys", isysModuleMethods); - d = PyModule_GetDict(m); - - PyDict_SetItemString(d, "MIN_RAM", PyInt_FromLong(MIN_RAM)); - PyDict_SetItemString(d, "MIN_GUI_RAM", PyInt_FromLong(MIN_GUI_RAM)); - PyDict_SetItemString(d, "URL_INSTALL_EXTRA_RAM", PyInt_FromLong(URL_INSTALL_EXTRA_RAM)); - PyDict_SetItemString(d, "EARLY_SWAP_RAM", PyInt_FromLong(EARLY_SWAP_RAM)); -} - -static PyObject * doPrefixToNetmask (PyObject * s, PyObject * args) { - int prefix = 0; - struct in_addr *mask = NULL; - char dst[INET_ADDRSTRLEN+1]; - - if (!PyArg_ParseTuple(args, "i", &prefix)) - return NULL; - - if ((mask = iface_prefix2netmask(prefix)) == NULL) - return NULL; - - if (inet_ntop(AF_INET, mask, dst, INET_ADDRSTRLEN) == NULL) - return NULL; - - return Py_BuildValue("s", dst); -} - -static PyObject * doResetResolv(PyObject * s, PyObject * args) { - if (!PyArg_ParseTuple(args, "")) { - return NULL; - } - - /* reinit the resolver so DNS changes take affect */ - res_init(); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * doWipeRaidSuperblock(PyObject * s, PyObject * args) { - int fd; - unsigned long size; - struct mdp_super_t * sb; - - if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; - - if (ioctl(fd, BLKGETSIZE, &size)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - /* put the size in 1k blocks */ - size >>= 1; - - if (lseek64(fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), SEEK_SET) < 0) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - sb = malloc(sizeof(mdp_super_t)); - sb = memset(sb, '\0', sizeof(mdp_super_t)); - - if (write(fd, sb, sizeof(sb)) != sizeof(sb)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - return Py_None; -} - -static PyObject * doGetRaidChunkSize(PyObject * s, PyObject * args) { - int fd; - unsigned long size; - mdp_super_t sb; - - if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; - - if (ioctl(fd, BLKGETSIZE, &size)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - /* put the size in 1k blocks */ - size >>= 1; - - if (lseek64(fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), SEEK_SET) < 0) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - if (sb.md_magic != MD_SB_MAGIC) { - PyErr_SetString(PyExc_ValueError, "bad md magic on device"); - return NULL; - } - - return Py_BuildValue("i", sb.chunk_size / 1024); -} - -static int get_bits(unsigned long long v) { - int b = 0; - - if ( v & 0xffffffff00000000LLU ) { b += 32; v >>= 32; } - if ( v & 0xffff0000LLU ) { b += 16; v >>= 16; } - if ( v & 0xff00LLU ) { b += 8; v >>= 8; } - if ( v & 0xf0LLU ) { b += 4; v >>= 4; } - if ( v & 0xcLLU ) { b += 2; v >>= 2; } - if ( v & 0x2LLU ) b++; - - return v ? b + 1 : b; -} - -static PyObject * doDevSpaceFree(PyObject * s, PyObject * args) { - char * path; - struct statfs sb; - unsigned long long size; - - if (!PyArg_ParseTuple(args, "s", &path)) return NULL; - - if (statfs(path, &sb)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - /* Calculate a saturated addition to prevent oveflow. */ - if ( get_bits(sb.f_bfree) + get_bits(sb.f_bsize) <= 64 ) - size = (unsigned long long)sb.f_bfree * sb.f_bsize; - else - size = ~0LLU; - - return PyLong_FromUnsignedLongLong(size>>20); -} - -static PyObject * doLoadKeymap (PyObject * s, PyObject * args) { - char * keymap; - int ret; - - if (!PyArg_ParseTuple(args, "s", &keymap)) return NULL; - - ret = isysLoadKeymap (keymap); - if (ret) { - errno = -ret; - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * doExt2Dirty(PyObject * s, PyObject * args) { - char * device; - ext2_filsys fsys; - int rc; - int clean; - - if (!PyArg_ParseTuple(args, "s", &device)) return NULL; - - rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, - &fsys); - if (rc) { - Py_INCREF(Py_None); - return Py_None; - } - - clean = fsys->super->s_state & EXT2_VALID_FS; - - ext2fs_close(fsys); - - return Py_BuildValue("i", !clean); -} -static PyObject * doExt2HasJournal(PyObject * s, PyObject * args) { - char * device; - ext2_filsys fsys; - int rc; - int hasjournal; - - if (!PyArg_ParseTuple(args, "s", &device)) return NULL; - rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, - &fsys); - if (rc) { - Py_INCREF(Py_None); - return Py_None; - } - - hasjournal = fsys->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL; - - ext2fs_close(fsys); - - return Py_BuildValue("i", hasjournal); -} - -static PyObject * doEjectCdrom(PyObject * s, PyObject * args) { - int fd; - - if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; - - /* Ask it to unlock the door and then eject the disc. There's really - * nothing to do if unlocking doesn't work, so just eject without - * worrying about it. -- pjones - */ - ioctl(fd, CDROM_LOCKDOOR, 0); - if (ioctl(fd, CDROMEJECT, 1)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * doVtActivate(PyObject * s, PyObject * args) { - int vtnum; - - if (!PyArg_ParseTuple(args, "i", &vtnum)) return NULL; - - if (ioctl(0, VT_ACTIVATE, vtnum)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * doisPseudoTTY(PyObject * s, PyObject * args) { - int fd; - struct stat sb; - - if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; - fstat(fd, &sb); - - /* XXX close enough for now */ - return Py_BuildValue("i", ((major(sb.st_rdev) >= 136) && (major(sb.st_rdev) <= 143))); -} - -static PyObject * doisVioConsole(PyObject * s) { - return Py_BuildValue("i", isVioConsole()); -} - -static PyObject * doSync(PyObject * s, PyObject * args) { - int fd; - - if (!PyArg_ParseTuple(args, "", &fd)) return NULL; - sync(); - - Py_INCREF(Py_None); - return Py_None; -} - -int fileIsIso(const char * file); - -static PyObject * doisIsoImage(PyObject * s, PyObject * args) { - char * fn; - int rc; - - if (!PyArg_ParseTuple(args, "s", &fn)) return NULL; - - rc = fileIsIso(fn); - - return Py_BuildValue("i", rc); -} - -static PyObject * printObject (PyObject * o, PyObject * args) { - PyObject * obj; - char buf[256]; - - if (!PyArg_ParseTuple(args, "O", &obj)) - return NULL; - - snprintf(buf, 256, "<%s object at %lx>", obj->ob_type->tp_name, - (long) obj); - - return PyString_FromString(buf); -} - -static PyObject * -py_bind_textdomain_codeset(PyObject * o, PyObject * args) { - char *domain, *codeset, *ret; - - if (!PyArg_ParseTuple(args, "ss", &domain, &codeset)) - return NULL; - - ret = bind_textdomain_codeset(domain, codeset); - - if (ret) - return PyString_FromString(ret); - - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; -} - -static PyObject * doSegvHandler(PyObject *s, PyObject *args) { - void *array[20]; - size_t size; - char **strings; - size_t i; - - signal(SIGSEGV, SIG_DFL); /* back to default */ - - size = backtrace (array, 20); - strings = backtrace_symbols (array, size); - - printf ("Anaconda received SIGSEGV!. Backtrace:\n"); - for (i = 0; i < size; i++) - printf ("%s\n", strings[i]); - - free (strings); - exit(1); -} - -static PyObject * doAuditDaemon(PyObject *s) { - audit_daemonize(); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * doGetBlkidData(PyObject * s, PyObject * args) { - char * dev, * key; - blkid_cache cache; - blkid_dev bdev = NULL; - blkid_tag_iterate titer; - const char * type, * data; - - if (!PyArg_ParseTuple(args, "ss", &dev, &key)) return NULL; - - blkid_get_cache(&cache, NULL); - - bdev = blkid_get_dev(cache, dev, BLKID_DEV_NORMAL); - if (bdev == NULL) - goto out; - titer = blkid_tag_iterate_begin(bdev); - while (blkid_tag_next(titer, &type, &data) >= 0) { - if (!strcmp(type, key)) { - blkid_tag_iterate_end(titer); - return Py_BuildValue("s", data); - } - } - blkid_tag_iterate_end(titer); - - out: - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * doIsCapsLockEnabled(PyObject * s, PyObject * args) { - Display *d = NULL; - XkbStateRec state; - - if ((d = XOpenDisplay(NULL)) == NULL) { - return NULL; - } - - memset(&state, 0, sizeof(state)); - XkbGetState(d, XkbUseCoreKbd, &state); - - if (XCloseDisplay(d)) { - return NULL; - } - - return PyBool_FromLong(state.locked_mods & LockMask); -} - -static PyObject * doGetLinkStatus(PyObject * s, PyObject * args) { - char *dev = NULL; - - if (!PyArg_ParseTuple(args, "s", &dev)) { - return NULL; - } - - if (get_link_status(dev) == 1) { - return PyBool_FromLong(1); - } - - return PyBool_FromLong(0); -} - -static PyObject * doGetAnacondaVersion(PyObject * s, PyObject * args) { - return Py_BuildValue("s", VERSION); -} - -static PyObject * doInitLog(PyObject * s) { - openLog(); - Py_INCREF(Py_None); - return Py_None; -} - -/* vim:set shiftwidth=4 softtabstop=4: */ diff --git a/pyanaconda/isys/isys.h b/pyanaconda/isys/isys.h deleted file mode 100644 index e3cb1fc..0000000 --- a/pyanaconda/isys/isys.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * isys.h - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef H_ISYS -#define H_ISYS - -#define MIN_RAM 262144 // 256 MB -#define MIN_GUI_RAM 524288 // 512 MB -#define URL_INSTALL_EXTRA_RAM 131072 // 128 MB -#define EARLY_SWAP_RAM 524288 - -#define OUTPUT_TERMINAL "/dev/tty5" - -int insmod(char * modName, char * path, char ** args); -int rmmod(char * modName); - -/* returns 0 for true, !0 for false */ -int fileIsIso(const char * file); - -/* returns 1 if on an iSeries vio console, 0 otherwise */ -int isVioConsole(void); - -#endif diff --git a/pyanaconda/isys/lang.c b/pyanaconda/isys/lang.c deleted file mode 100644 index b6e2a36..0000000 --- a/pyanaconda/isys/lang.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * lang.c - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <alloca.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <unistd.h> - -#include <linux/keyboard.h> -#ifdef NR_KEYS -#undef NR_KEYS -#define NR_KEYS 128 -#endif - -#include "linux/kd.h" - -#include "cpio.h" -#include "isys.h" -#include "lang.h" -#include "stubs.h" - -int isysLoadFont(void) { - unsigned char font[65536]; - struct console_font_op cfo; - unsigned short map[E_TABSZ]; - struct unimapdesc d; - struct unimapinit u; - struct unipair desc[2048]; - gzFile stream; - int rc; - -#if defined (__s390__) || defined (__s390x__) - return 0; -#endif - stream = gunzip_open("/etc/screenfont.gz"); - if (!stream) - return -EACCES; - - gunzip_read(stream, &cfo, sizeof(cfo)); - gunzip_read(stream, font, sizeof(font)); - gunzip_read(stream, map, sizeof(map)); - gunzip_read(stream, &d.entry_ct, sizeof(d.entry_ct)); - d.entries = desc; - gunzip_read(stream, desc, d.entry_ct * sizeof(desc[0])); - gunzip_close(stream); - - cfo.data = font; - cfo.op = KD_FONT_OP_SET; - - rc = ioctl(1, KDFONTOP, &cfo); - if (rc) return rc; - rc = ioctl(1, PIO_UNIMAPCLR, &u); - if (rc) return rc; - rc = ioctl(1, PIO_UNIMAP, &d); - if (rc) return rc; - rc = ioctl(1, PIO_UNISCRNMAP, map); - if (rc) return rc; - /* activate the font map */ - fprintf(stderr, "\033(K"); - return 0; -} - -int isysSetUnicodeKeymap(void) { - int console; - -#if defined (__s390__) || defined (__s390x__) - return 0; -#endif - console = open("/dev/console", O_RDWR); - if (console < 0) - return -EACCES; - - /* place keyboard in unicode mode */ - ioctl(console, KDSKBMODE, K_UNICODE); - close(console); - return 0; -} - -/* the file pointer must be at the beginning of the section already! */ -int loadKeymap(gzFile stream) { - int console; - int kmap, key; - struct kbentry entry; - int keymaps[MAX_NR_KEYMAPS]; - int count = 0; - unsigned int magic; - short keymap[NR_KEYS]; - struct stat sb; - -#if defined (__s390__) || defined (__s390x__) - return 0; -#endif - if (isVioConsole()) - return 0; - - /* assume that if we're already on a pty loading a keymap is silly */ - fstat(0, &sb); - if (major(sb.st_rdev) == 3 || major(sb.st_rdev) == 136) - return 0; - - if (gunzip_read(stream, &magic, sizeof(magic)) != sizeof(magic)) - return -EIO; - - if (magic != KMAP_MAGIC) return -EINVAL; - - if (gunzip_read(stream, keymaps, sizeof(keymaps)) != sizeof(keymaps)) - return -EINVAL; - - console = open("/dev/tty0", O_RDWR); - if (console < 0) - return -EACCES; - - for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) { - if (!keymaps[kmap]) continue; - - if (gunzip_read(stream, keymap, sizeof(keymap)) != sizeof(keymap)) { - close(console); - return -EIO; - } - - count++; - for (key = 0; key < NR_KEYS; key++) { - entry.kb_index = key; - entry.kb_table = kmap; - entry.kb_value = keymap[key]; - if (KTYP(entry.kb_value) != KT_SPEC) { - if (ioctl(console, KDSKBENT, &entry)) { - int ret = errno; - close(console); - return ret; - } - } - } - } - close(console); - return 0; -} - -int isysLoadKeymap(char * keymap) { - int num = -1; - int rc; - gzFile f; - struct kmapHeader hdr; - struct kmapInfo * infoTable; - char buf[16384]; /* I hope this is big enough */ - int i; - - f = gunzip_open("/etc/keymaps.gz"); - if (!f) return -EACCES; - - if (gunzip_read(f, &hdr, sizeof(hdr)) != sizeof(hdr)) { - gunzip_close(f); - return -EINVAL; - } - - i = hdr.numEntries * sizeof(*infoTable); - infoTable = alloca(i); - if (gunzip_read(f, infoTable, i) != i) { - gunzip_close(f); - return -EIO; - } - - for (i = 0; i < hdr.numEntries; i++) - if (!strcmp(infoTable[i].name, keymap)) { - num = i; - break; - } - - if (num == -1) { - gunzip_close(f); - return -ENOENT; - } - - for (i = 0; i < num; i++) { - if (gunzip_read(f, buf, infoTable[i].size) != infoTable[i].size) { - gunzip_close(f); - return -EIO; - } - } - - rc = loadKeymap(f); - - gunzip_close(f); - - return rc; -} diff --git a/pyanaconda/isys/lang.h b/pyanaconda/isys/lang.h deleted file mode 100644 index a08adbd..0000000 --- a/pyanaconda/isys/lang.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * lang.h - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef ISYS_LANG_H -#define ISYS_LANG_H - -#include "stubs.h" - -/* define ask johnsonm@xxxxxxxxxx where this came from */ -#define KMAP_MAGIC 0x8B39C07F -#define KMAP_NAMELEN 40 /* including '\0' */ - -struct kmapHeader { - int magic; - int numEntries; -}; - -struct kmapInfo { - int size; - char name[KMAP_NAMELEN]; -}; - -int loadKeymap(gzFile stream); -int isysLoadFont(void); -int isysLoadKeymap(char * keymap); -int isysSetUnicodeKeymap(void); - -#endif diff --git a/pyanaconda/isys/linkdetect.c b/pyanaconda/isys/linkdetect.c deleted file mode 100644 index f97a291..0000000 --- a/pyanaconda/isys/linkdetect.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * linkdetect.c - simple link detection - * - * pulls code from mii-tool.c in net-toools and ethtool so - * that we can do everything that jgarzik says we should check - * - * Copyright (C) 2002, 2003 Red Hat, Inc. All rights reserved. - * Portions Copyright (C) 2000 David A. Hinds -- dhinds@xxxxxxxxxxxxxxxxxxxxxx - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Author(s): Jeremy Katz <katzj@xxxxxxxxxx> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <sys/ioctl.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include <sys/socket.h> -#include <sys/types.h> -#include <net/if.h> - -#include <linux/sockios.h> -#include <linux/mii.h> -#include <linux/ethtool.h> -#include "ethtool.h" - -static struct ifreq ifr; - -static int mdio_read(int skfd, uint16_t location) -{ - struct mii_ioctl_data mii; - - memset(&mii, 0, sizeof(mii)); - memcpy(&mii, &ifr.ifr_data, sizeof(mii)); - mii.reg_num = location; - memcpy(&ifr.ifr_data, &mii, sizeof(mii)); - - if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) { -#ifdef STANDALONE - fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name, - strerror(errno)); -#endif - return -1; - } else { - memcpy(&mii, &ifr.ifr_data, sizeof(mii)); - } - - return mii.val_out; -} - -/* we don't need writing right now */ -#if 0 -static void mdio_write(int skfd, int location, int value) -{ - struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr.ifr_data; - mii->reg_num = location; - mii->val_in = value; - if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) { -#ifdef STANDALONE - fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name, - strerror(errno)); -#endif - } -} -#endif - - - -static int get_mii_link_status(int sock) { - int i, mii_val[32]; - - if (ioctl(sock, SIOCGMIIPHY, &ifr) < 0) { - if (errno != ENODEV) -#ifdef STANDALONE - fprintf(stderr, "SIOCGMIIPHY on '%s' failed: %s\n", - ifr.ifr_name, strerror(errno)); -#endif - return -1; - } - - /* Some bits in the BMSR are latched, but we can't rely on being - the only reader, so only the current values are meaningful */ - mdio_read(sock, MII_BMSR); - for (i = 0; i < 8; i++) - mii_val[i] = mdio_read(sock, i); - - if (mii_val[MII_BMCR] == 0xffff) { -#ifdef STANDALONE - fprintf(stderr, " No MII transceiver present!.\n"); -#endif - return -1; - } - - if (mii_val[MII_BMSR] & BMSR_LSTATUS) - return 1; - else - return 0; -} - -static int get_ethtool_link_status(int sock) { - struct ethtool_value edata; - int rc; - - edata.cmd = ETHTOOL_GLINK; - ifr.ifr_data = (caddr_t)&edata; - rc = ioctl(sock, SIOCETHTOOL, &ifr); - if (rc == 0) { - return edata.data; - } else if (errno != EOPNOTSUPP) { -#ifdef STANDALONE - fprintf(stderr, "Cannot get link status (%d): %s\n", errno, strerror(errno)); -#endif - } - - return -1; -} - - - -int get_link_status(char * devname) { - int sock, rc; - - if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { -#ifdef STANDALONE - fprintf(stderr, "Error creating socket: %s\n", strerror(errno)); -#endif - return -1; - } - - /* make sure interface is up and activated */ - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, devname); - - if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { - return -1; - } - - ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); - - if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) { - return -1; - } - - /* Setup our control structures. */ - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, devname); - - /* check for link with both ethtool and mii registers. ethtool is - * supposed to be the One True Way (tm), but it seems to not work - * with much yet :/ */ - - rc = get_ethtool_link_status(sock); -#ifdef STANDALONE - printf("ethtool link status of %s is: %d\n", devname, rc); -#endif - if (rc == 1) { - close(sock); - return 1; - } - - rc = get_mii_link_status(sock); -#ifdef STANDALONE - printf("MII link status of %s is: %d\n", devname, rc); -#endif - if (rc == 1) { - close(sock); - return 1; - } - - return 0; -} - -#ifdef STANDALONE -/* hooray for stupid test programs! */ -int main(int argc, char **argv) { - char * dev; - - if (argc >= 2) - dev = argv[1]; - else - dev = strdup("eth0"); - - printf("link status of %s is %d\n", dev, get_link_status(dev)); - return 0; -} -#endif diff --git a/pyanaconda/isys/log.c b/pyanaconda/isys/log.c deleted file mode 100644 index da39c7b..0000000 --- a/pyanaconda/isys/log.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * log.c - logging functionality - * - * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Author(s): Erik Troan <ewt@xxxxxxxxxx> - * Matt Wilson <msw@xxxxxxxxxx> - * Michael Fulbright <msf@xxxxxxxxxx> - * Jeremy Katz <katzj@xxxxxxxxxx> - */ - -#include <fcntl.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include <unistd.h> -#include <sys/time.h> -#include <syslog.h> - -#include "log.h" - -static FILE * main_log_tty = NULL; -static FILE * main_log_file = NULL; -static FILE * program_log_file = NULL; -static int minLevel = INFO; -static const char * main_tag = "loader"; -static const char * program_tag = "program"; -static const int syslog_facility = LOG_LOCAL0; - -/* maps our loglevel to syslog loglevel */ -static int mapLogLevel(int level) -{ - switch (level) { - case DEBUGLVL: - return LOG_DEBUG; - case INFO: - return LOG_INFO; - case WARNING: - return LOG_WARNING; - case CRITICAL: - return LOG_CRIT; - case ERROR: - default: - /* if someone called us with an invalid level value, log it as an error - too. */ - return LOG_ERR; - } -} - -static void printLogHeader(int level, const char *tag, FILE *outfile) { - struct timeval current_time; - struct tm *t; - int msecs; - - gettimeofday(¤t_time, NULL); - t = gmtime(¤t_time.tv_sec); - msecs = current_time.tv_usec / 1000; - switch (level) { - case DEBUGLVL: - fprintf (outfile, "%02d:%02d:%02d,%03d DEBUG %s: ", t->tm_hour, - t->tm_min, t->tm_sec, msecs, tag); - break; - - case INFO: - fprintf (outfile, "%02d:%02d:%02d,%03d INFO %s: ", t->tm_hour, - t->tm_min, t->tm_sec, msecs, tag); - break; - - case WARNING: - fprintf (outfile, "%02d:%02d:%02d,%03d WARNING %s: ", t->tm_hour, - t->tm_min, t->tm_sec, msecs, tag); - break; - - case ERROR: - fprintf (outfile, "%02d:%02d:%02d,%03d ERROR %s: ", t->tm_hour, - t->tm_min, t->tm_sec, msecs, tag); - break; - - case CRITICAL: - fprintf (outfile, "%02d:%02d:%02d,%03d CRITICAL %s: ", t->tm_hour, - t->tm_min, t->tm_sec, msecs, tag); - break; - } -} - -static void printLogMessage(int level, const char *tag, FILE *outfile, const char *s, va_list ap) -{ - printLogHeader(level, tag, outfile); - - va_list apc; - va_copy(apc, ap); - vfprintf(outfile, s, apc); - va_end(apc); - - fprintf(outfile, "\n"); - fflush(outfile); -} - -static void retagSyslog(const char* new_tag) -{ - closelog(); - openlog(new_tag, 0, syslog_facility); -} - -void logMessageV(enum logger_t logger, int level, const char * s, va_list ap) { - FILE *log_tty = main_log_tty; - FILE *log_file = main_log_file; - const char *tag = main_tag; - if (logger == PROGRAM_LOG) { - /* tty output is done directly for programs */ - log_tty = NULL; - log_file = program_log_file; - tag = program_tag; - /* close and reopen syslog so we get the tagging right */ - retagSyslog(tag); - } - - va_list apc; - /* Log everything into syslog */ - va_copy(apc, ap); - vsyslog(mapLogLevel(level), s, apc); - va_end(apc); - - /* Only log to the screen things that are above the minimum level. */ - if (main_log_tty && level >= minLevel && log_tty) { - printLogMessage(level, tag, log_tty, s, ap); - } - - /* But log everything to the file. */ - if (main_log_file) { - printLogMessage(level, tag, log_file, s, ap); - } - - /* change the syslog tag back to the default again */ - if (logger == PROGRAM_LOG) - retagSyslog(main_tag); -} - -void logMessage(int level, const char * s, ...) { - va_list args; - - va_start(args, s); - logMessageV(MAIN_LOG, level, s, args); - va_end(args); -} - -void logProgramMessage(int level, const char * s, ...) { - va_list args; - - va_start(args, s); - logMessageV(PROGRAM_LOG, level, s, args); - va_end(args); -} - -int tty_logfd = -1; -int file_logfd = -1; - -void openLog() { - /* init syslog logging (so loader messages can also be forwarded to a remote - syslog daemon */ - openlog(main_tag, 0, syslog_facility); - - int flags; - main_log_tty = fopen("/dev/tty3", "a"); - main_log_file = fopen("/tmp/anaconda.log", "a"); - program_log_file = fopen("/tmp/program.log", "a"); - - if (main_log_tty) { - tty_logfd = fileno(main_log_tty); - flags = fcntl(tty_logfd, F_GETFD, 0) | FD_CLOEXEC; - fcntl(tty_logfd, F_SETFD, flags); - } - - if (main_log_file) { - file_logfd = fileno(main_log_file); - flags = fcntl(file_logfd, F_GETFD, 0) | FD_CLOEXEC; - fcntl(file_logfd, F_SETFD, flags); - } - - if (program_log_file) { - int fd; - fd = fileno(program_log_file); - flags = fcntl(fd, F_GETFD, 0) | FD_CLOEXEC; - fcntl(file_logfd, F_SETFD, flags); - } -} - -void closeLog(void) { - if (main_log_tty) - fclose(main_log_tty); - if (main_log_file) - fclose(main_log_file); - if (program_log_file) - fclose(program_log_file); - - /* close syslog logger */ - closelog(); -} - -/* set the level. higher means you see more verbosity */ -void setLogLevel(int level) { - minLevel = level; -} - -int getLogLevel(void) { - return minLevel; -} - -/* vim:set shiftwidth=4 softtabstop=4: */ diff --git a/pyanaconda/isys/log.h b/pyanaconda/isys/log.h deleted file mode 100644 index 51de2de..0000000 --- a/pyanaconda/isys/log.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * log.h - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _LOG_H_ -#define _LOG_H_ - -#include <stdio.h> -#include <stdarg.h> - -#define DEBUGLVL 10 -#define INFO 20 -#define WARNING 30 -#define ERROR 40 -#define CRITICAL 50 - -enum logger_t { - MAIN_LOG = 1, - PROGRAM_LOG = 2 -}; - -void logMessageV(enum logger_t logger, int level, const char * s, va_list ap) - __attribute__ ((format (printf, 3, 0))); -void logMessage(int level, const char * s, ...) - __attribute__ ((format (printf, 2, 3))); -void logProgramMessage(int level, const char * s, ...) - __attribute__ ((format (printf, 2, 3))); -void openLog(); -void closeLog(void); -void setLogLevel(int minLevel); -int getLogLevel(void); - -extern int tty_logfd; -extern int file_logfd; - -#endif /* _LOG_H_ */ diff --git a/pyanaconda/isys/stubs.h b/pyanaconda/isys/stubs.h deleted file mode 100644 index 40ecb22..0000000 --- a/pyanaconda/isys/stubs.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * stubs.h - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* we use gzlib when linked against dietlibc, but otherwise, we should use - zlib. it would make more sense to do the defines in the other direction, - but that causes symbol wackiness because both gunzip_open and gzip_open in - gzlib are gzopen from zlib -*/ - -#ifndef ISYS_STUB -#define ISYS_STUB - -#ifndef GZLIB -#include <zlib.h> - -#define gunzip_open(x) gzopen(x, "r") -#define gunzip_dopen gzdopen(x, "r") -#define gunzip_close gzclose -#define gunzip_read gzread -#define gzip_write gzwrite -#define gzip_open(x, y, z) gzopen(x, "w") - -#else -#include "gzlib/gzlib.h" - -#endif - -#endif diff --git a/pyanaconda/isys/uncpio.c b/pyanaconda/isys/uncpio.c deleted file mode 100644 index 171eb6b..0000000 --- a/pyanaconda/isys/uncpio.c +++ /dev/null @@ -1,798 +0,0 @@ -/* - * uncpio.c - * - * Copyright (C) 2007 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#define HAVE_ALLOCA_H 1 -#define MAJOR_IN_SYSMACROS 1 - -#if HAVE_ALLOCA_H -# include <alloca.h> -#endif - -#define _(foo) (foo) - -#include <errno.h> -#include <fcntl.h> -#include <fnmatch.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <utime.h> - -#include "cpio.h" -#include "stubs.h" - -#if MAJOR_IN_SYSMACROS -#include <sys/sysmacros.h> -#elif MAJOR_IN_MKDEV -#include <sys/mkdev.h> -#endif - -#define CPIO_NEWC_MAGIC "070701" -#define CPIO_CRC_MAGIC "070702" -#define TRAILER "TRAILER!!!" - -/* FIXME: We don't translate between cpio and system mode bits! These - should both be the same, but really odd things are going to happen if - that's not true! */ - -/* We need to maintain our oun file pointer to allow padding */ -struct ourfd { - gzFile fd; - size_t pos; -}; - -struct hardLink { - struct hardLink * next; - char ** files; /* there are nlink of these, used by install */ - int * fileMaps; /* used by build */ - dev_t dev; - ino_t inode; - int nlink; - int linksLeft; - int createdPath; - struct stat sb; -}; - -struct cpioCrcPhysicalHeader { - char magic[6]; - char inode[8]; - char mode[8]; - char uid[8]; - char gid[8]; - char nlink[8]; - char mtime[8]; - char filesize[8]; - char devMajor[8]; - char devMinor[8]; - char rdevMajor[8]; - char rdevMinor[8]; - char namesize[8]; - char checksum[8]; /* ignored !! */ -}; - -#define PHYS_HDR_SIZE 110 /* don't depend on sizeof(struct) */ - -struct cpioHeader { - ino_t inode; - mode_t mode; - uid_t uid; - gid_t gid; - int nlink; - time_t mtime; - unsigned long size; - dev_t dev, rdev; - char * path; -}; - -static inline off_t ourread(struct ourfd * thefd, void * buf, size_t size) { - off_t i; - - i = gunzip_read(thefd->fd, buf, size); - thefd->pos += i; - - return i; -} - -static inline void padinfd(struct ourfd * fd, int modulo) { - int buf[10]; - int amount; - - amount = (modulo - fd->pos % modulo) % modulo; - ourread(fd, buf, amount); -} - -static inline int padoutfd(struct ourfd * fd, size_t * where, int modulo) { - /*static int buf[10] = { '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0' };*/ - int amount; - static int buf[512]; - - amount = (modulo - *where % modulo) % modulo; - *where += amount; - - if (gzip_write(fd->fd, buf, amount) != amount) - return CPIOERR_WRITE_FAILED; - - return 0; -} - -static int strntoul(const char * str, char ** endptr, int base, int num) { - char * buf, * end; - unsigned long ret; - - buf = alloca(num + 1); - strncpy(buf, str, num); - buf[num] = '\0'; - - ret = strtoul(buf, &end, base); - if (*end) - *endptr = (char *)(str + (end - buf)); /* XXX discards const */ - else - *endptr = ""; - - return strtoul(buf, endptr, base); -} - -#define GET_NUM_FIELD(phys, log) \ - log = strntoul(phys, &end, 16, sizeof(phys)); \ - if (*end) return CPIOERR_BAD_HEADER; -#define SET_NUM_FIELD(phys, val, space) \ - sprintf(space, "%8.8lx", (unsigned long) (val)); \ - memcpy(phys, space, 8); - -static int getNextHeader(struct ourfd * fd, struct cpioHeader * chPtr, - struct cpioCrcPhysicalHeader * physHeaderPtr) { - struct cpioCrcPhysicalHeader physHeader; - int nameSize; - char * end; - int major, minor; - - if (ourread(fd, &physHeader, PHYS_HDR_SIZE) != PHYS_HDR_SIZE) - return CPIOERR_READ_FAILED; - - if (physHeaderPtr) - memcpy(physHeaderPtr, &physHeader, PHYS_HDR_SIZE); - - if (strncmp(CPIO_CRC_MAGIC, physHeader.magic, strlen(CPIO_CRC_MAGIC)) && - strncmp(CPIO_NEWC_MAGIC, physHeader.magic, strlen(CPIO_NEWC_MAGIC))) - return CPIOERR_BAD_MAGIC; - - GET_NUM_FIELD(physHeader.inode, chPtr->inode); - GET_NUM_FIELD(physHeader.mode, chPtr->mode); - GET_NUM_FIELD(physHeader.uid, chPtr->uid); - GET_NUM_FIELD(physHeader.gid, chPtr->gid); - GET_NUM_FIELD(physHeader.nlink, chPtr->nlink); - GET_NUM_FIELD(physHeader.mtime, chPtr->mtime); - GET_NUM_FIELD(physHeader.filesize, chPtr->size); - - GET_NUM_FIELD(physHeader.devMajor, major); - GET_NUM_FIELD(physHeader.devMinor, minor); - chPtr->dev = makedev(major, minor); - - GET_NUM_FIELD(physHeader.rdevMajor, major); - GET_NUM_FIELD(physHeader.rdevMinor, minor); - chPtr->rdev = makedev(major, minor); - - GET_NUM_FIELD(physHeader.namesize, nameSize); - - chPtr->path = malloc(nameSize + 1); - if (ourread(fd, chPtr->path, nameSize) != nameSize) { - free(chPtr->path); - return CPIOERR_BAD_HEADER; - } - - /* this is unecessary chPtr->path[nameSize] = '\0'; */ - - padinfd(fd, 4); - - return 0; -} - -int myCpioFileMapCmp(const void * a, const void * b) { - const struct cpioFileMapping * first = a; - const struct cpioFileMapping * second = b; - - return (strcmp(first->archivePath, second->archivePath)); -} - -/* This could trash files in the path! I'm not sure that's a good thing */ -static int createDirectory(char * path, mode_t perms) { - struct stat sb; - int dounlink; - - if (!lstat(path, &sb)) { - if (S_ISDIR(sb.st_mode)) { - return 0; - } else if (S_ISLNK(sb.st_mode)) { - if (stat(path, &sb)) { - if (errno != ENOENT) - return CPIOERR_STAT_FAILED; - dounlink = 1; - } else { - if (S_ISDIR(sb.st_mode)) - return 0; - dounlink = 1; - } - } else { - dounlink = 1; - } - - if (dounlink && unlink(path)) { - return CPIOERR_UNLINK_FAILED; - } - } - - if (mkdir(path, 000)) - return CPIOERR_MKDIR_FAILED; - - if (chmod(path, perms)) - return CPIOERR_CHMOD_FAILED; - - return 0; -} - -static int setInfo(struct cpioHeader * hdr) { - int rc = 0; - struct utimbuf stamp; - - stamp.actime = hdr->mtime; - stamp.modtime = hdr->mtime; - - if (!S_ISLNK(hdr->mode)) { - if (!getuid() && chown(hdr->path, hdr->uid, hdr->gid)) - rc = CPIOERR_CHOWN_FAILED; - if (!rc && chmod(hdr->path, hdr->mode & 07777)) - rc = CPIOERR_CHMOD_FAILED; - if (!rc && utime(hdr->path, &stamp)) - rc = CPIOERR_UTIME_FAILED; - } else { -# if ! CHOWN_FOLLOWS_SYMLINK - if (!getuid() && !rc && lchown(hdr->path, hdr->uid, hdr->gid)) - rc = CPIOERR_CHOWN_FAILED; -# endif - } - - return rc; -} - -static int checkDirectory(char * filename) { - static char * lastDir = NULL; - static int lastDirLength = 0; - static int lastDirAlloced = 0; - int length = strlen(filename); - char * buf; - char * chptr; - int rc = 0; - - buf = alloca(length + 1); - strcpy(buf, filename); - - for (chptr = buf + length - 1; chptr > buf; chptr--) { - if (*chptr == '/') break; - } - - if (chptr == buf) return 0; /* /filename - no directories */ - - *chptr = '\0'; /* buffer is now just directories */ - - length = strlen(buf); - if (lastDirLength == length && !strcmp(buf, lastDir)) return 0; - - if (lastDirAlloced < (length + 1)) { - lastDirAlloced = length + 100; - lastDir = realloc(lastDir, lastDirAlloced); - } - - strcpy(lastDir, buf); - lastDirLength = length; - - for (chptr = buf + 1; *chptr; chptr++) { - if (*chptr == '/') { - *chptr = '\0'; - rc = createDirectory(buf, 0755); - *chptr = '/'; - if (rc) return rc; - } - } - rc = createDirectory(buf, 0755); - - return rc; -} - -static int expandRegular(struct ourfd * fd, struct cpioHeader * hdr, - cpioCallback cb, void * cbData) { - int out; - char buf[8192]; - int bytesRead; - unsigned long left = hdr->size; - int rc = 0; - struct cpioCallbackInfo cbInfo; - struct stat sb; - - if (!lstat(hdr->path, &sb)) - if (unlink(hdr->path)) - return CPIOERR_UNLINK_FAILED; - - out = open(hdr->path, O_CREAT | O_WRONLY, 0); - if (out < 0) - return CPIOERR_OPEN_FAILED; - - cbInfo.file = hdr->path; - cbInfo.fileSize = hdr->size; - - while (left) { - bytesRead = ourread(fd, buf, left < sizeof(buf) ? left : sizeof(buf)); - if (bytesRead <= 0) { - rc = CPIOERR_READ_FAILED; - break; - } - - if (write(out, buf, bytesRead) != bytesRead) { - rc = CPIOERR_COPY_FAILED; - break; - } - - left -= bytesRead; - - /* don't call this with fileSize == fileComplete */ - if (!rc && cb && left) { - cbInfo.fileComplete = hdr->size - left; - cbInfo.bytesProcessed = fd->pos; - cb(&cbInfo, cbData); - } - } - - close(out); - - return rc; -} - -static int expandSymlink(struct ourfd * fd, struct cpioHeader * hdr) { - char buf[2048], buf2[2048]; - struct stat sb; - int len; - - if ((hdr->size + 1)> sizeof(buf)) - return CPIOERR_INTERNAL; - - if (ourread(fd, buf, hdr->size) != hdr->size) - return CPIOERR_READ_FAILED; - - buf[hdr->size] = '\0'; - - if (!lstat(hdr->path, &sb)) { - if (S_ISLNK(sb.st_mode)) { - len = readlink(hdr->path, buf2, sizeof(buf2) - 1); - if (len > 0) { - buf2[len] = '\0'; - if (!strcmp(buf, buf2)) return 0; - } - } - - if (unlink(hdr->path)) - return CPIOERR_UNLINK_FAILED; - } - - if (symlink(buf, hdr->path) < 0) - return CPIOERR_SYMLINK_FAILED; - - return 0; -} - -static int expandFifo(struct ourfd * fd, struct cpioHeader * hdr) { - struct stat sb; - - if (!lstat(hdr->path, &sb)) { - if (S_ISFIFO(sb.st_mode)) return 0; - - if (unlink(hdr->path)) - return CPIOERR_UNLINK_FAILED; - } - - if (mkfifo(hdr->path, 0)) - return CPIOERR_MKFIFO_FAILED; - - return 0; -} - -static int expandDevice(struct ourfd * fd, struct cpioHeader * hdr) { - struct stat sb; - - if (!lstat(hdr->path, &sb)) { - if ((S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) && - (sb.st_rdev == hdr->rdev)) - return 0; - if (unlink(hdr->path)) - return CPIOERR_UNLINK_FAILED; - } - - if (mknod(hdr->path, hdr->mode & (~0777), hdr->rdev)) - return CPIOERR_MKNOD_FAILED; - - return 0; -} - -static void freeLink(struct hardLink * li) { - int i; - - for (i = 0; i < li->nlink; i++) { - if (li->files[i]) free(li->files[i]); - } - free(li->files); -} - -static int createLinks(struct hardLink * li, const char ** failedFile) { - int i; - struct stat sb; - - for (i = 0; i < li->nlink; i++) { - if (i == li->createdPath) continue; - if (!li->files[i]) continue; - - if (!lstat(li->files[i], &sb)) { - if (unlink(li->files[i])) { - *failedFile = strdup(li->files[i]); - return CPIOERR_UNLINK_FAILED; - } - } - - if (link(li->files[li->createdPath], li->files[i])) { - *failedFile = strdup(li->files[i]); - return CPIOERR_LINK_FAILED; - } - - free(li->files[i]); - li->files[i] = NULL; - li->linksLeft--; - } - - return 0; -} - -static int eatBytes(struct ourfd * fd, unsigned long amount) { - char buf[4096]; - unsigned long bite; - - while (amount) { - bite = (amount > sizeof(buf)) ? sizeof(buf) : amount; - if (ourread(fd, buf, bite) != bite) - return CPIOERR_READ_FAILED; - amount -= bite; - } - - return 0; -} - -int myCpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings, - int numMappings, cpioCallback cb, void * cbData, - const char ** failedFile) { - struct cpioHeader ch; - struct ourfd fd; - int rc = 0; - int linkNum = 0; - struct cpioFileMapping * map = NULL; - struct cpioFileMapping needle; - mode_t cpioMode; - int olderr; - struct cpioCallbackInfo cbInfo; - struct hardLink * links = NULL; - struct hardLink * li = NULL; - - fd.fd = stream; - fd.pos = 0; - - *failedFile = NULL; - - do { - if ((rc = getNextHeader(&fd, &ch, NULL))) { - fprintf(stderr, _("error %d reading header: %s\n"), rc, - myCpioStrerror(rc)); - return CPIOERR_BAD_HEADER; - } - - if (!strcmp(ch.path, TRAILER)) { - free(ch.path); - break; - } - - if (mappings) { - needle.archivePath = ch.path; - map = bsearch(&needle, mappings, numMappings, sizeof(needle), - myCpioFileMapCmp); - } - - if (mappings && !map) { - eatBytes(&fd, ch.size); - } else { - cpioMode = ch.mode; - - if (map) { - if (map->mapFlags & CPIO_MAP_PATH) { - free(ch.path); - ch.path = strdup(map->fsPath); - } - - if (map->mapFlags & CPIO_MAP_MODE) - ch.mode = map->finalMode; - if (map->mapFlags & CPIO_MAP_UID) - ch.uid = map->finalUid; - if (map->mapFlags & CPIO_MAP_GID) - ch.gid = map->finalGid; - } - - /* This won't get hard linked symlinks right, but I can't seem - to create those anyway */ - - if (S_ISREG(ch.mode) && ch.nlink > 1) { - li = links; - for (li = links; li; li = li->next) { - if (li->inode == ch.inode && li->dev == ch.dev) break; - } - - if (!li) { - li = malloc(sizeof(*li)); - li->inode = ch.inode; - li->dev = ch.dev; - li->nlink = ch.nlink; - li->linksLeft = ch.nlink; - li->createdPath = -1; - li->files = calloc(sizeof(char *), li->nlink); - li->next = links; - links = li; - } - - for (linkNum = 0; linkNum < li->nlink; linkNum++) - if (!li->files[linkNum]) break; - li->files[linkNum] = strdup(ch.path); - } - - if ((ch.nlink > 1) && S_ISREG(ch.mode) && !ch.size && - li->createdPath == -1) { - /* defer file creation */ - } else if ((ch.nlink > 1) && S_ISREG(ch.mode) && - (li->createdPath != -1)) { - createLinks(li, failedFile); - - /* this only happens for cpio archives which contain - hardlinks w/ the contents of each hardlink being - listed (intead of the data being given just once. This - shouldn't happen, but I've made it happen w/ buggy - code, so what the heck? GNU cpio handles this well fwiw */ - if (ch.size) eatBytes(&fd, ch.size); - } else { - rc = checkDirectory(ch.path); - - if (!rc) { - if (S_ISREG(ch.mode)) - rc = expandRegular(&fd, &ch, cb, cbData); - else if (S_ISDIR(ch.mode)) - rc = createDirectory(ch.path, 000); - else if (S_ISLNK(ch.mode)) - rc = expandSymlink(&fd, &ch); - else if (S_ISFIFO(ch.mode)) - rc = expandFifo(&fd, &ch); - else if (S_ISCHR(ch.mode) || S_ISBLK(ch.mode)) - rc = expandDevice(&fd, &ch); - else if (S_ISSOCK(ch.mode)) { - /* this mimicks cpio but probably isnt' right */ - rc = expandFifo(&fd, &ch); - } else { - rc = CPIOERR_INTERNAL; - } - } - - if (!rc) - rc = setInfo(&ch); - - if (S_ISREG(ch.mode) && ch.nlink > 1) { - li->createdPath = linkNum; - li->linksLeft--; - rc = createLinks(li, failedFile); - } - } - - if (rc && !*failedFile) { - *failedFile = strdup(ch.path); - - olderr = errno; - unlink(ch.path); - errno = olderr; - } - } - - padinfd(&fd, 4); - - if (!rc && cb) { - cbInfo.file = ch.path; - cbInfo.fileSize = ch.size; - cbInfo.fileComplete = ch.size; - cbInfo.bytesProcessed = fd.pos; - cb(&cbInfo, cbData); - } - - free(ch.path); - } while (1 && !rc); - - li = links; - while (li && !rc) { - if (li->linksLeft) { - if (li->createdPath == -1) - rc = CPIOERR_INTERNAL; - else - rc = createLinks(li, failedFile); - } - - freeLink(li); - - links = li; - li = li->next; - free(links); - links = li; - } - - li = links; - /* if an error got us here links will still be eating some memory */ - while (li) { - freeLink(li); - links = li; - li = li->next; - free(links); - } - - return rc; -} - -const char * myCpioStrerror(int rc) -{ - static char msg[256]; - char *s; - int l, myerrno = errno; - - strcpy(msg, "cpio: "); - switch (rc) { - default: - s = msg + strlen(msg); - sprintf(s, _("(error 0x%x)"), rc); - s = NULL; - break; - case CPIOERR_BAD_MAGIC: s = _("Bad magic"); break; - case CPIOERR_BAD_HEADER: s = _("Bad header"); break; - - case CPIOERR_OPEN_FAILED: s = "open"; break; - case CPIOERR_CHMOD_FAILED: s = "chmod"; break; - case CPIOERR_CHOWN_FAILED: s = "chown"; break; - case CPIOERR_WRITE_FAILED: s = "write"; break; - case CPIOERR_UTIME_FAILED: s = "utime"; break; - case CPIOERR_UNLINK_FAILED: s = "unlink"; break; - case CPIOERR_SYMLINK_FAILED: s = "symlink"; break; - case CPIOERR_STAT_FAILED: s = "stat"; break; - case CPIOERR_MKDIR_FAILED: s = "mkdir"; break; - case CPIOERR_MKNOD_FAILED: s = "mknod"; break; - case CPIOERR_MKFIFO_FAILED: s = "mkfifo"; break; - case CPIOERR_LINK_FAILED: s = "link"; break; - case CPIOERR_READLINK_FAILED: s = "readlink"; break; - case CPIOERR_READ_FAILED: s = "read"; break; - case CPIOERR_COPY_FAILED: s = "copy"; break; - - case CPIOERR_INTERNAL: s = _("Internal error"); break; - case CPIOERR_HDR_SIZE: s = _("Header size too big"); break; - case CPIOERR_UNKNOWN_FILETYPE: s = _("Unknown file type"); break; - } - - l = sizeof(msg) - strlen(msg) - 1; - if (s != NULL) { - if (l > 0) strncat(msg, s, l); - l -= strlen(s); - } - if (rc & CPIOERR_CHECK_ERRNO) { - s = _(" failed - "); - if (l > 0) strncat(msg, s, l); - l -= strlen(s); - if (l > 0) strncat(msg, strerror(myerrno), l); - } - return msg; -} - -static int copyFile(struct ourfd * inFd, struct ourfd * outFd, - struct cpioHeader * chp, struct cpioCrcPhysicalHeader * pHdr) { - char buf[8192]; - int amount; - size_t size = chp->size; - - amount = strlen(chp->path) + 1; - memcpy(pHdr->magic, CPIO_NEWC_MAGIC, sizeof(pHdr->magic)); - - gzip_write(outFd->fd, pHdr, PHYS_HDR_SIZE); - gzip_write(outFd->fd, chp->path, amount); - - outFd->pos += PHYS_HDR_SIZE + amount; - - padoutfd(outFd, &outFd->pos, 4); - - while (size) { - amount = ourread(inFd, buf, size > sizeof(buf) ? sizeof(buf) : size); - gzip_write(outFd->fd, buf, amount); - size -= amount; - } - - outFd->pos += chp->size; - - padoutfd(outFd, &outFd->pos, 4); - - return 0; -} - -int myCpioFilterArchive(gzFile inStream, gzFile outStream, char ** patterns) { - struct ourfd inFd, outFd; - char ** aPattern; - struct cpioHeader ch; - int rc; - struct cpioCrcPhysicalHeader pHeader; - - inFd.fd = inStream; - inFd.pos = 0; - outFd.fd = outStream; - outFd.pos = 0; - - do { - if ((rc = getNextHeader(&inFd, &ch, &pHeader))) { - fprintf(stderr, _("error %d reading header: %s\n"), rc, - myCpioStrerror(rc)); - return CPIOERR_BAD_HEADER; - } - - if (!strcmp(ch.path, TRAILER)) { - free(ch.path); - break; - } - - for (aPattern = patterns; *aPattern; aPattern++) - if (!fnmatch(*aPattern, ch.path, FNM_PATHNAME | FNM_PERIOD)) - break; - - if (!*aPattern) - eatBytes(&inFd, ch.size); - else - copyFile(&inFd, &outFd, &ch, &pHeader); - - padinfd(&inFd, 4); - - free(ch.path); - } while (1 && !rc); - - memset(&pHeader, '0', sizeof(pHeader)); - memcpy(pHeader.magic, CPIO_NEWC_MAGIC, sizeof(pHeader.magic)); - memcpy(pHeader.nlink, "00000001", 8); - memcpy(pHeader.namesize, "0000000b", 8); - gzip_write(outFd.fd, &pHeader, PHYS_HDR_SIZE); - gzip_write(outFd.fd, "TRAILER!!!", 11); - - outFd.pos += PHYS_HDR_SIZE + 11; - - if ((rc = padoutfd(&outFd, &outFd.pos, 4))) - return rc; - - if ((rc = padoutfd(&outFd, &outFd.pos, 512))) - return rc; - - return 0; -} diff --git a/pyanaconda/isys/vio.c b/pyanaconda/isys/vio.c deleted file mode 100644 index 9b06a3e..0000000 --- a/pyanaconda/isys/vio.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * vio.c - probing for vio devices on the iSeries (viocd and viodasd) - * - * Copyright (C) 2003 Red Hat, Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * Author(s): Jeremy Katz <katzj@xxxxxxxxxx> - */ - -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#if defined(__powerpc__) -static int readFD (int fd, char **buf) -{ - char *p; - size_t size = 4096; - int s, filesize; - - *buf = malloc (size); - if (*buf == 0) - return -1; - - filesize = 0; - do { - p = &(*buf) [filesize]; - s = read (fd, p, 4096); - if (s < 0) - break; - filesize += s; - if (s == 0) - break; - size += 4096; - *buf = realloc (*buf, size); - } while (1); - - if (filesize == 0 && s < 0) { - free (*buf); - *buf = NULL; - return -1; - } - - return filesize; -} -#endif - -int isVioConsole(void) { -#if !defined(__powerpc__) - return 0; -#else - int fd, i; - char *buf, *start; - char driver[50], device[50]; - static int isviocons = -1; - - if (isviocons != -1) - return isviocons; - - fd = open("/proc/tty/drivers", O_RDONLY); - if (fd < 0) { - fprintf(stderr, "failed to open /proc/tty/drivers!\n"); - return 0; - } - i = readFD(fd, &buf); - if (i < 1) { - close(fd); - fprintf(stderr, "error reading /proc/tty/drivers!\n"); - return 0; - } - close(fd); - buf[i] = '\0'; - - isviocons = 0; - start = buf; - while (start && *start) { - if (sscanf(start, "%s %s", (char *) &driver, (char *) &device) == 2) { - if (!strcmp(driver, "vioconsole") && !strcmp(device, "/dev/tty")) { - isviocons = 1; - break; - } - } - start = strchr(start, '\n'); - if (start) - start++; - } - free(buf); - return isviocons; -#endif -} diff --git a/scripts/getlangnames.py b/scripts/getlangnames.py index b25db83..5af8d0f 100644 --- a/scripts/getlangnames.py +++ b/scripts/getlangnames.py @@ -19,7 +19,7 @@ import sys sys.path.append("..") -import language +import pyanaconda.language as language import gettext diff --git a/tests/Makefile.am b/tests/Makefile.am index a348364..6ee2cea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -19,6 +19,4 @@ SUBDIRS = mock kickstart_test storage_test -EXTRA_DIST = *.py - MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/mock/Makefile.am b/tests/mock/Makefile.am index ce35c64..87ebd00 100644 --- a/tests/mock/Makefile.am +++ b/tests/mock/Makefile.am @@ -17,8 +17,5 @@ # # Author: David Cantrell <dcantrell@xxxxxxxxxx> -SUBDIRS = - EXTRA_DIST = *.py - MAINTAINERCLEANFILES = Makefile.in diff --git a/tests/storage_test/Makefile.am b/tests/storage_test/Makefile.am index 23565ab..51bb6af 100644 --- a/tests/storage_test/Makefile.am +++ b/tests/storage_test/Makefile.am @@ -19,6 +19,5 @@ SUBDIRS = devicelibs_test -EXTRA_DIST = *.py MAINTAINERCLEANFILES = Makefile.in diff --git a/utils/Makefile.am b/utils/Makefile.am index d11b805..2955485 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -28,8 +28,8 @@ if IS_S390 utils_PROGRAMS += addrsize mk-s390-cdboot endif -modlist_CFLAGS = -I$(top_srcdir)/loader $(GLIB_CFLAGS) +modlist_CFLAGS = -I$(top_srcdir)/bin/loader $(GLIB_CFLAGS) modlist_LDADD = $(GLIB_LIBS) -modlist_SOURCES = modlist.c $(top_srcdir)/loader/moduleinfo.c +modlist_SOURCES = modlist.c $(top_srcdir)/bin/loader/moduleinfo.c MAINTAINERCLEANFILES = Makefile.in diff --git a/utils/mapshdr.c b/utils/mapshdr.c index f2209c7..7817ef4 100644 --- a/utils/mapshdr.c +++ b/utils/mapshdr.c @@ -24,7 +24,7 @@ #include <sys/stat.h> #include <unistd.h> -#include "../isys/lang.h" +#include "../bin/isys/lang.h" int main(int argc, char ** argv) { struct kmapHeader h; diff --git a/utils/modlist.c b/utils/modlist.c index 7aff567..418bf97 100644 --- a/utils/modlist.c +++ b/utils/modlist.c @@ -22,7 +22,7 @@ #include <string.h> #include <glib.h> -#include "../isys/isys.h" +#include "../bin/isys/isys.h" #include "moduleinfo.h" int main(int argc, char ** argv) { diff --git a/utils/readmap.c b/utils/readmap.c index 7d65636..f506e7e 100644 --- a/utils/readmap.c +++ b/utils/readmap.c @@ -32,7 +32,7 @@ #include <stdlib.h> #include <unistd.h> -#include "../isys/lang.h" +#include "../bin/isys/lang.h" int main(int argc, char ** argv) { int console; -- 1.6.6.1 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list