[Debootloaders-devel] r164 - in trunk: . powerpc-ibm-utils
powerpc-ibm-utils/cmds powerpc-ibm-utils/doc
powerpc-ibm-utils/doc/nvram powerpc-ibm-utils/scripts
Aurélien GÉRÔME
ag-guest at costa.debian.org
Mon Sep 25 09:08:45 UTC 2006
Author: ag-guest
Date: 2006-09-25 09:08:44 +0000 (Mon, 25 Sep 2006)
New Revision: 164
Added:
trunk/powerpc-ibm-utils/
trunk/powerpc-ibm-utils/COPYRIGHT
trunk/powerpc-ibm-utils/Changelog
trunk/powerpc-ibm-utils/Makefile
trunk/powerpc-ibm-utils/README
trunk/powerpc-ibm-utils/cmds/
trunk/powerpc-ibm-utils/cmds/Makefile
trunk/powerpc-ibm-utils/cmds/nvram.c
trunk/powerpc-ibm-utils/cmds/nvram.h
trunk/powerpc-ibm-utils/doc/
trunk/powerpc-ibm-utils/doc/Makefile
trunk/powerpc-ibm-utils/doc/bootlist.8
trunk/powerpc-ibm-utils/doc/nvram/
trunk/powerpc-ibm-utils/doc/nvram/Makefile
trunk/powerpc-ibm-utils/doc/nvram/nvram.8
trunk/powerpc-ibm-utils/doc/nvram/nvram.doxycfg
trunk/powerpc-ibm-utils/doc/ofpathname.8
trunk/powerpc-ibm-utils/doc/snap.8
trunk/powerpc-ibm-utils/powerpc-utils.spec
trunk/powerpc-ibm-utils/rules.mk
trunk/powerpc-ibm-utils/scripts/
trunk/powerpc-ibm-utils/scripts/Makefile
trunk/powerpc-ibm-utils/scripts/bootlist
trunk/powerpc-ibm-utils/scripts/ofpathname
trunk/powerpc-ibm-utils/scripts/snap
Log:
Initial import of upstream tarball.
Added: trunk/powerpc-ibm-utils/COPYRIGHT
===================================================================
--- trunk/powerpc-ibm-utils/COPYRIGHT (rev 0)
+++ trunk/powerpc-ibm-utils/COPYRIGHT 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,228 @@
+Common Public License - v 1.0
+
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON
+PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF
+THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and
+documentation distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+i) changes to the Program, and
+ii) additions to the Program;
+where such changes and/or additions to the Program originate from and are
+distributed by that particular Contributor. A Contribution 'originates'
+from a Contributor if it was added to the Program by such Contributor
+itself or anyone acting on such Contributor's behalf. Contributions do
+not include additions to the Program which: (i) are separate modules of
+software distributed in conjunction with the Program under their own
+license agreement, and (ii) are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+
+"Licensed Patents " mean patent claims licensable by a Contributor which
+are necessarily infringed by the use or sale of its Contribution alone or
+when combined with the Program.
+
+
+"Program" means the Contributions distributed in accordance with this
+Agreement.
+
+
+"Recipient" means anyone who receives the Program under this Agreement,
+including all Contributors.
+
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free copyright license to
+reproduce, prepare derivative works of, publicly display, publicly
+perform, distribute and sublicense the Contribution of such Contributor,
+if any, and such derivative works, in source code and object code form.
+b) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free patent license under
+Licensed Patents to make, use, sell, offer to sell, import and otherwise
+transfer the Contribution of such Contributor, if any, in source code and
+object code form. This patent license shall apply to the combination of
+the Contribution and the Program if, at the time the Contribution is
+added by the Contributor, such addition of the Contribution causes such
+combination to be covered by the Licensed Patents. The patent license
+shall not apply to any other combinations which include the Contribution.
+No hardware per se is licensed hereunder.
+c) Recipient understands that although each Contributor grants the
+licenses to its Contributions set forth herein, no assurances are
+provided by any Contributor that the Program does not infringe the patent
+or other intellectual property rights of any other entity. Each
+Contributor disclaims any liability to Recipient for claims brought by
+any other entity based on infringement of intellectual property rights or
+otherwise. As a condition to exercising the rights and licenses granted
+hereunder, each Recipient hereby assumes sole responsibility to secure
+any other intellectual property rights needed, if any. For example, if a
+third party patent license is required to allow Recipient to distribute
+the Program, it is Recipient's responsibility to acquire that license
+before distributing the Program.
+d) Each Contributor represents that to its knowledge it has sufficient
+copyright rights in its Contribution, if any, to grant the copyright
+license set forth in this Agreement.
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form
+under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+b) its license agreement:
+i) effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of
+title and non-infringement, and implied warranties or conditions of
+merchantability and fitness for a particular purpose;
+ii) effectively excludes on behalf of all Contributors all liability for
+damages, including direct, indirect, special, incidental and
+consequential damages, such as lost profits;
+iii) states that any provisions which differ from this Agreement are
+offered by that Contributor alone and not by any other party; and
+iv) states that source code for the Program is available from such
+Contributor, and informs licensees how to obtain it in a reasonable
+manner on or through a medium customarily used for software exchange.
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+b) a copy of this Agreement must be included with each copy of the
+Program.
+
+Contributors may not remove or alter any copyright notices contained
+within the Program.
+
+
+Each Contributor must identify itself as the originator of its
+Contribution, if any, in a manner that reasonably allows subsequent
+Recipients to identify the originator of the Contribution.
+
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities
+with respect to end users, business partners and the like. While this
+license is intended to facilitate the commercial use of the Program, the
+Contributor who includes the Program in a commercial product offering
+should do so in a manner which does not create potential liability for
+other Contributors. Therefore, if a Contributor includes the Program in a
+commercial product offering, such Contributor ("Commercial Contributor")
+hereby agrees to defend and indemnify every other Contributor
+("Indemnified Contributor") against any losses, damages and costs
+(collectively "Losses") arising from claims, lawsuits and other legal
+actions brought by a third party against the Indemnified Contributor to
+the extent caused by the acts or omissions of such Commercial Contributor
+in connection with its distribution of the Program in a commercial
+product offering. The obligations in this section do not apply to any
+claims or Losses relating to any actual or alleged intellectual property
+infringement. In order to qualify, an Indemnified Contributor must: a)
+promptly notify the Commercial Contributor in writing of such claim, and
+b) allow the Commercial Contributor to control, and cooperate with the
+Commercial Contributor in, the defense and any related settlement
+negotiations. The Indemnified Contributor may participate in any such
+claim at its own expense.
+
+
+For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those performance
+claims and warranties, and if a court requires any other Contributor to
+pay any damages as a result, the Commercial Contributor must pay those
+damages.
+
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED
+ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
+EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
+CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
+PARTICULAR PURPOSE. Each Recipient is solely responsible for determining
+the appropriateness of using and distributing the Program and assumes all
+risks associated with its exercise of rights under this Agreement,
+including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs or
+equipment, and unavailability or interruption of operations.
+
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
+ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
+DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of the
+remainder of the terms of this Agreement, and without further action by
+the parties hereto, such provision shall be reformed to the minimum
+extent necessary to make such provision valid and enforceable.
+
+
+If Recipient institutes patent litigation against a Contributor with
+respect to a patent applicable to software (including a cross-claim or
+counterclaim in a lawsuit), then any patent licenses granted by that
+Contributor to such Recipient under this Agreement shall terminate as of
+the date such litigation is filed. In addition, if Recipient institutes
+patent litigation against any entity (including a cross-claim or
+counterclaim in a lawsuit) alleging that the Program itself (excluding
+combinations of the Program with other software or hardware) infringes
+such Recipient's patent(s), then such Recipient's rights granted under
+Section 2(b) shall terminate as of the date such litigation is filed.
+
+
+All Recipient's rights under this Agreement shall terminate if it fails
+to comply with any of the material terms or conditions of this Agreement
+and does not cure such failure in a reasonable period of time after
+becoming aware of such noncompliance. If all Recipient's rights under
+this Agreement terminate, Recipient agrees to cease use and distribution
+of the Program as soon as reasonably practicable. However, Recipient's
+obligations under this Agreement and any licenses granted by Recipient
+relating to the Program shall continue and survive.
+
+
+Everyone is permitted to copy and distribute copies of this Agreement,
+but in order to avoid inconsistency the Agreement is copyrighted and may
+only be modified in the following manner. The Agreement Steward reserves
+the right to publish new versions (including revisions) of this Agreement
+from time to time. No one other than the Agreement Steward has the right
+to modify this Agreement. IBM is the initial Agreement Steward. IBM may
+assign the responsibility to serve as the Agreement Steward to a suitable
+separate entity. Each new version of the Agreement will be given a
+distinguishing version number. The Program (including Contributions) may
+always be distributed subject to the version of the Agreement under which
+it was received. In addition, after a new version of the Agreement is
+published, Contributor may elect to distribute the Program (including its
+Contributions) under the new version. Except as expressly stated in
+Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement,
+whether expressly, by implication, estoppel or otherwise. All rights in
+the Program not expressly granted under this Agreement are reserved.
+
+
+This Agreement is governed by the laws of the State of New York and the
+intellectual property laws of the United States of America. No party to
+this Agreement will bring a legal action under this Agreement more than
+one year after the cause of action arose. Each party waives its rights to
+a jury trial in any resulting litigation.
+
+
+
Added: trunk/powerpc-ibm-utils/Changelog
===================================================================
--- trunk/powerpc-ibm-utils/Changelog (rev 0)
+++ trunk/powerpc-ibm-utils/Changelog 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,20 @@
+Changelog for powerpc-utils-1.0.2
+=======================================
+ - Updated bootlist so that eth devices don't require any options
+
+Changelog for powerpc-utils-1.0.1
+=======================================
+ - ofpathanme: Updated the virtual disk number calculation for scsi
+ devices.
+
+Changelog for powerpc-utils-1.0.0
+=======================================
+ - Added devball target for builds.
+
+Changelog for powerpc-utils-0.0.1
+=======================================
+ - Initial creation of powerpc-utils package.
+ - nvram command now defaults to the "common" partition.
+ - Corrected the parsing of optional ethernet args to the
+ bootlist command.
+
Added: trunk/powerpc-ibm-utils/Makefile
===================================================================
--- trunk/powerpc-ibm-utils/Makefile (rev 0)
+++ trunk/powerpc-ibm-utils/Makefile 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,49 @@
+#
+# Makefile for powerpc-utils
+#
+
+include rules.mk
+
+.SILENT:
+
+FILES = README COPYRIGHT
+SUBDIRS = cmds scripts doc
+
+TARBALL_FILES += $(FILES) Changelog
+
+all:
+ @echo "Building cmds files..."
+ @$(MAKE) -C cmds
+ @echo "Building scripts files..."
+ @$(MAKE) -C scripts
+ @echo "Building doc files..."
+ @$(MAKE) -C doc
+
+install: all
+ @$(call install_doc,$(FILES),$(DESTDIR))
+ @$(foreach d,$(SUBDIRS), $(MAKE) -C $d install;)
+
+uninstall:
+ @$(call uninstall_doc,$(FILES),$(DESTDIR))
+ @$(foreach d,$(SUBDIRS), $(MAKE) -C $d uninstall;)
+
+rpm: all
+ @echo "Creating rpm..."
+ @export DESTDIR=$(SHIPDIR); $(MAKE) install
+ @$(RPM) -bb -v $(SPECFILE)
+ @rm -rf $(SHIPDIR)
+
+docs:
+ @$(MAKE) -C doc docs
+
+tarball: clean
+ @echo "Creating release tarball..."
+ @$(BUILD_TARBALL)
+
+devball: clean
+ @echo "Creating snapshot tarball..."
+ @$(BUILD_DEVBALL)
+
+clean:
+ @$(foreach d,$(SUBDIRS), $(MAKE) -C $d clean;)
+ @$(CLEAN) -rf $(SHIPDIR) $(TARBALL) $(DEVBALL) *~
Added: trunk/powerpc-ibm-utils/README
===================================================================
--- trunk/powerpc-ibm-utils/README (rev 0)
+++ trunk/powerpc-ibm-utils/README 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,33 @@
+powerpc-utils package
+===================
+
+This package contains utilities intended for maintenance of powerpc platforms.
+All of these utilities must be run as root.
+
+Further documentation for each of these utilities is available in their
+corresponding man pages.
+
+snap: system configuration snapshot
+----
+A script to gather significant system configuration information. The
+script creates snap.tar.gz in the working directory; the contents of
+this file can be used for problem determination by servicers of the
+system.
+
+nvram: NVRAM access utility
+-----
+A utility to view and format the contents of the system's non-volatile
+RAM, which contains configuration variables for Open Firmware and the
+system's Service Processor (if any), as well as error records and Vital
+Product Data (VPD).
+
+bootlist: boot configuration utility
+--------
+A script to view and set the list of devices with which the system will
+attempt to boot. Both the "normal" and "service" mode lists can be
+manipulated.
+
+ofpathname: translate logical device names to OF names
+----------
+Used by bootlist to convert between Linux logical device names and Open
+Firmware names.
Added: trunk/powerpc-ibm-utils/cmds/Makefile
===================================================================
--- trunk/powerpc-ibm-utils/cmds/Makefile (rev 0)
+++ trunk/powerpc-ibm-utils/cmds/Makefile 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,23 @@
+#
+# Makefile for powerpc-utils/cmds
+#
+
+include ../rules.mk
+
+CMDS = nvram
+
+all: $(CMDS)
+
+nvram: nvram.o
+ @echo "LD $(WORK_DIR)/$@"
+ @$(CC) -o $@ $^ -ldl
+
+install: all
+ @$(call install_sbin,$(CMDS),$(DESTDIR))
+
+uninstall:
+ @$(call uninstall_sbin,$(CMDS),$(DESTDIR))
+
+clean:
+ @echo "Cleaning up $(WORK_DIR) files..."
+ @rm -f $(CMDS) *.o *~
Added: trunk/powerpc-ibm-utils/cmds/nvram.c
===================================================================
--- trunk/powerpc-ibm-utils/cmds/nvram.c (rev 0)
+++ trunk/powerpc-ibm-utils/cmds/nvram.c 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,1649 @@
+/**
+ * @file nvram.c
+ * @brief nvram access utility for powerpc platforms.
+ */
+/**
+ * @mainpage nvram documentation
+ * @section Copyright
+ * Copyright (c) 2003, 2004, 2005 International Business Machines
+ * Common Public License Version 1.0 (see COPYRIGHT)
+ *
+ * @section Overview
+ * The nvram command is used to print and modify data stored in the
+ * non-volatile RAM (NVRAM) on powerpc systems. NVRAM on powerpc systems
+ * is split into several partitions, each with their own format.
+ *
+ * The print options allow you to view the available partitions in NVRAM
+ * and print their contents.
+ *
+ * The update options allow you to update certain partitions of NVRAM,
+ * namely those containing name=value pairs. On many systems, the
+ * following NVRAM partitions contain data formatted as name=value pairs:
+ * common, of-config, and ibm,setupcfg.
+ *
+ * @author Nathan Fontenot <nfont at austin.ibm.com>
+ * @author Michael Strosaker <strosake at us.ibm.com>
+ * @author Todd Inglett <tinglett at us.ibm.com>
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <stdint.h>
+#include <dlfcn.h>
+#include <netinet/in.h> /* for ntohs */
+#include <glob.h>
+#include <getopt.h>
+
+#include "nvram.h"
+
+/**
+ * @var nvram_cmdname
+ * @brief name used to invoke thre nvram command (argv[0])
+ */
+char *nvram_cmdname;
+static int verbose;
+
+static struct option long_options[] = {
+ {"verbose", optional_argument, NULL, 'v'},
+ {"print-config", optional_argument, NULL, 'o'},
+ {"print-vpd", optional_argument, NULL, 'V'},
+ {"print-all-vpd", optional_argument, NULL, 'W'},
+ {"print-err-log", no_argument, NULL, 'e'},
+ {"print-event-scan", no_argument, NULL, 'E'},
+ {"partitions", no_argument, NULL, 'P'},
+ {"dump", required_argument, NULL, 'd'},
+ {"nvram-file", required_argument, NULL, 'n'},
+ {"nvram-size", required_argument, NULL, 's'},
+ {"update-config", required_argument, NULL, 'u'},
+ {"help", no_argument, NULL, 'h'},
+ {"partition", required_argument, NULL, 'p'},
+ {0,0,0,0}
+};
+
+/**
+ * help
+ * @brief print the help/usage message for nvram
+ */
+static void
+help(void)
+{
+ printf("nvram options:\n"
+ " --print-config[=var]\n"
+ " print value of a config variable, or print all variables in\n"
+ " the specified (or all) partitions\n"
+ " --update-config <var>=<value>\n"
+ " update the config variable in the specified partition; the -p\n"
+ " option must also be specified\n"
+ " -p <partition>\n"
+ " specify a partition; required with --update-config option,\n"
+ " optional with --print-config option\n"
+ " --print-vpd\n"
+ " print VPD\n"
+ " --print-all-vpd\n"
+ " print VPD, including vendor specific data\n"
+ " --print-err-log\n"
+ " print checkstop error log\n"
+ " --print-event-scan\n"
+ " print event scan log\n"
+ " --partitions\n"
+ " print NVRAM paritition header info\n"
+ " --dump <name>\n"
+ " raw dump of partition (use --partitions to see names)\n"
+ " --nvram-file <path>\n"
+ " specify alternate nvram data file (default is /dev/nvram)\n"
+ " --nvram-size\n"
+ " specify size of nvram data (for repair operations)\n"
+ " --verbose (-v)\n"
+ " be (more) verbose\n"
+ " --help\n"
+ " print what you are reading right now.\n"
+ );
+}
+
+/**
+ * @def ERR_MSG
+ * @brief define to denote error messages
+ */
+#define ERR_MSG 0
+/**
+ * @def WARN_MSG
+ * @brief define to denote warning messages
+ */
+#define WARN_MSG 1
+/**
+ * @def MAXLINE
+ * @brief maximum line length
+ */
+#define MAXLINE 4096
+
+/**
+ * _msg
+ * @brief print a message to stderr with the specified prefix
+ *
+ * @param msg_type either ERR_MSG or WARN_MSG
+ * @param fmt formatted string a la printf()
+ * @param ap initialized varaiable arg list
+ */
+void
+_msg(int msg_type, const char *fmt, va_list ap)
+{
+ int n;
+ char buf[MAXLINE];
+
+ n = sprintf(buf, "%s: %s", nvram_cmdname,
+ (msg_type == WARN_MSG ? "WARNING: " : "ERROR: "));
+
+ vsprintf(buf + n, fmt, ap);
+
+ fflush(stderr);
+ fputs(buf, stderr);
+ fflush(NULL);
+}
+
+/**
+ * err_msg
+ * @brief print an error message to stderr
+ *
+ * @param fmt formatted string a la printf()
+ */
+void err_msg(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
+void
+err_msg(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ _msg(ERR_MSG, fmt, ap);
+ va_end(ap);
+}
+
+/**
+ * warn_msg
+ * @brief print a warning message to stderr
+ *
+ * @param fmt formatted string a la printf()
+ */
+void warn_msg(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
+void
+warn_msg(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ _msg(WARN_MSG, fmt, ap);
+ va_end(ap);
+}
+
+/**
+ * resolve_of_node
+ * @brief resolve an Open Firmware node name
+ *
+ * In a device tree node with a single child, "foo at 0", all of the following
+ * names refer to that child: "foo at 0", "foo", "@0".
+ *
+ * @param parent fully-qualified path to the parent device node
+ * @param node the (possibly abbreviated) name of the child node
+ * @param nodelen length of the node parameter
+ * @param resolved pointer to return resolved node name in
+ * @return 0 if a suitable child can be found, and 'resolved' is a
+ * dynamically-allocated string containing the resolved node name.
+ * Otherwise, -1.
+ */
+static int
+resolve_of_node(const char *parent, const char *node, int nodelen,
+ char **resolved)
+{
+ static char nodebuf[1024]; /* XXX hardcoded length */
+ struct stat sbuf;
+ glob_t pglob;
+ int rc;
+
+ *resolved = NULL;
+
+ snprintf(nodebuf, sizeof(nodebuf), "%s/%.*s", parent,
+ nodelen, node);
+ rc = stat(nodebuf, &sbuf);
+ if (rc != -1) {
+ *resolved = malloc(nodelen+2);
+ snprintf(*resolved, nodelen+2, "/%.*s", nodelen, node);
+ goto out;
+ }
+ if (errno != ENOENT)
+ goto out; /* report unusual errors */
+
+ if (node[0] == '@') {
+ /* it's a unit address; glob for *@unitaddr */
+ snprintf(nodebuf, sizeof(nodebuf), "%s/*%.*s*", parent, nodelen, node);
+ rc = glob(nodebuf, 0, NULL, &pglob);
+ if (rc == 0) {
+ if (pglob.gl_pathc > 1) {
+ err_msg("Ambiguous node name \"%.*s\"\n", nodelen, node);
+ while (pglob.gl_pathc) {
+ free(pglob.gl_pathv[pglob.gl_pathc]);
+ pglob.gl_pathc--;
+ }
+ goto out;
+ }
+
+ /* skip the leading fully-qualified path */
+ *resolved = strdup(pglob.gl_pathv[0] + strlen(parent));
+ free(pglob.gl_pathv[0]);
+ goto out;
+ }
+ } else {
+ /* must be a node name; glob for node@* */
+ snprintf(nodebuf, sizeof(nodebuf), "%s/%.*s@*", parent, nodelen, node);
+ rc = glob(nodebuf, 0, NULL, &pglob);
+ if (rc == 0) {
+ if (pglob.gl_pathc > 1) {
+ err_msg("Ambiguous node name \"%.*s\"\n", nodelen, node);
+ while (pglob.gl_pathc) {
+ free(pglob.gl_pathv[pglob.gl_pathc]);
+ pglob.gl_pathc--;
+ }
+ goto out;
+ }
+
+ /* skip the leading fully-qualified path */
+ *resolved = strdup(pglob.gl_pathv[0] + strlen(parent));
+ free(pglob.gl_pathv[0]);
+ goto out;
+ }
+ }
+
+out:
+ if (*resolved != NULL)
+ return 0;
+ return -1;
+}
+
+/**
+ * open_of_path
+ * @brief open an Open Firmware path under DEVICE_TREE
+ *
+ * @param ofpath the path to open, such as "/pci/@d/mac-io/nvram/#bytes"
+ *
+ * An Open Firmware path may contain "shortcut" node names that are not present
+ * under /proc/device-tree. In the above example, we may need to open
+ * "pci at 80000000" instead of "pci".
+ *
+ * @return file descriptor to the opened node, or -1 on failure
+ */
+static int
+open_of_path(const char *ofpath)
+{
+ static char resolved_ofpath[1024]; /* XXX hardcoded length */
+ const char *node;
+ int fd = -1;
+ int rc = 0;
+
+ strcpy(resolved_ofpath, DEVICE_TREE);
+
+ while (ofpath) {
+ int nodelen;
+ char *resolved_node;
+
+ node = ofpath + 1;
+ ofpath = strchr(node + 1, '/');
+
+ nodelen = ofpath - node;
+ if (ofpath == NULL)
+ nodelen = strlen(node);
+
+ rc = resolve_of_node(resolved_ofpath, node, nodelen, &resolved_node);
+ if (rc < 0)
+ break;
+
+ strcat(resolved_ofpath, resolved_node);
+ free(resolved_node);
+ }
+
+ if (rc >= 0)
+ fd = open(resolved_ofpath, O_RDONLY);
+
+ return fd;
+}
+
+/**
+ * get_of_nvram_size
+ * @brief Get the size of nvram from the device tree
+ *
+ * Retrieve the size of nvram as specified by the Open Firmware
+ * device tree. If this fails we return a default size of
+ * 1024 * 1024.
+ *
+ * @return size of nvram
+ */
+static int
+get_of_nvram_size(void)
+{
+ char buf[1024] = NVRAM_DEFAULT "/#bytes";
+ int fd;
+ int size, len;
+
+ fd = open(buf, O_RDONLY);
+ if (fd == -1) {
+ /* Check the aliases directory */
+ struct stat sbuf;
+ int offset;
+
+ fd = open(NVRAM_ALIAS, O_RDONLY);
+ if (fd == -1) {
+ err_msg("%s", "Could not determine nvram size from "
+ NVRAM_ALIAS "\n");
+ return DEFAULT_NVRAM_SZ;
+ }
+
+ if (fstat(fd, &sbuf) != 0) {
+ err_msg("%s", "Could not determine nvram size from "
+ NVRAM_ALIAS "\n");
+ close(fd);
+ return DEFAULT_NVRAM_SZ;
+ }
+
+ offset = read(fd, buf, sbuf.st_size - 1);
+ offset += sprintf(buf + offset, "%s", "/#bytes");
+ buf[offset] = '\0';
+
+ close(fd);
+ fd = open_of_path(buf);
+ }
+
+ if (fd == -1) {
+ warn_msg("cannot open nvram node \"%s\" in device tree: %s\n", buf,
+ strerror(errno));
+ close(fd);
+ return DEFAULT_NVRAM_SZ;
+ }
+
+ len = read(fd, &size, sizeof(size));
+ close(fd);
+
+ if (len != sizeof(size)) {
+ perror("got odd size for nvram node in device tree");
+ return DEFAULT_NVRAM_SZ;
+ }
+
+ return size;
+}
+
+/**
+ * nvram_read
+ * @brief read in the contents of nvram
+ *
+ * @param nvram nvram struct to read data into
+ * @return 0 on success, !0 on failure
+ */
+int
+nvram_read(struct nvram *nvram)
+{
+ int len, remaining;
+ char *p;
+
+ /* read in small chunks */
+ for (p = nvram->data, remaining = nvram->nbytes;
+ (len = read(nvram->fd, p, 512)) > 0;
+ p += len, remaining -= len) {
+ if (remaining <= 0) {
+ remaining = 0;
+ break;
+ }
+ }
+
+ if (len == -1) {
+ err_msg("cannot read \"%s\": %s\n", nvram->filename, strerror(errno));
+ return -1;
+ }
+
+ /* If we are using the DEFAULT_NVRAM_SZ value we to do a small bit of
+ * fixup here. All of the remaining code assumes that nbytes contains
+ * the actual size of nvram, not a guess-timated amount and bad things
+ * ensue if it is not correct.
+ */
+ if (nvram->nbytes == DEFAULT_NVRAM_SZ) {
+ nvram->nbytes = nvram->nbytes - remaining;
+ remaining = DEFAULT_NVRAM_SZ - (remaining + nvram->nbytes);
+ }
+
+ if (remaining) {
+ warn_msg("expected %d bytes, but only read %d!\n",
+ nvram->nbytes, nvram->nbytes - remaining);
+ /* preserve the given nbytes, but zero the rest in case someone cares */
+ memset(p, 0, remaining);
+ }
+
+ if (verbose)
+ printf("NVRAM size %d bytes\n", nvram->nbytes);
+
+ return 0;
+}
+
+/**
+ * checksum
+ * @brief calculate the checksum for a partition header
+ *
+ * @param p pointer to partition header
+ * @return calculated checksum
+ */
+static unsigned char
+checksum(struct partition_header *p)
+{
+ unsigned int c_sum, c_sum2;
+ unsigned short *sp = (unsigned short *)p->name; /* assume 6 shorts */
+
+ c_sum = p->signature + p->length + sp[0] + sp[1] + sp[2] + sp[3]
+ + sp[4] + sp[5];
+
+ /* The sum probably may have spilled into the 3rd byte. Fold it back. */
+ c_sum = ((c_sum & 0xffff) + (c_sum >> 16)) & 0xffff;
+
+ /* The sum cannot exceed 2 bytes. Fold it into a checksum */
+ c_sum2 = (c_sum >> 8) + (c_sum << 8);
+ c_sum = ((c_sum + c_sum2) >> 8) & 0xff;
+
+ return c_sum;
+}
+
+/**
+ * dump_raw_data
+ * @brief raw data dump of a partition.
+ *
+ * Note that data_len must be a multiple of 16 bytes which makes
+ * for a cheap implementation.
+ *
+ * @param data pointer to data to be dumped
+ * @param data_len length of data buffer to be dumped
+ */
+void
+dump_raw_data(char *data, int data_len)
+{
+ int i, j;
+ int offset = 0;
+ char *h, *a;
+ char *end = data + data_len;
+
+ h = a = data;
+
+ while (h < end) {
+ printf("0x%08x ", offset);
+ offset += 16;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ if (h <= end)
+ printf("%02x", *h++);
+ else
+ printf(" ");
+ }
+ printf(" ");
+ }
+
+ printf("|");
+
+ for (i = 0; i < 16; i++) {
+ if (a <= end) {
+ if ((*a >= ' ') && (*a <= '~'))
+ printf("%c", *a);
+ else
+ printf(".");
+ a++;
+ } else
+ printf(" ");
+ }
+ printf("|\n");
+ }
+}
+
+/**
+ * parse_of_common
+ * @brief parse a config definition
+ *
+ * Parse an Open Firmware common config definition which
+ * is of the form name=value and return its length.
+ *
+ * Note that the name will always be < 32 chars. OF does
+ * not specify the max value length, but the value is binary
+ * and must be unquoted. We assume 4k is enough.
+ *
+ * @param data pointer to start of raw data (NULL terminated)
+ * @param data_len length of remaining raw data
+ * @param outname buffer to write parsed name
+ * @param outval buffer to write parsed output value
+ * @return number of bytes parsed
+ */
+int
+parse_of_common(char *data, int data_len, char *outname, char *outval)
+{
+ char *p, *np;
+ char *p_end = data + data_len;
+
+ for (p = data, np = outname; *p && *p != '='; p++) {
+ *np++ = *p;
+ if (np - outname > 32)
+ break; /* don't overrun */
+ if (p >= p_end) {
+ err_msg("partition corrupt: ran off end parsing name\n");
+ return 0;
+ }
+ }
+
+ *np = '\0';
+ if (*p != '=') {
+ err_msg("corrupt data: no = sign found or name > 31 chars\n");
+ return 0;
+ }
+ p++;
+
+ /* Value needs to be unquoted */
+ for (np = outval; *p; p++) {
+ if (*p == (char)0xff) {
+ char ch, num;
+ p++;
+
+ if (p >= p_end) {
+ err_msg("partition corrupt: ran off end parsing "
+ "quoted value\n");
+ return 0;
+ }
+
+ num = *p & 0x7f;
+ ch = (*p & 0x80) ? 0xff : 0; /* hi bit chooses ff or 00. */
+ if (np + num - outval > 4096)
+ break; /* don't overrun */
+
+ /* repeat char */
+ while (num > 0) {
+ *np++ = ch;
+ num--;
+ }
+
+ }
+ else {
+ *np++ = *p;
+ if (np - outval > 4096)
+ break; /* don't overrun */
+ }
+
+ if (p >= p_end) {
+ err_msg("partition corrupt: ran off end parsing value\n");
+ return 0;
+ }
+ }
+
+ *np = '\0';
+ if (*p) {
+ err_msg("data value too long for this utility (>4k)\n");
+ return 0;
+ /* ToDo: recover */
+ }
+
+ return p - data;
+}
+
+/**
+ * nvram_parse_partitions
+ * @brief fill in the nvram structure with data from nvram
+ *
+ * Fill in the partition parts of the struct nvram.
+ * This makes handling partitions easier for the rest of the code.
+ *
+ * The spec says that partitions are made up of 16 byte blocks and
+ * the partition header must be 16 bytes. We verify that here.
+ *
+ * @param nvram pointer to nvram struct to fill out
+ * @return 0 on success, !0 otherwise
+ */
+static int
+nvram_parse_partitions(struct nvram *nvram)
+{
+ char *nvram_end = nvram->data + nvram->nbytes;
+ char *p_start = nvram->data;
+ struct partition_header *phead;
+ unsigned char c_sum;
+
+ if (sizeof(struct partition_header) != 16) {
+ err_msg("partition_header struct is not 16 bytes\n");
+ return -1;
+ }
+
+ while (p_start < nvram_end) {
+ phead = (struct partition_header *)p_start;
+ nvram->parts[nvram->nparts++] = phead;
+ c_sum = checksum(phead);
+ if (c_sum != phead->checksum)
+ warn_msg("this partition checksum should be %02x!\n", c_sum);
+ p_start += phead->length * NVRAM_BLOCK_SIZE;
+ }
+
+ if (verbose)
+ printf("NVRAM contains %d partitions\n", nvram->nparts);
+
+ return 0;
+}
+
+/**
+ * nvram_find_fd_partition
+ * @brief Find a particular nvram partition using a file descriptor
+ *
+ * @param name name of the partition to find
+ * @param nvram pointer to nvram struct to search
+ * @return 0 on success, !0 otherwise
+ */
+static int
+nvram_find_fd_partition(struct nvram *nvram, char *name)
+{
+ struct partition_header phead;
+ int len;
+ int found = 0;
+
+ if (lseek(nvram->fd, SEEK_SET, 0) == -1) {
+ err_msg("could not seek to beginning of file %s\n", nvram->filename);
+ return -1;
+ }
+
+ while (! found) {
+ len = read(nvram->fd, &phead, sizeof(phead));
+ if (len == 0) { /* EOF */
+ err_msg("could not find %s partition in %s\n",
+ name, nvram->filename);
+ return -1;
+ }
+ else if (len != sizeof(phead)) {
+ err_msg("Invalid read from %s: %s\n", nvram->filename,
+ strerror(errno));
+ return -1;
+ }
+
+ if (! strncmp(phead.name, name, sizeof(phead.name)))
+ found = 1;
+ else {
+ int offset = phead.length * NVRAM_BLOCK_SIZE - len;
+ if (lseek(nvram->fd, offset, SEEK_CUR) == -1) {
+ err_msg("seek error in file %s: %s\n", nvram->filename,
+ strerror(errno));
+ return -1;
+ }
+ }
+ }
+
+ if (! found) {
+ err_msg("could not find %s partition in %s\n", name, nvram->filename);
+ return -1;
+ }
+
+ /* we found the correct partition seek back to the beginning of it */
+ if (lseek(nvram->fd, -len, SEEK_CUR) == -1) {
+ err_msg("could not seek to %s partition\n", name);
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * nvram_find_partition
+ * @brief Find a partition given a signature and name.
+ *
+ * If signature is zero (invalid) it is not used for matching.
+ * If name is NULL it is ignored.
+ * start is the partition in which to resume a search (NULL starts at the first
+ * partition).
+ *
+ * @param signature partition signature to find
+ * @param name partition name to find
+ * @param start partition header to start search at
+ * @param nvram nvram struct to search
+ * @return pointer to partition header on success, NULL otherwise
+ */
+static struct partition_header *
+nvram_find_partition(struct nvram *nvram, unsigned char signature, char *name,
+ struct partition_header *start)
+{
+ struct partition_header *phead;
+ int i;
+
+ /* Get starting partition. This is not terribly efficient... */
+ if (start == NULL) {
+ i = 0;
+ if (verbose > 1)
+ printf("find partition starts with zero\n");
+ }
+ else {
+ for (i = 0; i < nvram->nparts; i++)
+ if (nvram->parts[i] == start)
+ break;
+ i++; /* start at next partition */
+ if (verbose > 1)
+ printf("find partition starts with %d\n", i);
+ }
+
+ /* Search starting with partition i... */
+ while (i < nvram->nparts) {
+ phead = nvram->parts[i];
+ if (signature == '\0' || signature == phead->signature) {
+ if (name == NULL
+ || strncmp(name, phead->name, sizeof(phead->name)) == 0) {
+ return phead;
+ }
+ }
+ i++;
+ }
+
+ return NULL;
+}
+
+/**
+ * print_partition_table
+ * @brief print a table of available partitions
+ *
+ * @param nvram nvram struct of partitions
+ */
+static void
+print_partition_table(struct nvram *nvram)
+{
+ struct partition_header *phead;
+ int i = 0;
+
+ printf(" # Sig Chk Len Name\n");
+ for (i = 0; i < nvram->nparts; i++) {
+ phead = nvram->parts[i];
+ printf("%2d %02x %02x %04x %.12s\n", i, phead->signature,
+ phead->checksum, phead->length, phead->name);
+ }
+}
+
+/**
+ * getvalue
+ * @brief Copy a value into a buf.
+ * The first two bytes of the value is a length.
+ * Return pointer to byte after the value.
+ *
+ * @param p pointer to value to copy
+ * @param buf buffer to copy value into
+ * @return pointer past the copied value in p
+ */
+static char *
+getvalue(char *p, char *buf)
+{
+ int len = *p++;
+ len |= ((*p++) << 8);
+ memcpy(buf, p, len);
+ buf[len] = '\0';
+ return p+len;
+}
+
+/**
+ * getsmallvlaue
+ * @brief Copy a value into a buf.
+ * The first one bytes of the value is a length.
+ *
+ * @param p pointer to value to copy
+ * @param buf buffer to copy value into
+ * @return pointer past the copied value in p
+ */
+static char *
+getsmallvalue(char *p, char *buf)
+{
+ int len = *p++;
+ memcpy(buf, p, len);
+ buf[len] = '\0';
+ return p+len;
+}
+
+/**
+ * lookupfield
+ * @brief translate a VPD field to human readable string
+ *
+ * Lookup a VPD field name (always 2 chars) and return a human
+ * readable string.
+ *
+ * @param p VPD field name
+ * @return pointer to human readable string on success, NULL otherwise
+ */
+static char *
+lookupfield(char *p)
+{
+ int i;
+
+ for (i = 0; (i < sizeof(descs) / sizeof(descs[0])); i++) {
+ if (strcmp(p, descs[i].name) == 0)
+ return descs[i].desc;
+ }
+
+ return NULL;
+}
+
+/**
+ * printVPDfield
+ * @brief Format and print a VPD field and return a ptr to the next field.
+ *
+ * @param p pointer to VPD field
+ * @param show_all verbosity level
+ * @return pointer to next VPD field
+ */
+static char *
+printVPDfield(char *p, int show_all)
+{
+ char field[3];
+ char value[256];
+ char *fname;
+
+ field[0] = p[0]; field[1] = p[1]; field[2] = 0;
+ p+=2;
+ p = getsmallvalue(p, value);
+ if ((fname = lookupfield(field)) != NULL)
+ printf(" %-20s %s\n", fname, value);
+ else if (show_all)
+ printf(" %-20s %s\n", field, value);
+
+ return p;
+}
+
+/**
+ * dump_vpd
+ * @brief Dump Vital Product Data
+ *
+ * See Chapter 18: Expansion ROMs of the PCI spec.
+ *
+ * @param nvram nvram struct to retrieve VPD data from
+ * @param show_all verbosity level
+ */
+int
+dump_vpd(struct nvram *nvram, int show_all)
+{
+ struct partition_header *phead;
+ char *p, *p_end;
+ char value[4096];
+
+ phead = nvram_find_partition(nvram, NVRAM_SIG_HW, "ibm,vpd", NULL);
+ if (!phead) {
+ err_msg("there is no ibm,vpd partition!\n");
+ return -1;
+ }
+
+ p = (char *)(phead + 1);
+ p_end = (char *)(phead + phead->length);
+
+ while (*p && p < p_end) {
+ if (*p == (char)0x82) { /* Identification string descriptor. */
+ p++;
+ p = getvalue(p, value);
+ printf("%s\n", value); /* print id string */
+
+ while (*p != 0x79) { /* loop until VPD end tag */
+ int vpdlen;
+ char *vpd_endp;
+ p++;
+ vpdlen = *p++;
+ vpdlen |= ((*p++) << 8);
+ vpd_endp = p + vpdlen;
+ while (p < vpd_endp)
+ p = printVPDfield(p, show_all);
+ }
+
+ p++;
+ /* printf("checksum byte=0x%x\n", *p); */
+ p++;
+ }
+ else if (*p == 0) { /* end tag */
+ break;
+ }
+ }
+
+ if (*p && p < p_end) {
+ warn_msg("found unknown descriptor byte 0x%x\n", *p);
+ }
+
+ return 0;
+}
+
+/**
+ * dump_errlog
+ * @brief Dump ibm,err-log partition which contains checkstop info.
+ *
+ * ToDo: this code needs more work.
+ * See IBM RPA (IBM internal use only -- sorry).
+ *
+ * @param nvram nvram struct to dump errlog from
+ * @return 0 on success, !0 otherwise
+ */
+int
+dump_errlog(struct nvram *nvram)
+{
+ struct partition_header *phead;
+ uint16_t *p, *p_end; /* Note: data is organized into 16bit big
+ * endian (network byte order) */
+ int p_max; /* max index to go out of bounds of the partition */
+ int i, cpu;
+ char checkstop_count;
+ int offset;
+ int num_cpus;
+ int num_memctrls;
+ int num_ioctrls;
+ uint16_t *sys_regs; /* System specific registers
+ * (e.g. bus arbitration chips, etc */
+ uint16_t *cpu_regs[MAX_CPUS+1];
+ uint16_t *memctrl_data;
+ uint16_t *ioctrl_data;
+
+ phead = nvram_find_partition(nvram, NVRAM_SIG_SP, "ibm,err-log", NULL);
+ if (!phead) {
+ err_msg("there is no ibm,err-log partition!\n");
+ return -1;
+ }
+
+ p = (uint16_t *)(phead + 1);
+ p_end = (uint16_t *)(phead + phead->length);
+ p_max = p_end - p; /* max in 16bit values */
+ if (p_max < 4) {
+ err_msg("Corrupt ibm,err-log partition in nvram\n");
+ return -1;
+ }
+
+ /* index 0 is checkstop count (high byte), semaphores (low byte) */
+ i = 0; /* index through short words */
+ checkstop_count = p[i] >> 8;
+ if (checkstop_count)
+ printf("Checkstops detected: %d\n", checkstop_count);
+ else
+ printf("No checkstops have been detected.\n");
+
+ /* index 1 is system specific register offset */
+ i++;
+ offset = ntohs(p[i])/2+1;
+ sys_regs = offset + i < p_max ? p + offset + i : 0;
+
+ /* index 2 is number of cpus */
+ i++;
+ num_cpus = ntohs(p[i]);
+ printf("CPUS: %d\n", num_cpus);
+
+ /* Next indexes are offsets to cpu specific regs */
+ for (cpu = 0; cpu < num_cpus; cpu++) {
+ i++;
+ if (cpu < MAX_CPUS) {
+ offset = ntohs(p[i])/2+1;
+ cpu_regs[cpu] = offset + i < p_max ? p + offset + i : 0;
+ }
+ }
+
+ if (num_cpus > MAX_CPUS)
+ num_cpus = MAX_CPUS; /* just in case... */
+
+ /* next index is number of memory controllers */
+ i++;
+ num_memctrls = ntohs(p[i]);
+ printf("Memory Controllers: %d\n", num_memctrls);
+
+ /* next index is offset of memory controller data */
+ i++; /* ToDo: this may be a list of offsets...manual doesn't show
+ that but only 1 seems odd */
+ offset = ntohs(p[i])/2+1;
+ memctrl_data = offset + i < p_max ? p + offset + i : 0;
+
+ /* next index is number of I/O Subsystem controllers */
+ i++;
+ num_ioctrls = ntohs(p[i]);
+ printf("I/O Controllers: %d\n", num_ioctrls);
+
+ /* next index is offset of I/O Subsystem controller data */
+ i++; /* ToDo: this may be a list of offsets...manual doesn't show
+ that but only 1 seems odd */
+ offset = ntohs(p[i])/2+1;
+ ioctrl_data = offset + i < p_max ? p + offset + i : 0;
+
+ /*** End of header ***/
+
+ /* Now dump sections collected by the header. */
+ if (sys_regs && num_cpus > 0) {
+ /* ToDo: what is the length of the data? We dump until the
+ first cpu data. */
+ printf("System Specific Registers\n");
+ dump_raw_data((char *)sys_regs, cpu_regs[0] - sys_regs);
+ }
+
+ /* artificial "next cpu" data for length */
+ cpu_regs[num_cpus] = ioctrl_data;
+
+ for (cpu = 0; cpu < num_cpus; cpu++) {
+ /*char buf[64];*/
+ int len;
+ /* ToDo: what is the length of the data? We dump until the
+ next cpu data. */
+ len = cpu_regs[cpu+1] - cpu_regs[cpu];
+ printf("CPU %d Register Data (len=%x, offset=%x)\n", cpu, len,
+ cpu_regs[cpu]-p);
+ if (len < 4096) /* reasonable bound */
+ dump_raw_data((char *)cpu_regs[cpu], len);
+ }
+
+ return 0;
+}
+
+/**
+ * dump_rtas_event_entry
+ * @brief Dump event-scan data.
+ *
+ * Note: This is really only valid for PAPR machines. To ensure
+ * the nvram command can run on all powerpc machines we dlopen the
+ * the librtasevent library to dump the rtas event.
+ *
+ * @param data pointer to rtas error to dump
+ * @param len length of data buffer
+ * @return 0 on success, !0 otherwise
+ */
+int
+dump_rtas_event_entry(char *data, int len)
+{
+ void *rtas_event;
+ void *handle;
+ void *(*parse_rtas_event)();
+ void (*rtas_print_event)();
+ void (*cleanup_rtas_event)();
+
+ handle = dlopen("/usr/lib/librtasevent.so", RTLD_LAZY);
+ if (handle == NULL)
+ return 1;
+
+ parse_rtas_event = dlsym(handle, "parse_rtas_event");
+ if (parse_rtas_event == NULL) {
+ dlclose(handle);
+ return 1;
+ }
+
+ rtas_print_event = dlsym(handle, "rtas_print_event");
+ if (rtas_print_event == NULL) {
+ dlclose(handle);
+ return 1;
+ }
+
+ cleanup_rtas_event = dlsym(handle, "cleanup_rtas_event");
+ if (cleanup_rtas_event == NULL) {
+ dlclose(handle);
+ return 1;
+ }
+
+ rtas_event = parse_rtas_event(data, len);
+ if (rtas_event == NULL) {
+ dlclose(handle);
+ return 1;
+ }
+
+ rtas_print_event(stdout, rtas_event, 0);
+
+ cleanup_rtas_event(rtas_event);
+
+ dlclose(handle);
+ return 0;
+}
+
+/**
+ * dump_eventscanlog
+ * @brief Dump ibm,es-logs partition, which contains a service processor log
+ *
+ * See IBM RPA (IBM internal use only -- sorry).
+ *
+ * @param nvram nvram struct to get eventscan log from
+ * @return 0 on success, !0 otherwise
+ */
+int
+dump_eventscanlog(struct nvram *nvram)
+{
+ struct partition_header *phead;
+ uint32_t *p, *p_end; /* Note: data is organized into 32bit big
+ * endian (network byte order) */
+ int p_max; /* max index to go out of bounds of the partition */
+ int lognum;
+ int num_logs;
+ int rc;
+#define MAX_EVENTLOGS 100
+ uint32_t loghdr[MAX_EVENTLOGS+1];
+
+ phead = nvram_find_partition(nvram, NVRAM_SIG_SP, "ibm,es-logs", NULL);
+ if (!phead) {
+ err_msg("there is no ibm,es-logs partition!\n");
+ return -1;
+ }
+
+ p = (uint32_t *)(phead + 1);
+ p_end = (uint32_t *)(phead + phead->length);
+ p_max = p_end - p; /* max in 32bit values */
+ if (p_max < 1) {
+ err_msg("Corrupt ibm,es-logs partition in nvram\n");
+ return -1;
+ }
+
+ num_logs = ntohl(*p);
+ printf("Number of Logs: %d\n", num_logs);
+
+ if (num_logs > MAX_EVENTLOGS) {
+ num_logs = MAX_EVENTLOGS;
+ warn_msg("limiting to %d log entries (program limit)\n", num_logs);
+ }
+
+ if (num_logs > p_max-1) {
+ /* of course this leaves no room for log data
+ (i.e. corrupt partition) */
+ num_logs = p_max-1;
+ warn_msg("limiting to %d log entries (partition limit)\n", num_logs);
+ }
+
+ for (lognum = 0; lognum < num_logs; lognum++) {
+ loghdr[lognum] = ntohl(p[lognum+1]);
+ }
+
+ /* artificial log entry (offset) to put a limit on the last log */
+ loghdr[num_logs] = p_max * sizeof(uint32_t);
+
+ for (lognum = 0; lognum < num_logs; lognum++) {
+ uint32_t hdr = loghdr[lognum];
+ int flags = (hdr >> 24) & 0xff;
+ int logtype = (hdr >> 16) & 0xff;
+ int start = hdr & 0xffff;
+ int end = loghdr[lognum+1] & 0xffff;
+ printf("Log Entry %d: flags: 0x%02x type: 0x%02x\n", lognum,
+ flags, logtype);
+ rc = dump_rtas_event_entry(((char *)p) + start, end - start);
+ if (rc) {
+ printf("==== Log %d ====\n", lognum);
+ dump_raw_data(((char *)p) + start, end - start);
+ }
+ }
+
+ return 0;
+}
+
+
+/**
+ * dump_raw_partition
+ * @brief Dump raw data of a partition. Mainly for debugging.
+ *
+ * @param nvram nvram struct containing partition
+ * @param name name of partition to dump
+ * @return 0 on success, !0 otherwise
+ */
+int
+dump_raw_partition(struct nvram *nvram, char *name)
+{
+ struct partition_header *phead;
+
+ phead = nvram_find_partition(nvram, 0, name, NULL);
+ if (!phead) {
+ err_msg("there is no %s partition!\n", name);
+ return -1;
+ }
+
+ dump_raw_data((char *)phead, phead->length * NVRAM_BLOCK_SIZE);
+
+ return 0;
+}
+
+/**
+ * print_of_config_part
+ * @brief Print the name/value pairs of a partition
+ *
+ * @param pname partition name containing name/value pairs
+ * @param nvram nvram struct containing partition to dump
+ * @return 0 on success, !0 otherwise
+ */
+static int
+print_of_config_part(struct nvram *nvram, char *pname)
+{
+ struct partition_header *phead;
+ char *data;
+ int i;
+
+ phead = nvram_find_partition(nvram, 0, pname, NULL);
+ if (phead == NULL)
+ return -1;
+
+ data = (char *)phead + sizeof(*phead);
+
+ printf("\"%s\" Partition\n", pname);
+ for (i = 0; i <= (strlen(pname) + 14); i++)
+ printf("-");
+ printf("\n");
+
+ while (*data != '\0') {
+ printf("%s\n", data);
+ data += strlen(data) + 1;
+ }
+
+ printf("\n");
+
+ return 0;
+}
+
+/* Print a single OF var...or all if "" is used */
+/**
+ * @var name_value_parts
+ * @brief List of partition names that contain name/value pairs
+ */
+/**
+ * @var num_name_value_parts
+ * @brief number of names in the name_vlaue_parts array
+ */
+static char *name_value_parts[] = {
+ "common", "ibm,setupcfg", "of-config"
+};
+static int num_name_value_parts = 3;
+
+/**
+ * print_of_config
+ * @brief Print the contents of an Open Firmware config partition
+ *
+ * This will print the name/value pair for a specified Open
+ * Firmware config variable or print all of the name/value pairs
+ * in the partition if the name is NULL.
+ *
+ * @param config_var config variable to print
+ * @param pname partition name containing config_var
+ * @param nvram nvram struct containing pname
+ * @return 0 on success, !0 otherwise
+ */
+static int
+print_of_config(struct nvram *nvram, char *config_var, char *pname)
+{
+ struct partition_header *phead;
+ char *data;
+ int i, varlen;
+ int rc = -1;
+
+ /* if config_var is NULL , print the data from the
+ * partition specified by pname or all of the
+ * name/value pair partitions if pname is NULL.
+ */
+ if (config_var == NULL) {
+ if (pname == NULL) {
+ for (i = 0; i < num_name_value_parts; i++)
+ (void)print_of_config_part(nvram, name_value_parts[i]);
+ }
+ else {
+ for (i = 0; i < num_name_value_parts; i++) {
+ if (strcmp(pname, name_value_parts[i]) == 0) {
+ (void)print_of_config_part(nvram, name_value_parts[i]);
+ rc = 0;
+ }
+ }
+ if (rc)
+ err_msg("There is no Open Firmware \"%s\" partition!\n", pname);
+ }
+ return rc;
+ }
+
+ /* the config_var is a variable name */
+ varlen = strlen(config_var);
+
+ if (pname == NULL) {
+ for (i = 0; i < num_name_value_parts; i++) {
+ phead = nvram_find_partition(nvram, 0, name_value_parts[i], NULL);
+ if (phead == NULL)
+ continue;
+
+ data = (char *)phead + sizeof(*phead);
+
+ while (*data != '\0') {
+ if ((data[varlen] == '=') &&
+ strncmp(config_var, data, varlen) == 0) {
+ printf("%s\n", data + varlen + 1);
+ rc = 0;
+ }
+ data += strlen(data) + 1;
+ }
+ }
+ }
+ else {
+ phead = nvram_find_partition(nvram, 0, pname, NULL);
+ if (phead == NULL) {
+ err_msg("There is no Open Firmware \"%s\" partition.\n", pname);
+ return -1;
+ }
+
+ data = (char *)phead + sizeof(*phead);
+ while (*data != '\0') {
+ if ((data[varlen] == '=') &&
+ strncmp(config_var, data, varlen) == 0) {
+ printf("%s\n", data + varlen + 1);
+ rc = 0;
+ }
+ data += strlen(data) + 1;
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * update_config_var
+ * @brief Update an Open Firmware config variable in nvram
+ *
+ * This will attempt to update the value half of a name/value
+ * pair in the nvram config partition. If the name/value pair
+ * is not found in the partition then the specified name/value pair
+ * is added to the end of the data in the partition.
+ *
+ * @param config_var OF config variable to update
+ * @param pname partition containing config_var
+ * @param nvram nvram struct containing pname
+ * @return 0 on success, !0 otherwise
+ */
+int
+update_of_config_var(struct nvram *nvram, char *config_var, char *pname)
+{
+ struct partition_header *phead, *new_phead;
+ char *data_offset;
+ char *new_part;
+ char *new_part_offset, *new_part_end;
+ char *tmp_offset;
+ int config_name_len;
+ int len, part_size, found = 0;
+
+ phead = nvram_find_partition(nvram, 0, pname, NULL);
+ if (phead == NULL) {
+ err_msg("there is no \"%s\" partition!\n", pname);
+ return -1;
+ }
+
+ part_size = phead->length * NVRAM_BLOCK_SIZE;
+ data_offset = (char *)((unsigned long)phead + sizeof(*phead));
+
+ new_part = malloc(part_size);
+ if (new_part == NULL) {
+ err_msg("cannot allocate space to update \"%s\" partition\n", pname);
+ return -1;
+ }
+
+ /* get the length of then name of the config variable we are updating */
+ config_name_len = strstr(config_var, "=") - config_var;
+ config_name_len++;
+
+ /* now find this config variable in the partition */
+ while (*data_offset != '\0') {
+ if (strncmp(data_offset, config_var, config_name_len) == 0) {
+ found = 1;
+ break;
+ }
+ else
+ data_offset += strlen(data_offset) + 1;
+ }
+
+ if (!found) {
+ err_msg("cannot update %s\n"
+ "\tThe config var does not exist in the \"%s\" partition\n",
+ config_var, pname);
+ free(new_part);
+ return -1;
+ }
+
+ /* Copy everything up to the config name we are modifying
+ * to the new partition
+ */
+ memcpy(new_part, phead, data_offset - (char *)phead);
+
+ /* make sure the new config var will fit into the partition and add it */
+ new_phead = (struct partition_header *)new_part;
+ new_part_offset = new_part + (data_offset - (char *)phead);
+ new_part_end = new_part + part_size;
+
+ if ((new_part_offset + strlen(config_var) + 1) >= new_part_end) {
+ err_msg("cannot update config var to\"%s\".\n"
+ "\tThere is not enough room in the \"%s\" partition\n",
+ config_var, pname);
+ free(new_part);
+ return -1;
+ }
+
+ strncpy(new_part_offset, config_var, strlen(config_var));
+ new_part_offset += strlen(config_var);
+ *new_part_offset++ = '\0';
+
+ /* Find the end of the name/value pairs in the partition so we
+ * can copy them over to the new partition.
+ */
+ data_offset += strlen(data_offset) + 1;
+ tmp_offset = data_offset;
+ while (*data_offset != '\0') {
+ data_offset += strlen(data_offset) + 1;
+ }
+
+ /* we should now be pointing to a double NULL, verify this */
+ if ((data_offset[-1] != '\0') && (data_offset[0] != '\0')) {
+ err_msg("the \"%s\" partition appears to be corrupt\n", pname);
+ free(new_part);
+ return -1;
+ }
+
+ /* go past double NULL */
+ data_offset++;
+
+ /* verify that this will fit into the new partition */
+ if ((new_part_offset + (data_offset - tmp_offset)) > new_part_end) {
+ err_msg("cannot update open firmware config var to \"%s\".\n"
+ "\tThere is not enough room in the \"%s\" partition\n",
+ config_var, pname);
+ free(new_part);
+ return -1;
+ }
+
+ memcpy(new_part_offset, tmp_offset, data_offset - tmp_offset);
+
+ /* recalculate the checksum */
+ new_phead->checksum = checksum(new_phead);
+
+ /* seek the position in the /dev/nvram for the common partition */
+ if (nvram_find_fd_partition(nvram, new_phead->name) != 0) {
+ free(new_part);
+ return -1;
+ }
+
+ /* write the partition out to nvram */
+ len = write(nvram->fd, new_part, part_size);
+ if (len != part_size) {
+ err_msg("only wrote %d bytes of the \"%s\" partition back\n"
+ "\tto %s, expected to write %d bytes\n",
+ len, pname, nvram->filename, part_size);
+ }
+
+ free(new_part);
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ struct nvram nvram;
+ struct stat sbuf;
+ int ret = 0;
+ int of_nvram_size;
+ int option_index;
+ char *endp;
+ char *of_config_var = NULL;
+ int print_partitions = 0;
+ int print_vpd = 0;
+ int print_errlog = 0;
+ int print_event_scan = 0;
+ int print_config_var = 0;
+ char *dump_name = NULL;
+ char *update_config_var = NULL;
+ char *config_pname = "common";
+
+ nvram_cmdname = argv[0];
+ if (argc == 1) {
+ help();
+ exit(1);
+ }
+
+ /* initialize nvram struct */
+ memset(&nvram, 0, sizeof(struct nvram));
+ nvram.fd = -1;
+
+ for (;;) {
+ option_index = 0;
+ ret = getopt_long(argc, argv, "+v:p:", long_options, &option_index);
+ if (ret == -1)
+ break;
+ switch (ret) {
+ case 'h':
+ help();
+ exit(0);
+ case 'v':
+ verbose += (optarg ? atoi(optarg) : 1);
+ break;
+ case 'd': /* dump */
+ dump_name = optarg;
+ break;
+ case 'n': /* nvram-file */
+ nvram.filename = optarg;
+ break;
+ case 'o': /*print-config */
+ print_config_var = 1;
+ of_config_var = optarg;
+ break;
+ case 'P': /* partitions */
+ print_partitions = 1;
+ break;
+ case 's': /* nvram-size */
+ nvram.nbytes = strtoul(optarg, &endp, 10);
+ if (!*optarg || *endp) {
+ err_msg("specify nvram-size as an integer\n");
+ exit(1);
+ }
+ break;
+ case 'V': /* print-vpd */
+ print_vpd = 1;
+ break;
+ case 'W': /* print-all-vpd */
+ print_vpd = 2;
+ break;
+ case 'e': /* print-err-log */
+ print_errlog = 1;
+ break;
+ case 'E': /* print-event-scan */
+ print_event_scan = 1;
+ break;
+ case 'u': /* update-config */
+ update_config_var = optarg;
+ break;
+ case 'p': /* update-config partition name */
+ config_pname = optarg;
+ break;
+ case '?':
+ exit(1);
+ break;
+ default:
+ printf("huh?\n");
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ err_msg("Could not parse the option %s correctly.\n",
+ argv[optind]);
+ help();
+ exit(-1);
+ }
+
+ ret = 0;
+
+ if (nvram.filename) {
+ nvram.fd = open(nvram.filename, O_RDWR);
+ if (nvram.fd == -1) {
+ err_msg("cannot open \"%s\": %s\n",
+ nvram.filename, strerror(errno));
+ ret = -1;
+ goto err_exit;
+ }
+ } else {
+ nvram.filename = NVRAM_FILENAME1;
+ nvram.fd = open(nvram.filename, O_RDWR);
+ if (nvram.fd == -1) {
+ int errno1 = errno;
+
+ nvram.filename = NVRAM_FILENAME2;
+ nvram.fd = open(nvram.filename, O_RDWR);
+ if (nvram.fd == -1) {
+ err_msg("cannot open \"%s\": %s\n",
+ NVRAM_FILENAME1, strerror(errno1));
+ err_msg("cannot open \"%s\": %s\n",
+ NVRAM_FILENAME2, strerror(errno));
+ ret = -1;
+ goto err_exit;
+ }
+ }
+ }
+
+ if (fstat(nvram.fd, &sbuf) < 0) {
+ err_msg("cannot stat %s: %s\n", nvram.filename, strerror(errno));
+ ret = -1;
+ goto err_exit;
+ }
+
+ of_nvram_size = get_of_nvram_size();
+ nvram.nbytes = sbuf.st_size ? sbuf.st_size : of_nvram_size;
+ if (nvram.nbytes != of_nvram_size) {
+ warn_msg("specified nvram size %d does not match this machine %d!\n",
+ nvram.nbytes, of_nvram_size);
+ }
+
+ nvram.data = malloc(nvram.nbytes);
+ if (nvram.data == NULL) {
+ err_msg("cannot allocate space for nvram of %d bytes\n", nvram.nbytes);
+ ret = -1;
+ goto err_exit;
+ }
+
+ if (nvram_read(&nvram) != 0) {
+ ret = -1;
+ goto err_exit;
+ }
+
+ if (nvram_parse_partitions(&nvram) != 0) {
+ ret = -1;
+ goto err_exit;
+ }
+
+ if (print_partitions)
+ print_partition_table(&nvram);
+
+ if (update_config_var) {
+ if (config_pname == NULL) {
+ err_msg("you must specify the partition name with the -p option\n"
+ "\twhen using the --update-config option\n");
+ goto err_exit;
+ }
+ if (update_of_config_var(&nvram, update_config_var, config_pname) != 0)
+ ret = -1;
+ }
+ if (print_config_var)
+ if (print_of_config(&nvram, of_config_var, config_pname) != 0)
+ ret = -1;
+ if (print_vpd)
+ if (dump_vpd(&nvram, print_vpd == 2) != 0)
+ ret = -1;
+ if (print_errlog)
+ if (dump_errlog(&nvram) != 0)
+ ret = -1;
+ if (print_event_scan)
+ if (dump_eventscanlog(&nvram) != 0)
+ ret = -1;
+ if (dump_name)
+ if (dump_raw_partition(&nvram, dump_name) != 0)
+ ret = -1;
+
+err_exit:
+ if (nvram.data)
+ free(nvram.data);
+ if (nvram.fd != -1)
+ close(nvram.fd);
+
+ return ret;
+}
Added: trunk/powerpc-ibm-utils/cmds/nvram.h
===================================================================
--- trunk/powerpc-ibm-utils/cmds/nvram.h (rev 0)
+++ trunk/powerpc-ibm-utils/cmds/nvram.h 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,111 @@
+/**
+ * @file nvram.h
+ * @brief nvram access utility for powerpc platforms.
+ *
+ * Copyright (c) 2003, 2004 International Business Machines
+ * Common Public License Version 1.0 (see COPYRIGHT)
+ *
+ * @author Nathan Fontenot <nfont at austin.ibm.com>
+ * @author Michael Strosaker <strosake at us.ibm.com>
+ * @author Todd Inglett <tinglett at us.ibm.com>
+ */
+
+#ifndef _DEV_NVRAM_H_
+#define _DEV_NVRAM_H_
+
+#define NVRAM_SIG_SP 0x02 /**< support processor signature */
+#define NVRAM_SIG_OF 0x50 /**< open firmware config signature */
+#define NVRAM_SIG_FW 0x51 /**< general firmware signature */
+#define NVRAM_SIG_HW 0x52 /**< hardware (VPD) signature */
+#define NVRAM_SIG_SYS 0x70 /**< system env vars signature */
+#define NVRAM_SIG_CFG 0x71 /**< config data signature */
+#define NVRAM_SIG_ELOG 0x72 /**< error log signature */
+#define NVRAM_SIG_VEND 0x7e /**< vendor defined signature */
+#define NVRAM_SIG_FREE 0x7f /**< Free space signature */
+#define NVRAM_SIG_OS 0xa0 /**< OS defined signature */
+
+/**
+ * @def printmap(ch)
+ * @brief dertermines if 'ch' is a printable character
+ */
+#define printmap(ch) (isgraph(ch) ? (ch) : '.')
+
+#define NVRAM_BLOCK_SIZE 16
+#define NVRAM_FILENAME1 "/dev/nvram"
+#define NVRAM_FILENAME2 "/dev/misc/nvram"
+
+#define DEVICE_TREE "/proc/device-tree"
+#define NVRAM_DEFAULT DEVICE_TREE "/nvram"
+#define NVRAM_ALIAS DEVICE_TREE "/aliases/nvram"
+
+#define DEFAULT_NVRAM_SZ (1024 * 1024)
+
+/**
+ * @def MAX_CPUS
+ * @brief maximum number of CPUS for errlog dumps
+ */
+#define MAX_CPUS 128
+
+/**
+ * @struct partition_header
+ * @brief nvram partition header data
+ */
+struct partition_header {
+ unsigned char signature; /**< partition signature */
+ unsigned char checksum; /**< partition checksum */
+ unsigned short length; /**< partition length */
+ char name[12]; /**< partition name */
+};
+
+/* Internal representation of NVRAM. */
+#define MAX_PARTITIONS 50
+/**
+ * @struct nvram
+ * @brief internal representation of nvram data
+ */
+struct nvram {
+ char *filename; /**< original filename */
+ int fd; /**< file descriptor */
+ int nparts; /**< number of partitions */
+ int nbytes; /**< size of data in bytes. This
+ * cannot be changed
+ * (i.e. hardware size)
+ */
+ struct partition_header *parts[MAX_PARTITIONS];
+ /**< partition header pointers
+ * into data
+ */
+ char *data; /**< nvram contents */
+};
+
+/**
+ * @var descs
+ * @brief Array of VPD field names and descriptions
+ */
+static struct { char *name; char *desc; } descs[] = {
+ {"PN", "Part Number"},
+ {"FN", "FRU Number"},
+ {"EC", "EC Level"},
+ {"MN", "Manufacture ID"},
+ {"SN", "Serial Number"},
+ {"LI", "Load ID"},
+ {"RL", "ROM Level"},
+ {"RM", "Alterable ROM Level"},
+ {"NA", "Network Address"},
+ {"DD", "Device Driver Level"},
+ {"DG", "Diagnostic Level"},
+ {"LL", "Loadable Microcode Level"},
+ {"VI", "Vendor ID/Device ID"},
+ {"FU", "Function Number"},
+ {"SI", "Subsystem Vendor ID/Device ID"},
+ {"VK", "Platform"}, /**< "RS6K" => VPD is present */
+ {"TM", "Model"}, /**< IBM specific? */
+ {"YL", "Location Code"}, /**< IBM specific? */
+ {"BR", "Brand"}, /**< IBM specific */
+ {"CI", "CEC ID"}, /**< IBM specific */
+ {"RD", "Rack ID"}, /**< IBM specific */
+ {"PA", "Op Panel Installed"}, /**< IBM specific */
+ {"NN", "Node Name"}, /**< IBM specific */
+};
+
+#endif
Added: trunk/powerpc-ibm-utils/doc/Makefile
===================================================================
--- trunk/powerpc-ibm-utils/doc/Makefile (rev 0)
+++ trunk/powerpc-ibm-utils/doc/Makefile 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,28 @@
+#
+# Makefile for powerpc-utils/doc
+#
+
+include ../rules.mk
+
+MANPAGES8 = snap.8 bootlist.8 ofpathname.8
+
+SUBDIRS = nvram
+
+all: $(MANPAGES8)
+ @$(foreach d,$(SUBDIRS), $(MAKE) -C $d;)
+
+install: all
+ @$(call install_man,$(MANPAGES8),$(DESTDIR))
+ @$(foreach d,$(SUBDIRS), $(MAKE) -C $d install;)
+
+uninstall:
+ @$(call uninstall_man,$(MANPAGES8),$(DESTDIR))
+ @$(foreach d,$(SUBDIRS), $(MAKE) -C $d uninstall;)
+
+docs:
+ @$(foreach d,$(SUBDIRS), $(MAKE) -C $d docs;)
+
+clean:
+ @echo "Cleaning up $(WORK_DIR) files..."
+ @$(foreach d,$(SUBDIRS), $(MAKE) -C $d clean;)
+ @rm -f *~
Added: trunk/powerpc-ibm-utils/doc/bootlist.8
===================================================================
--- trunk/powerpc-ibm-utils/doc/bootlist.8 (rev 0)
+++ trunk/powerpc-ibm-utils/doc/bootlist.8 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,59 @@
+.\"
+.\" Copyright (C) 2004 International Business Machines
+.\" Nathan Fontenot <nfont at austin.ibm.com>
+.\"
+.TH BOOTLIST 8 "April 2004" Linux "Linux on Power Service Tools"
+.SH NAME
+bootlist - update and view the bootlist
+.SH SYNOPSIS
+.nf
+\fB/usr/sbin/bootlist \-m normal\fR|\fBservice\fR|\fBboth \fR[\fB-o\fR|\fB-r\fR] <\fIdev_list\fR>
+\fB/usr/sbin/bootlist \-m normal\fR|\fBservice\fR|\fBboth \fR[\fB-o\fR|\fB-r\fR] \fB-f \fIfile
+.fi
+.SH DESCRIPTION
+The bootlist command allows users to view and update the system bootlist
+stored in NVRAM for PowerPC-64 machines. The bootlist entries can be
+specified as either logical device names or Open Firmware device path names.
+The bootlist will convert all names to Open Firmware device path names using
+\fIofpathname\fR when updating the bootlist. Then uses the \fInvram\fR
+command to update NVRAM. If a list of devices is specified, the boot list
+will be updated with the list provided. If a list is not specified, the
+current boot list will be printed.
+.SH OPTIONS
+.TP
+\fB\-m normal\fR|\fBservice\fR|\fBboth
+Required; specify whether the normal or service mode boot list should be
+viewed/updated. Specifying "both" will update the normal and service mode
+boot lists.
+.TP
+\fB\-o
+Display the current boot list entries as logical device names.
+.TP
+\fB\-r
+Display the current boot list entries as Open Firmware device path names
+(default).
+.TP
+\fB\-f \fIfile
+Read the bootlist device names from \fIfile\fR, one entry per line.
+.TP
+\fIdev_list
+A space-separated list of devices, specified as logical device names or OF
+device path names, depending on whether the \fB-o\fR or \fB-r\fR option is
+specified.
+.SH EXAMPLES
+.nf
+View the normal mode boot list as logical device names:
+
+ /usr/sbin/bootlist -o -m normal
+
+Update the service mode boot list:
+
+ /usr/sbin/bootlist -o -m service /dev/sda3 /dev/cdrom
+.fi
+.SH AUTHOR
+Written by Nathan Fontenot
+.SH "SEE ALSO"
+.BR ofpathname (8),
+.BR nvram (8)
+
+
Added: trunk/powerpc-ibm-utils/doc/nvram/Makefile
===================================================================
--- trunk/powerpc-ibm-utils/doc/nvram/Makefile (rev 0)
+++ trunk/powerpc-ibm-utils/doc/nvram/Makefile 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,24 @@
+#
+# Makefile for powerpc-utils/doc/nvram
+#
+
+include ../../rules.mk
+
+MANPAGE = nvram.8
+
+DOXYGEN_CFG = nvram.doxycfg
+
+all: $(MANPAGE)
+
+install: all
+ @$(call install_man,$(MANPAGE),$(DESTDIR))
+
+uninstall:
+ @$(call uninstall_man,$(MANPAGE),$(DESTDIR))
+
+docs: $(DOXYGEN_CFG)
+ @echo "Creating $(WORK_DIR) doxygen docs..."
+ @$(DOXYGEN) $(DOXYGEN_CFG) >/dev/null
+
+clean:
+ @rm -rf html latex *~
Added: trunk/powerpc-ibm-utils/doc/nvram/nvram.8
===================================================================
--- trunk/powerpc-ibm-utils/doc/nvram/nvram.8 (rev 0)
+++ trunk/powerpc-ibm-utils/doc/nvram/nvram.8 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,73 @@
+.\"
+.\" Copyright (C) 2002 - 2004 International Business Machines
+.\"
+.TH NVRAM 8 "May 2004" Linux "Linux on Power Service Tools"
+.SH NAME
+nvram \- format data stored in non-volatile RAM
+.SH SYNOPSIS
+.B /usr/sbin/nvram
+[ options ]
+.SH DESCRIPTION
+.I Nvram
+is used to print and modify data stored in the non-volatile RAM (NVRAM)
+on a PowerPC-64 system. NVRAM on these systems is partitioned into data
+sections that each have their own format. The print options to this
+command selects what to print and how to format it.
+
+.P
+The
+.I nvram
+utility can also be used to update the data in certain NVRAM partitions of
+PowerPC-64 systems.
+.I Nvram
+can update the value of a name/value pair for NVRAM partitions formatted
+as a set of name=value pairs. On many systems, the following NVRAM
+partitions contain data formatted as name=value pairs: common, of-config,
+and ibm,setupcfg.
+.SH OPTIONS
+.TP
+\fB\--print-config\fR[=\fIvar\fR]
+print value of a config variable, or print all variables in the specified
+(or all) partitions.
+.TP
+\fB\--update-config \fIname\fR=\fIvalue
+update the config variable in the specified partition; the -p option
+must also be specified..
+.TP
+\fB\-p \fIpartition
+specify a partition; required with the --update-config option, optional
+with the --print-config option.
+.TP
+\fB\--print-vpd
+print vital product data (VPD) collected by the system in NVRAM.
+This data may also be viewed with the lscfg(1) command directly from the
+devices.
+.TP
+\fB\--print-all-vpd
+print viral product data (VPD) collected by the system in NVRAM including
+vendor specific data.
+.TP
+\fB\--print-err-log
+print the checkstop error log generated by the service processor whenever
+the system checkstops.
+.TP
+\fB\--print-event-scan
+print the event scan log stored in NVRAM.
+.TP
+\fB\--partitions
+print the contents of all the NVRAM partition headers.
+.TP
+\fB\--nvram-file \fIpath
+read nvram data from a given file rather than /dev/nvram. To capture NVRAM
+for later use, simply copy /dev/nvram into a file.
+.TP
+\fB\--verbose \fR(\fB-v\fR)
+be more verbose.
+.TP
+\fB\--help
+print usage information including other low level options useful for
+debugging nvram.
+.SH FILES
+/dev/nvram
+.SH AUTHOR
+Writtem by Todd Inglett, Nathan Fontenot, and Michael Strosaker
Added: trunk/powerpc-ibm-utils/doc/nvram/nvram.doxycfg
===================================================================
--- trunk/powerpc-ibm-utils/doc/nvram/nvram.doxycfg (rev 0)
+++ trunk/powerpc-ibm-utils/doc/nvram/nvram.doxycfg 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,1153 @@
+# Doxyfile 1.3.8
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = nvram
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = .
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of source
+# files, where putting all generated files in the same directory would otherwise
+# cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = NO
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is used
+# as the annotated text. Otherwise, the brief description is used as-is. If left
+# blank, the following values are used ("$name" is automatically replaced with the
+# name of the entity): "The $name class" "The $name widget" "The $name file"
+# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = ../../cmds/nvram.c ../../cmds/nvram.h
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse the
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this
+# option is superseded by the HAVE_DOT option below. This is only a fallback. It is
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes that
+# lay further from the root node will be omitted. Note that setting this option to
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that a graph may be further truncated if the graph's image dimensions are
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT).
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
Added: trunk/powerpc-ibm-utils/doc/ofpathname.8
===================================================================
--- trunk/powerpc-ibm-utils/doc/ofpathname.8 (rev 0)
+++ trunk/powerpc-ibm-utils/doc/ofpathname.8 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,30 @@
+.\"
+.\" Copyright (C) 2004 International Business Machines
+.\" Nathan Fontenot <nfont at austin.ibm.com>
+.\"
+.TH OFPATHNAME 8 "April 2004" Linux "Linux on Power Service Tools"
+.SH NAME
+ofpathname \- translate between Open Firmware and logical device names
+.SH SYNOPSIS
+\fB/usr/sbin/ofpathname \fR[\fB-lq\fR] \fIname
+.SH DESCRIPTION
+.I Ofpathname
+provides the ability to translate logical device names to their Open Firmware
+device path names for PoowerPC-64 systems. It can also translate an Open
+Firmware device path to its logical device name using the -l option.
+.SH OPTIONS
+.TP
+\fB\-l
+Translate the \fIname \fRparameter to the corresponding logical device name.
+.TP
+\fB\--quiet \fR(\fB\-q\fR)
+Do not report any failures, exit quietly.
+.TP
+\fB\--help \fR(\fB\-?\fR)
+print usage information.
+.SH AUTHOR
+Written by Nathan Fontenot
+.SH "SEE ALSO"
+.BR bootlist (8),
+.BR nvram (8)
+
Added: trunk/powerpc-ibm-utils/doc/snap.8
===================================================================
--- trunk/powerpc-ibm-utils/doc/snap.8 (rev 0)
+++ trunk/powerpc-ibm-utils/doc/snap.8 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,51 @@
+.\"
+.\" Copyright (C) 2002 - 2004 International Business Machines
+.\" Todd Inglett <tinglett at vnet.ibm.com>
+.\" Michael Strosaker <strosake at us.ibm.com>
+.\"
+.TH SNAP 8 "14 November 2003" Linux "Linux on Power Service Tools"
+.SH NAME
+snap \- generate a configuration snapshot for service
+.SH SYNOPSIS
+\fB/usr/sbin/snap \fR[\fB-ahv\fR] [\fB-d \fIdir\fR] [\fB-o \fIfile\fR]
+.SH DESCRIPTION
+The
+.I snap
+script copies several system status and config files and the output of
+several commands from the system into snap.tar.gz in the current directory.
+System servicers may ask that this be run in order collect data to diagnose
+a problem.
+
+.SH OPTIONS
+.TP
+.B \-a
+All data; collect detailed information (more files and output).
+.TP
+\fB\-d \fIdir
+Specify the directory where files and ouput will be collected (default:
+/tmp/ibmsupt).
+.TP
+.B \-h
+Print a help message.
+.TP
+\fB\-o \fIfile
+Specify the output path and filename (.tar required, .tar.gz optional)
+(default: snap.tar.gz).
+.TP
+.B \-v
+verbose output
+
+.SH FILES
+These are some of the files that are archived:
+.P
+/var/log/messages
+.br
+/var/log/platform
+.br
+/var/log/scanoutlog.*
+.br
+/proc (select files)
+.br
+/dev/nvram
+.br
+/etc/yaboot.conf
Added: trunk/powerpc-ibm-utils/powerpc-utils.spec
===================================================================
--- trunk/powerpc-ibm-utils/powerpc-utils.spec (rev 0)
+++ trunk/powerpc-ibm-utils/powerpc-utils.spec 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,29 @@
+%define name powerpc-utils
+%define version 1.0.2
+%define release 1
+Summary: Utilities for PowerPC Platforms
+Name: %{name}
+Version: %{version}
+Release: %{release}
+License: IBM Common Public License (CPL)
+Group: System Environment
+Source0: N/A
+BuildRoot: /tmp/%{name}-buildroot/
+Requires: /bin/bash, /bin/sed, /usr/bin/perl
+
+%description
+Utilities for PowerPC Platforms.
+
+%files
+%defattr(-,root,root)
+/usr/share/doc/packages/powerpc-utils/README
+/usr/share/doc/packages/powerpc-utils/COPYRIGHT
+/usr/sbin/nvram
+/usr/sbin/snap
+/usr/sbin/bootlist
+/usr/sbin/ofpathname
+/usr/share/man/man8/nvram.8
+/usr/share/man/man8/snap.8
+/usr/share/man/man8/bootlist.8
+/usr/share/man/man8/ofpathname.8
+
Added: trunk/powerpc-ibm-utils/rules.mk
===================================================================
--- trunk/powerpc-ibm-utils/rules.mk (rev 0)
+++ trunk/powerpc-ibm-utils/rules.mk 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,206 @@
+#
+# Common Makefile definitions
+#
+
+PWD = $(shell echo `pwd`)
+INSTALL = /usr/bin/install
+
+DOXYGEN = `which doxygen`
+
+# Name of the rpm spec file
+SPECFILENAME = powerpc-utils.spec
+
+# resolves the root directory at which this build is occuring
+ROOT_DIR = \
+ $(shell \
+ while [[ `pwd` != "/" ]]; \
+ do \
+ if [[ -f `pwd`/$(SPECFILENAME) ]]; \
+ then \
+ echo `pwd`; \
+ break; \
+ fi; \
+ cd ..; \
+ done;)
+
+# Full path to the rpm specfile
+SPECFILE = $(ROOT_DIR)/$(SPECFILENAME)
+
+# Find the correct command to build RPM's
+RPM = \
+ $(shell \
+ if [[ -a /bin/rpmbuild ]]; then \
+ echo "/bin/rpmbuild"; \
+ elif [[ -a /usr/bin/rpmbuild ]]; then \
+ echo "/usr/bin/rpmbuild"; \
+ elif [[ -a /bin/rpm ]]; then \
+ echo "/bin/rpm"; \
+ elif [[ -a /usr/bin/rpm ]]; then \
+ echo "/usr/bin/rpm"; \
+ else \
+ echo "rpm seems to be non-existant"; \
+ fi;)
+
+# Pull the version, release and project name info from the spec file
+VERSION := $(shell echo `grep "define version" $(SPECFILE) | cut -d' ' -f3`)
+RELEASE := $(shell echo `grep "define release" $(SPECFILE) | cut -d' ' -f3`)
+PROJECT := $(shell echo `grep "define name" $(SPECFILE) | cut -d' ' -f3`)
+
+# Generate the Major, Minor and Revision numbers from the version
+VERSION_LIST := $(subst ., ,$(VERSION))
+MAJOR_NO := $(word 1,$(VERSION_LIST))
+MINOR_NO := $(word 2,$(VERSION_LIST))
+REVISION_NO := $(word 3,$(VERSION_LIST))
+
+# Set this if you want to install to a base directory other than /
+DESTDIR ?=
+
+# Standard base directory names
+BIN_DIR = /usr/bin
+SBIN_DIR = /usr/sbin
+LIB_DIR = /usr/lib
+INC_DIR = /usr/include
+DOC_DIR = /usr/share/doc/packages/$(PROJECT)
+MAN_DIR = /usr/share/man/man8
+
+# Shipdir is where we put all the files to build an rpm
+SHIPDIR = /tmp/$(PROJECT)-buildroot
+
+# Source tarball name and build directory
+TARBALL = $(PROJECT)-$(VERSION).tar.gz
+TARBALL_FILES = Makefile rules.mk $(SPECFILENAME)
+TB_DIR = $(PROJECT)-$(VERSION)
+
+# Build a tarball of the source code
+BUILD_TARBALL = \
+ $(shell \
+ echo CVS > ./ignore; \
+ mkdir $(TB_DIR); \
+ cp -R $(SUBDIRS) $(TARBALL_FILES) $(TB_DIR); \
+ tar -zcf $(TARBALL) -X ./ignore $(TB_DIR); \
+ rm -rf ./ignore $(TB_DIR);)
+
+# Development snapshot builds
+DEVBALL = $(PROJECT)-$(VERSION)-`date +%Y%m%d`.tar.gz
+
+# Build a development snapshot of the source code
+BUILD_DEVBALL = \
+ $(shell \
+ echo CVS > ./ignore; \
+ mkdir $(TB_DIR); \
+ cp -R $(SUBDIRS) $(TARBALL_FILES) $(TB_DIR); \
+ tar -zcf $(DEVBALL) -X ./ignore $(TB_DIR); \
+ rm -rf ./ignore $(TB_DIR);)
+
+# Current build directory
+WORK_DIR = $(patsubst /%,%,$(subst $(ROOT_DIR),,$(PWD)))
+
+# You should always build with -Wall
+CFLAGS += -Wall
+
+# Uncomment this for debug builds
+CFLAGS += -g -DDEBUG
+
+# If you wish to have a log of installed files, define the file here
+INSTALL_LOG ?= $(ROOT_DIR)/install.log
+
+#
+# install_files - Install file(s) in the given location
+#
+# $1 - files to be installed
+# $2 - permissions to install file with
+# $3 - directory to install file to
+define install_files
+ $(INSTALL) -d -m 755 $3;
+ $(foreach f,$1, \
+ echo "Installing $(patsubst /%,%,$(WORK_DIR)/$f)"; \
+ $(INSTALL) -m $2 $f $3; \
+ $(if $(INSTALL_LOG),echo $3/$f >> $(INSTALL_LOG);,))
+endef
+
+#
+# The following are wrappers for calls to install_files for
+# installing files in known locations (i.e. /usr/bin). The args
+# to each of the wrappers are the same.
+#
+# $1 - files to be installed
+# $2 - prefix to install path for the files
+#
+define install_bin
+ $(call install_files,$1,755,$2/$(BIN_DIR))
+endef
+
+define install_sbin
+ $(call install_files,$1,744,$2/$(SBIN_DIR))
+endef
+
+define install_lib
+ $(call install_files,$1,755,$2/$(LIB_DIR))
+endef
+
+define install_inc
+ $(call install_files,$1,644,$2/$(INC_DIR))
+endef
+
+define install_doc
+ $(call install_files,$1,644,$2/$(DOC_DIR))
+endef
+
+define install_man
+ $(call install_files,$1,644,$2/$(MAN_DIR))
+endef
+
+#
+# uninstall_files - Uninstall file(s)
+#
+# $1 - files to be uninstalled
+# $2 - the directory the files to uninstall live in
+define uninstall_files
+ $(foreach f,$1, \
+ echo "Un-installing $(patsubst /%,%,$(WORK_DIR)/$f)"; \
+ rm -f $2/$f;)
+endef
+
+#
+# The following are wrappers for calls to uninstall_files for
+# removing files in known locations (i.e. /usr/bin). The args
+# to each of the wrappers are the same.
+#
+# $1 - files to be uninstalled
+# $2 - prefix to uninstall path for the files
+#
+define uninstall_bin
+ $(call uninstall_files,$1,$2/$(BIN_DIR))
+endef
+
+define uninstall_sbin
+ $(call uninstall_files,$1,$2/$(SBIN_DIR))
+endef
+
+define uninstall_lib
+ $(call uninstall_files,$1,$2/$(LIB_DIR))
+endef
+
+define uninstall_inc
+ $(call uninstall_files,$1,$2/$(INC_DIR))
+endef
+
+define uninstall_doc
+ $(call uninstall_files,$1,$2/$(DOC_DIR))
+endef
+
+define uninstall_man
+ $(call uninstall_files,$1,$2/$(MAN_DIR))
+endef
+
+
+# Define "CLEAN" as rm plus any files defined in this file that
+# the actual Makefile may not (or have to) know about
+CLEAN = /bin/rm -rf $(INSTALL_LOG) $(TB_DIR) *~
+
+# Default target for building object files
+%.o: %.c
+ @echo "CC $(WORK_DIR)/$@"
+ @$(CC) -c $(CFLAGS) $<
+
+
Added: trunk/powerpc-ibm-utils/scripts/Makefile
===================================================================
--- trunk/powerpc-ibm-utils/scripts/Makefile (rev 0)
+++ trunk/powerpc-ibm-utils/scripts/Makefile 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,19 @@
+#
+# Makefile for powerpc-utils/scripts
+#
+
+include ../rules.mk
+
+SCRIPTS = snap bootlist ofpathname
+
+all: $(SCRIPTS)
+
+install: all
+ @$(call install_sbin,$(SCRIPTS),$(DESTDIR))
+
+uninstall:
+ @$(call uninstall_sbin,$(SCRIPTS),$(DESTDIR))
+
+clean:
+ @echo "Cleaning up $(WORK_DIR) files..."
+ @rm -f *~
Added: trunk/powerpc-ibm-utils/scripts/bootlist
===================================================================
--- trunk/powerpc-ibm-utils/scripts/bootlist (rev 0)
+++ trunk/powerpc-ibm-utils/scripts/bootlist 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,331 @@
+#! /bin/bash
+# Copyright (c) 2004 International Business Machines
+# Common Public License Version 1.0 (see COPYRIGHT)
+#
+# bootlist - command to display and/or update the bootlist in nvram.
+#
+# author Nathan Fontenot <nfont at austin.ibm.com>
+#
+
+OFPATHNAME=/usr/sbin/ofpathname
+NVRAM=/usr/sbin/nvram
+
+#
+# usage
+#
+usage()
+{
+ echo "Usage: $0 -m {normal|service|both} [-o] [-r]"
+ echo " [-f <file>] [<device_list>]"
+ echo "View and update the system boot lists"
+ echo ""
+ echo "Required argument:"
+ echo " -m {normal|service|both}"
+ echo " Specify the boot mode for boolist manipulation"
+ echo "Optional arguments:"
+ echo " -o Display bootlist entries as logical device names"
+ echo " -r Display bootlist entries as Open Firmware device"
+ echo " path names"
+ echo " -f file Read the boolist device names from file"
+ echo " -?, --help display this help information and exit"
+ echo " <device_list> a space-separated list of devices, specified as"
+ echo " logical device names or OF device path names,"
+ echo " depending on whether the -o or -r option is specified"
+ echo ""
+ echo "Additional optional arguments for ethernet devices:"
+ echo " bserver=<IP address of BOOTP server>"
+ echo " gateway=<IP address of gateway>"
+ echo " client=<IP address of the client>"
+ echo " speed=<Network adapter speed>, default=auto"
+ echo " duplex=<mode of the network adapter>, default=auto"
+ echo ""
+}
+
+#
+# update_eth_dev
+# When specifying an ethernet device for the bootlist we need to also get
+# the additional parameters for ethernet devices (i.e gateway, speed, ...)
+#
+# Please NOTE: this routine does depend on global variables
+#
+update_eth_dev()
+{
+ local speed=auto
+ local duplex=auto
+ local bserver
+ local gateway
+ local client
+ local eth_index=$[$ctr]
+ local index=$[$ctr + 1]
+ local found=1
+
+ while [[ $found -eq 1 ]]; do
+ found=0
+ case ${LOGICAL_NAMES[$index]} in
+ speed*) speed=${LOGICAL_NAMES[$index]##*=}
+ found=1 ;;
+
+ duplex*) duplex=${LOGICAL_NAMES[$index]##*=}
+ found=1 ;;
+
+ bserver*) bserver=${LOGICAL_NAMES[$index]##*=}
+ found=1 ;;
+
+ gateway*) gateway=${LOGICAL_NAMES[$index]##*=}
+ found=1 ;;
+
+ client*) client=${LOGICAL_NAMES[$index]##*=}
+ found=1 ;;
+ esac
+
+ if [[ $found -eq 1 ]]; then
+ index=$[$index + 1]
+ ctr=$[$ctr + 1]
+ fi
+ done
+
+ # if no additional option was specified, just use the full
+ # path without options
+ if [[ -z $bserver && -z $gateway && -z $client ]]; then
+ OF_DEVPATH[$eth_index]=${OF_DEVPATH[$eth_index]}
+ return
+ fi
+
+ # Parameter Checking
+ if [[ -z $bserver || -z $gateway || -z $client ]]; then
+ echo "You must provide the IP Address for the BOOTP server, the"
+ echo "client, and the gateway when specifying an ethernet adapter"
+ usage
+ exit -1
+ fi
+
+ # update the ethernet device
+ OF_DEVPATH[$eth_index]=${OF_DEVPATH[$eth_index]}:speed=$speed,duplex=$duplex,$bserver,,$client,$gateway
+}
+
+#
+# parse_eth_info
+# Ethernet read from nvram (possibly) have additional data appended to
+# them specifying the gateway, speed, ...
+#
+# $1 ethernet device name
+# $2 ethernet device data
+#
+parse_eth_info()
+{
+ local eth_name=$1
+ local eth_info=${2##*:}
+
+ echo $eth_name
+
+ # first the speed
+ local item=${eth_info%%,*}
+ if [[ -n $item ]]; then
+ echo " speed = ${item##*=}"
+ fi
+
+ # then the duplex
+ eth_info=${eth_info#*,}
+ item=${eth_info%%,*}
+ if [[ -n $item ]]; then
+ echo " duplex = ${item##*=}"
+ fi
+
+ # then the BOOTP server
+ eth_info=${eth_info#*,}
+ item=${eth_info%%,*}
+ if [[ -n $item ]]; then
+ echo " BOOTP Server: $item"
+ fi
+
+ # then the Mask
+ eth_info=${eth_info#*,}
+ item=${eth_info%%,*}
+ if [[ -n $item ]]; then
+ echo " Mask: $item"
+ fi
+
+ # then the client
+ eth_info=${eth_info#*,}
+ item=${eth_info%%,*}
+ if [[ -n $item ]]; then
+ echo " Client: $item"
+ fi
+
+ # then the Gateway
+ eth_info=${eth_info#*,}
+ item=${eth_info%%,*}
+ if [[ -n $item ]]; then
+ echo " Gateway: $item"
+ fi
+}
+
+#
+# show_bootlist
+# Retrieve a bootlist from nvram and print its contents
+#
+# $1 bootlist to print
+#
+show_bootlist()
+{
+ local devlist=$1
+ local i
+
+ for i in `$NVRAM --print-config=${devlist} | sed 's/ /\n/g'`; do
+ if [[ $TRANSLATE_NAMES = "yes" ]]; then
+ name=`$OFPATHNAME -l $i`
+ if [[ -z $name ]]; then
+ echo "Could not translate $i to logical device name"
+ else
+ case $name in
+ eth*) parse_eth_info $name $i ;;
+ *) echo $name ;;
+ esac
+ fi
+ else
+ echo $i
+ fi
+ done
+}
+
+#
+# Main
+#
+
+# make sure we can parse names
+if [[ ! -a $OFPATHNAME ]]; then
+ echo "no $OFPATHNAME!!!"
+fi
+
+# make sure we can update nvram
+if [[ ! -a $NVRAM ]]; then
+ echo "no $NVRAM!!!"
+fi
+
+BOOTLIST_MODE=unknown
+
+#
+# Parse the command line arguements and put them into two parallel
+# arrays, one to hold the logical device name and one to hold the
+# corresponding open firmware device path.
+#
+typeset -i ctr=0
+
+while [[ -n $1 ]]; do
+ if [[ $1 = "-o" ]]; then
+ DISPLAY_BOOTLIST=yes
+ TRANSLATE_NAMES=yes
+ elif [[ $1 = "-r" ]]; then
+ DISPLAY_BOOTLIST=yes
+ elif [[ $1 = "-m" ]]; then
+ shift
+ if [[ ! -n $1 ]]; then
+ echo "did not specify \"normal\" or \"service\" mode with -m"
+ usage
+ exit -1
+ fi
+
+ if [[ $1 = "normal" ]]; then
+ BOOTLIST_MODE=boot-device
+ elif [[ $1 = "service" ]]; then
+ BOOTLIST_MODE=diag-device
+ elif [[ $1 = "both" ]]; then
+ BOOTLIST_MODE=$1
+ else
+ echo "invalid mode specified with -m; must be \"normal\", \"service\" or \"both\""
+ usage
+ exit -1
+ fi
+ elif [[ $1 = "-f" ]]; then
+ # get bootlist names from specified file
+ if [[ ! -a $2 ]]; then
+ echo "file $2 does not exist"
+ fi
+
+ for i in `cat $2 2>/dev/null`; do
+ LOGICAL_NAMES[$ctr]=$i
+ ctr=$[$ctr + 1]
+ done
+ shift
+ elif [[ $1 = -* ]]; then
+ # catch any illegal flags here
+ usage
+ exit -1
+ else
+ # add this element to the array
+ LOGICAL_NAMES[$ctr]=$1
+ ctr=$[$ctr + 1]
+ fi
+
+ shift
+done
+
+if [[ ${BOOTLIST_MODE} = "unknown" ]]; then
+ echo "The boot mode must be specified with the -m option"
+ usage
+ exit -1
+fi
+
+# Now we need to convert all of the logical device names to
+# open firmware device paths.
+if [[ ${#LOGICAL_NAMES[*]} -ne 0 ]]; then
+ ctr=0
+ while [[ $ctr -lt ${#LOGICAL_NAMES[*]} ]]; do
+ OF_DEVPATH[$ctr]=`$OFPATHNAME ${LOGICAL_NAMES[$ctr]}`
+ if [[ $? -ne 0 ]]; then
+ # Assume the name is an OF pathname
+ OF_DEVPATH[$ctr]=${LOGICAL_NAMES[$ctr]}
+ fi
+
+ # See if this is an ethernet adapter. If so, the next entries
+ # may be parameters for the bootlist entry.
+ ethdev=${OF_DEVPATH[$ctr]##/*/}
+ ethdev=${ethdev%%@*}
+ if [[ $ethdev = "ethernet" ]]; then
+ update_eth_dev
+ fi
+
+ # bootlist entries cannot exceed more than 255 chars
+ if [[ ${#OF_DEVPATH[$ctr]} -gt 255 ]]; then
+ echo "Bootlist entries cannot exceed 255 characters"
+ echo "${OF_DEVPATH[$ctr]}"
+ exit -1
+ fi
+
+ ctr=$[$ctr + 1]
+ done
+
+ # We cannot have a bootlist with more than five entries
+ if [[ ${#OF_DEVPATH[*]} -gt 5 ]]; then
+ echo "More than five entries cannot be specified in the bootlist"
+ exit -1
+ fi
+
+ # update the bootlist in nvram
+ if [[ $BOOTLIST_MODE = "both" ]]; then
+ $NVRAM --update-config "boot-device=${OF_DEVPATH[*]}" -pcommon
+ if [[ $? -ne 0 ]]; then
+ echo "Could not update service-mode bootlist"
+ fi
+
+ $NVRAM --update-config "diag-device=${OF_DEVPATH[*]}" -pcommon
+ if [[ $? -ne 0 ]]; then
+ echo "Could not update normal-mode bootlist"
+ fi
+ else
+ $NVRAM --update-config "${BOOTLIST_MODE}=${OF_DEVPATH[*]}" -pcommon
+ if [[ $? -ne 0 ]]; then
+ echo "Could not update bootlist!"
+ fi
+ fi
+fi
+
+# Display the bootlist if desired
+if [[ $DISPLAY_BOOTLIST = "yes" ]]; then
+ if [[ $BOOTLIST_MODE = "both" ]]; then
+ show_bootlist "boot-device"
+ show_bootlist "diag-device"
+ else
+ show_bootlist $BOOTLIST_MODE
+ fi
+fi
Property changes on: trunk/powerpc-ibm-utils/scripts/bootlist
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/powerpc-ibm-utils/scripts/ofpathname
===================================================================
--- trunk/powerpc-ibm-utils/scripts/ofpathname (rev 0)
+++ trunk/powerpc-ibm-utils/scripts/ofpathname 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,587 @@
+#! /bin/bash
+
+# Copyright (c) 2004 International Business Machines
+# Common Public License Version 1.0 (see COPYRIGHT)
+#
+# Author Nathan Fontenot <nfont at austin.ibm.com>
+
+#
+# ofpathname - This utility provides a mechanism for converting a logical
+# device name to an open firmware device path, and vice versa.
+#
+# TODO: This script doesn't handle floppy drives and token ring devices,
+# perhaps they should be added in at some point.
+#
+
+OFPATHNAME="ofpathname"
+VERSION="0.5"
+FIND=/usr/bin/find
+CAT=/bin/cat
+
+# Usage statemnet
+usage()
+{
+ echo "Usage: $OFPATHNAME [OPTION] DEVICE"
+ echo "Provide logical device names <==> Open Firmware Device Path Conversion"
+ echo ""
+ echo "Optional arguments."
+ echo " -l Convert Open Firmware device pathname to"
+ echo " logical device name."
+ echo " -q, --quiet do not report failures, exit quietly"
+ echo " -V, --version display version information and exit"
+ echo " -h, --help display this help information and exit"
+ echo ""
+}
+
+show_version()
+{
+ echo "$OFPATHNAME: Version $VERSION"
+ echo "Written by: Nathan Fontenot"
+}
+
+#
+# err
+# Common routine to print error messages for ofpathname. Since most of the
+# error messages can be generated in multiple places, we put all the text
+# here to avoid errors in duplicating the messages.
+#
+# The first and only parameteris the error message number, all of which
+# are defined below as ERR_*.
+#
+ERR_NO_OFPATH=1
+ERR_NO_SYSFS=2
+ERR_NO_SYSFS_DEVINFO=3
+ERR_NOT_CONFIG=4
+ERR_NO_LOGDEV=5
+err()
+{
+ local emsg=$1
+
+ if [[ -n $be_quiet ]]; then
+ exit 1
+ fi
+
+ case $emsg in
+ 1) echo "$OFPATHNAME: Could not retrieve Open Firmware device path"
+ echo " for logical device \"$DEVNAME_ARG\"." ;;
+
+ 2) echo "$OFPATHNAME: sysfs (/sys) is needed and does not appear"
+ echo " to be mounted on this system." ;;
+
+ 3) echo "$OFPATHNAME: Could not find sysfs information for logical"
+ echo " device \"$DEVNAME_ARG\"." ;;
+
+ 4) echo "$OFPATHANME: Logical device \"$DEVNAME_ARG\" does not appear"
+ echo " to be configured." ;;
+
+ 5) echo "$OFPATHNAME: Could not retrieve logical device name for"
+ echo " Open Firmware path \"$DEVNAME_ARG\"."
+ esac
+
+ exit 1
+}
+
+#
+# get_link
+# return the directory path that a link points to.
+# The only parameter is the link name.
+#
+get_link()
+{
+ local ln_name=$1;
+ echo `ls -l $ln_name 2>/dev/null | awk -F"->" '{print $2}'`
+}
+
+#
+# get_hbtl
+# Given a path that ends in an HBTL (Host:Bus:Target ID:LUN), break it apart
+# into its constituent parts in the global vars HOST, BUS, TARGET and LUN
+#
+# #1 path ending in HBTL
+#
+get_hbtl()
+{
+ local hbtl
+
+ HBTL=${1##*/}
+ hbtl=$HBTL
+
+ HOST=${hbtl%%:*}
+ hbtl=${hbtl#*:}
+ BUS=${hbtl%%:*}
+ hbtl=${hbtl#*:}
+ ID=${hbtl%%:*}
+ ID=`echo "ibase=10;obase=16; $ID" | bc | tr "[:upper:]" "[:lower:]"`
+ LUN=${hbtl#*:}
+ LUN=`echo "ibase=10;obase=16; $LUN" | bc | tr "[:upper:]" "[:lower:]"`
+}
+
+#
+# get_vdisk_no
+# Given a path that ends in an HBTL, convert the HBTL values into a
+# virtual disk number (not sure what the real terminology is for it).
+# To do the conversion, the HBTL (A:B:C:D) is split apart and
+# calculated as;
+# no = (0x8000 | B << 8 | C << 5 | D) * 1000000000000
+#
+# $1 path ending in HBTL
+#
+get_vdisk_no()
+{
+ get_hbtl $1
+
+ local B C D
+ typeset -i B C D
+
+ B=$((0x$ID << 8))
+ C=$((0x$BUS << 5))
+ D=$((0x$LUN))
+
+ local vdiskno vdisk
+ typeset -i vdiskno
+ vdiskno=$((0x8000 | $B | $C | $D ))
+ vdisk=${vdiskno##-}
+
+ vdisk=`echo \`bc << END
+ibase=10
+obase=16
+$vdisk
+END\``
+
+ local extrazeroes="000000000000"
+ echo $vdisk$extrazeroes
+}
+
+#
+# goto_dir
+# This looks for a given file in a given directory or any parents of the
+# given directory.
+#
+# $1 starting directory
+# $2 file to search for
+#
+goto_dir()
+{
+ local start_dir=$1
+ local fname=$2
+ local found=0
+
+ cd $start_dir
+ while [[ $PWD != "/" ]]; do
+ ls 2>/dev/null | grep $fname >/dev/null 2>&1
+ if [[ $? -eq 0 ]]; then
+ found=1
+ break
+ fi
+ cd ..
+ done
+
+ if [[ $found -eq 0 ]]; then
+ err $ERR_NO_SYSFS_DEVINFO
+ fi
+}
+
+#
+# logical_to_ofpathname
+# Conversion for logical device name to an Open Firmware device path
+#
+logical_to_ofpathname()
+{
+ local is_cdrom
+
+ # follow any links to the real device name
+ while [[ -L $DEVNAME ]]; do
+ DEVNAME=`get_link $DEVNAME`
+ done
+
+ while [[ -L /dev/$DEVNAME ]]; do
+ DEVNAME=`get_link /dev/$DEVNAME`
+ done
+
+ DEVICE=${DEVNAME##*/}
+ DEVNODE=${DEVICE%%[0-9]*}
+
+ # try to determine if this is a cdrom device
+ if [[ ${DEVNAME_ARG##*/} = cdrom ]]; then
+ is_cdrom=yes
+ elif [[ `get_link /dev/cdrom` = /dev/$DEVICE ]]; then
+ is_cdrom=yes
+ else
+ is_cdrom=no
+ fi
+
+ case $DEVICE in
+ eth*) l2of_ethernet ;;
+ sd* | sr*) l2of_scsi ;;
+ hd*) l2of_ide ;;
+ fd*) echo "no fd support yet" ;;
+ esac
+
+ if [[ -z $OF_PATH ]]; then
+ err $ERR_NO_OFPATH
+ fi
+
+ if [[ $is_cdrom = yes ]]; then
+ OF_PATH=$OFPATH:1\\ppc\\bootinfo.txt
+ fi
+
+ echo $OF_PATH
+}
+
+#
+# l2of_ide
+# Conversion routine for logical => OF path of ide devices
+#
+l2of_ide()
+{
+ cd /sys/block/$DEVICE
+ local link=`get_link "device"`
+ if [[ -z $link ]]; then
+ err $ERR_NO_SYSFS_DEVINFO
+ fi
+ cd $link
+
+ # get the device number
+ local devdir=${PWD##/*/}
+ local channelno=${devdir%%\.*}
+ local devno=${devdir##*\.}
+
+ goto_dir $PWD "devspec"
+
+ OF_PATH=`$CAT $PWD/devspec`
+ if [[ -z $OF_PATH ]]; then
+ err $ERR_NO_OFPATH
+ fi
+
+ # PCI ATA controller nodes (found on some Macs) have one child per IDE
+ # channel.
+ case `$CAT "/proc/device-tree/$OF_PATH/device_type"` in
+ pci-ata | pci-ide) OF_PATH=$OF_PATH/@$channelno ;;
+ esac
+
+ OF_PATH=$OF_PATH/disk@$devno
+}
+
+#
+# l2of_ethernet
+# Conversion routine for logical => OF path of ethernet devices
+#
+l2of_ethernet()
+{
+ local sysfs_eth=`$FIND /sys -name $DEVICE 2> /dev/null`
+ if [[ -z $sysfs_eth ]]; then
+ err $ERR_NOT_CONFIG
+ fi
+
+ OF_PATH=`$CAT $sysfs_eth/device/devspec`
+ if [[ -z $OF_PATH ]]; then
+ err $ERR_NO_OFPATH
+ fi
+}
+
+#
+# l2of_scsi
+# Converion routine for logical => OF path of scsi devices
+#
+l2of_scsi()
+{
+ local sysfs_sd=`$FIND /sys -name $DEVICE 2>/dev/null`
+ if [[ -z $sysfs_sd ]]; then
+ err $ERR_NOT_CONFIG
+ fi
+
+ # Move up directories until we find onew with a device link
+ goto_dir $sysfs_sd "device"
+
+ # follow the 'device' link
+ local link=`get_link "device"`
+ if [[ -z $link ]]; then
+ err $ERR_NO_SYSFS_DEVINFO
+ fi
+
+ get_hbtl $link
+ cd $link
+
+ # save the name of the current directory, we may need it later...
+ local device_dir=${PWD##/*/}
+
+ # move up directories until we find one with devspec information
+ goto_dir $PWD "devspec"
+
+ OF_PATH=`$CAT $PWD/devspec`
+ if [[ -z $OF_PATH ]]; then
+ err $ERR_NO_OFPATH
+ fi
+
+ local vdev=${OF_PATH%/*}
+
+ if [[ $vdev = "/vdevice" ]]; then
+ # get the v-device data
+ local i vdiskno
+ cd host*
+ cd target*
+ vdiskno=`get_vdisk_no $device_dir`
+
+ OF_PATH=$OF_PATH/disk\@$vdiskno
+
+ else
+ # make sure the "scsi" information is on the end of the path
+ local scsi_name=${OF_PATH##/*/}
+ scsi_name=${scsi_name%%@*}
+ if [[ $scsi_name != "scsi" ]]; then
+ scsi_name="scsi@$BUS"
+ OF_PATH=$OF_PATH/$scsi_name
+ fi
+
+ OF_PATH=$OF_PATH/sd@$ID,$LUN
+ fi
+}
+
+#
+# ofpathname_to_logical
+# Conversion for Open Firmware device paths to logical device names
+#
+ofpathname_to_logical()
+{
+ DEVPATH=${DEVNAME%/*}
+ DEVICE=${DEVNAME##/*/}
+ DEVTYPE=${DEVICE%\@*}
+
+ if [[ $DEVTYPE = "disk" && $DEVICE != ${DEVICE%:*} ]]; then
+ DEVTYPE=${DEVICE%:*}
+ fi
+
+ # Remove any possible cdrom data from DEVICE
+ if [[ ${DEVICE##*,} = "\ppc\bootinfo.txt" ||
+ ${DEVICE##*,} = \ppc\bootinfo.txt ]]; then
+ DEVICE=${DEVICE%,*}
+ fi
+
+ case $DEVTYPE in
+ sd* ) of2l_scsi ;;
+ v-scsi | disk ) of2l_vscsi
+ if [[ -z $LOGICAL_DEVNAME && $DEVTYPE = disk ]]; then
+ of2l_ide
+ fi ;;
+ eth* | l-lan ) of2l_ethernet ;;
+ disk* ) of2l_ide ;;
+ esac
+
+ if [[ -z $LOGICAL_DEVNAME ]]; then
+ err $ERR_NO_LOGDEV
+ fi
+
+ # See if this device is the cdrom
+ if [[ `get_link "/dev/cdrom"` = $LOGICAL_DEVNAME ]]; then
+ LOGICAL_DEVNAME="cdrom"
+ fi
+
+ echo $LOGICAL_DEVNAME
+}
+
+#
+# of2l_ide
+# Conversion routine for OF path => logical name for ide devices
+#
+of2l_ide()
+{
+ local dir
+
+ for dir in `$FIND /sys/block -name hd*`; do
+ # get devno
+ local devno=${DEVICE##*@}
+ devno=${devno%%:*}
+
+ cd $dir
+ local link=`get_link "device"`
+ if [[ -n $link ]]; then
+ cd $link
+
+ # see if this is the correct device
+ local this_devno=${PWD##*\.}
+ if [[ $devno -eq $this_devno ]]; then
+ goto_dir $PWD "devspec"
+ local devspec=`$CAT ./devspec 2>/dev/null`
+
+ if [[ $devspec = $DEVPATH ]]; then
+ LOGICAL_DEVNAME="${dir##*/}"
+ break
+ fi
+ fi
+ fi
+ done
+}
+
+#
+# of2l_ethernet
+# Conversion routine for OF path => logical names of ethernet devices
+#
+of2l_ethernet()
+{
+ local dir
+
+ # strip off ip info if present
+ local devname=${DEVNAME%%:*}
+
+ for dir in `$FIND /sys/class/net -name eth*`; do
+ goto_dir $dir device
+
+ local link=`get_link "device"`
+ if [[ -z $link ]]; then
+ err $ERR_NO_SYSFS_DEVINFO
+ fi
+
+ cd $link
+ local devspec=`$CAT ./devspec 2>/dev/null`
+
+ if [[ $devspec = $devname ]]; then
+ LOGICAL_DEVNAME="${dir##*/}"
+ return
+ fi
+ done
+}
+
+#
+# of2l_vscsi
+# Conversion routine for OF path => logical names of virtual scsi devices
+#
+of2l_vscsi()
+{
+ DEV_HBTL_NO=${DEVICE##*\@}
+
+ local dir
+ for dir in `$FIND /sys/block -name "s[dr]*"`; do
+ # go up to find directory with 'device' link
+ goto_dir $dir "device"
+
+ local link=`get_link "device"`
+ if [[ -z $link ]]; then
+ err $ERR_NO_SYSFS_DEVINFO
+ fi
+
+ local vdiskno=`get_vdisk_no $link`
+
+ cd $link
+ if [[ $vdiskno = $DEV_HBTL_NO ]]; then
+ goto_dir $PWD "devspec"
+ local devspec=`$CAT ./devspec 2>/dev/null`
+
+ if [[ $devspec = $DEVPATH ]]; then
+ LOGICAL_DEVNAME=${dir##/*/}
+ return
+ fi
+ fi
+ done
+}
+
+#
+# of2l_scsi
+# Conversion routine for OF path => logical names of scsi devices
+#
+of2l_scsi()
+{
+ DEV_TARGET=${DEVICE##*\@}
+ DEV_TARGET=${DEV_TARGET%%,*}
+ DEV_LUN=${DEVICE##*,}
+
+ # At this point DEV_LUN may be in the form X:Y, we're only interested
+ # in the X component.
+ DEV_LUN=${DEV_LUN%%:*}
+
+ local dir
+ for dir in `$FIND /sys/block -name s[dr]*`; do
+ # go up to find directory with 'device' link
+ goto_dir $dir "device"
+
+ local link=`get_link "device"`
+ if [[ -z $link ]]; then
+ err $ERR_NO_SYSFS_DEVINFO
+ fi
+
+ get_hbtl $link
+ cd $link
+
+ # save the name of the current directory, we may need it later...
+ local device_dir=${PWD##/*/}
+
+ if [[ $ID = $DEV_TARGET && $LUN = $DEV_LUN ]]; then
+ goto_dir $PWD "devspec"
+ local devspec=`$CAT ./devspec 2>/dev/null`
+
+ if [[ $devspec = $DEVPATH ]]; then
+ LOGICAL_DEVNAME="${dir##*/}"
+ return
+ fi
+
+ local scsi_name=${devspec##/*/}
+ scsi_name=${scsi_name%%@*}
+
+ if [[ $scsi_name != "scsi" ]]; then
+ scsi_name="scsi@$BUS"
+ devspec=$devspec/$scsi_name
+
+ if [[ $devspec = $DEVPATH ]]; then
+ LOGICAL_DEVNAME="${dir##*/}"
+ return
+ fi
+ fi
+ fi
+ done
+}
+
+#
+# Main
+#
+
+if [[ "$#" -eq 0 ]]; then
+ usage
+ exit 0
+fi
+
+# default: convert logical => OFpath
+do_of2l=0
+
+getopt -o "l:Vqh" -l "help,version,quiet" $@ > /dev/null 2>&1
+while [[ -n $1 ]]; do
+ case "$1" in
+ -l) do_of2l=1
+ DEVNAME_ARG=$2
+ shift ;;
+
+ -V | --version) show_version
+ exit 0 ;;
+
+ -q | --quiet) be_quiet=1 ;;
+
+ -h | --help) usage
+ exit 0 ;;
+ *) DEVNAME_ARG=$1 ;;
+ esac
+
+ shift
+done
+
+DEVNAME=$DEVNAME_ARG
+
+# double check device name
+if [[ -z $DEVNAME ]]; then
+ usage
+ exit 1
+fi
+
+# We need sysfs
+if [[ ! -d "/sys" ]]; then
+ err $ERR_NO_SYSFS
+ exit 1
+fi
+
+
+if [[ $do_of2l = "0" ]]; then
+ # logical devname => OF pathname
+ logical_to_ofpathname
+else
+ # OF pathnmae => logical devname
+ ofpathname_to_logical
+fi
+
+exit 0
Property changes on: trunk/powerpc-ibm-utils/scripts/ofpathname
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/powerpc-ibm-utils/scripts/snap
===================================================================
--- trunk/powerpc-ibm-utils/scripts/snap (rev 0)
+++ trunk/powerpc-ibm-utils/scripts/snap 2006-09-25 09:08:44 UTC (rev 164)
@@ -0,0 +1,345 @@
+#!/usr/bin/perl -w
+# Copyright (c) 2003, 2004 International Business Machines
+# Common Public License Version 1.0 (see COPYRIGHT)
+#
+# Author Todd Inglett <tinglett at us.ibm.com>
+# updates by Michael Strosaker <strosake at us.ibm.com>
+
+# Snapshot system config
+# Command-line parameters:
+# a: all data; collect detailed information (more files and output)
+# d dir: specify the directory where files and output will be collected
+# (default: /tmp/ibmsupt)
+# h: print this help message
+# o file: specify the output file (.tar required, .tar.gz optional)
+# (default: snap.tar.gz)
+# v: verbose output
+#
+# Exit codes (view with "echo $?" immediately after running):
+# 0: snap data was successfully captured
+# 1: invalid command line
+# 2: other fatal error
+
+use Getopt::Std;
+
+$outdir = "/tmp/ibmsupt"; # note NO trailing /
+$outfile = "snap.tar.gz"; # in the working dir.
+
+# Files to include in all snaps
+ at snap_paths_general = (
+ "/var/log/messages",
+ "/var/log/platform",
+ "/var/log/scanoutlog.*",
+# "/proc/bus/pci", ?? binary file
+ "/proc/cmdline",
+ "/proc/cpuinfo",
+# "/proc/device-tree", must summarize device-tree (a la dmpdt_chrp) instead of dumping whole thing
+ "/proc/devices",
+ "/proc/dma",
+ "/proc/filesystems",
+ "/proc/fs",
+ "/proc/ide",
+ "/proc/interrupts",
+ "/proc/iomem",
+ "/proc/ioports",
+ "/proc/loadavg",
+ "/proc/locks",
+ "/proc/mdstat",
+ "/proc/meminfo",
+ "/proc/misc",
+ "/proc/modules",
+ "/proc/mounts",
+ "/proc/net",
+ "/proc/partitions",
+ "/proc/pci",
+ "/proc/ppc64/lparcfg",
+ "/proc/ppc64/eeh",
+ "/proc/ppc64/pci",
+ "/proc/ppc64/systemcfg",
+ "/proc/scsi",
+ "/proc/slabinfo",
+ "/proc/stat",
+ "/proc/swaps",
+ "/proc/sys",
+ "/proc/sysvipc",
+ "/proc/uptime",
+ "/proc/version",
+ "/dev/nvram",
+ "/etc/fstab",
+ "/etc/raidtab",
+ "/etc/yaboot.conf",
+);
+
+# Files to include in all snaps on SuSE systems
+ at snap_paths_general_SuSE = (
+ "/etc/SuSE-release",
+ "/var/log/boot.msg",
+);
+
+# Files to include in all snaps on RedHat systems
+ at snap_paths_general_RedHat = (
+ "/etc/redhat-release",
+ "/var/log/dmesg",
+);
+
+# Files to include only in detailed snaps (-a option)
+ at snap_paths_detailed = (
+ "/proc/tty",
+ "/etc/inittab",
+ "/proc/ppc64/paca",
+ "/proc/ppc64/naca",
+ "/proc/ppc64/pmc",
+ "/proc/ppc64/pcifr",
+);
+
+# Command output to include in all snaps
+ at snap_commands_general = (
+ "lscfg -vp",
+ "ifconfig -a",
+);
+
+# Command output to include only in detailed snaps (-a option)
+ at snap_commands_detailed = (
+ "rpm -qa",
+);
+
+
+sub recurse_dir($); # function prototype
+
+sub error {
+ my ($fatal, $message) = @_;
+
+ if ($fatal) {
+ print "$0: $message\n";
+ exit 2;
+ }
+ else {
+ if ($opt_v) {
+ print "$0: $message\n";
+ }
+ }
+}
+
+sub print_usage {
+ print "Usage: $0 [-ahv] [-d dir] [-o file]\n\n";
+ print " Command-line parameters:\n";
+ print " a: all data; collect detailed information (more files and output)\n";
+ print " d dir: specify the directory where files and output will be collected\n";
+ print " (default: /tmp/ibmsupt)\n";
+ print " h: print this help message\n";
+ print " o file: specify the output file (.tar required, .tar.gz optional)\n";
+ print " (default: snap.tar.gz)\n";
+ print " v: verbose output\n\n";
+ print " Exit codes (view with \"echo \$?\" immediately after running):\n";
+ print " 0: snap data was successfully captured\n";
+ print " 1: invalid command line\n";
+ print " 2: other fatal error\n\n";
+}
+
+sub copy {
+ my ($source, $destination) = @_;
+ my ($dir, @path, $d, $blocksize, $buffer, $length);
+
+ #print "Copying $source...";
+
+ # Create directories, if necessary
+ $dir = substr $destination, 0, rindex($destination, "/");
+ if (!(-d $dir)) {
+ @path = split /\//, $dir;
+ if (substr($dir, 0, 1) eq "/") { # remove leading /
+ shift @path;
+ }
+ $dir = "";
+ foreach $d (@path) {
+ $dir .= "/" . $d;
+ if (!(-d $dir)) {
+ if (!mkdir($dir, 0644)) {
+ error(0, "Cannot create directory: $dir");
+ return;
+ }
+ }
+ }
+ }
+
+ # Copy file
+ if (!open(SRC, "<$source")) {
+ error(0, "Cannot open file for reading: $source");
+ return;
+ }
+ binmode SRC;
+ if (!open(DST, ">$destination")) {
+ error(0, "Cannot open file for writing: $destination");
+ goto copy_out;
+ }
+ binmode DST;
+
+ $blocksize = (stat SRC)[11] || 16384;
+ while ($length = sysread SRC, $buffer, $blocksize) {
+ if (!defined $length) {
+ next if $! =~ /^Interrupted/; # ^Z and fg
+ error(0, "System read error while reading $source: $!");
+ goto copy_out;
+ }
+ $offset = 0;
+ while ($length) {
+ if (!defined($written = syswrite DST, $buffer, $length, $offset)) {
+ error(0, "System write error while writing $destination: $!");
+ goto copy_out;
+ }
+ $length -= $written;
+ $offset += $written;
+ }
+ }
+
+copy_out:
+ #print "done.\n";
+ close SRC;
+ close DST;
+}
+
+sub recurse_dir ($) {
+ my ($dir) = @_;
+ my ($file) = "";
+ my (@contents) = ();
+
+ if (!opendir(DIR, $dir)) {
+ error(0, "Could not open directory $dir");
+ return;
+ }
+
+ @contents = readdir DIR;
+ closedir DIR;
+
+ foreach $file (@contents) {
+ if ($file eq "." or $file eq ".." or (-l "$dir/$file")) {
+ next;
+ }
+
+ if (-d "$dir/$file") {
+ recurse_dir "$dir/$file";
+ }
+ else {
+ copy "$dir/$file", $outdir."$dir/$file";
+ }
+ }
+}
+
+sub snap_paths {
+ my ($file, $dir, $search, @contents);
+
+ foreach $file (@_) {
+ if (-d $file) {
+ recurse_dir $file;
+ }
+ else {
+ # Check for wildcard (* in last character only)
+ if (substr($file, -1) eq "*") {
+ $dir = substr $file, 0, rindex($file, "/");
+ $search = substr $file, rindex($file, "/")+1, -1;
+
+ if (!opendir(DIR, $dir)) {
+ error(0, "Could not open directory $dir");
+ return;
+ }
+
+ @contents = readdir DIR;
+ closedir DIR;
+
+ foreach $file (@contents) {
+ if (substr($file, 0, length($search)) eq $search) {
+ copy "$dir/$file", $outdir."$dir/$file";
+ }
+ }
+ }
+ else {
+ copy $file, $outdir.$file;
+ }
+ }
+ }
+}
+
+sub snap_commands {
+ my ($path, @junk, @path, $filename, $command, $exit_value);
+
+ foreach $command (@_) {
+ # Retrieve the name of the binary to run (for output file name)
+ ($path, @junk) = split / /, $command;
+ @path = reverse(split /\//, $path);
+ $filename = shift @path;
+
+ system("$command > $outdir/$filename.out 2>&1");
+ if ($exit_value = $? >> 8) {
+ error(0, "\"$command\" returned $exit_value");
+ }
+ }
+}
+
+$< == 0 or error(1, "Must be executed as root");
+
+$opt_a = 0;
+$opt_d = 0;
+$opt_h = 0;
+$opt_o = 0;
+$opt_v = 0;
+if (!getopts('ad:ho:v')) {
+ print_usage;
+ exit 1;
+}
+
+if ($opt_h) {
+ print_usage;
+ exit 0;
+}
+
+if ($opt_d) {
+ $outdir = $opt_d;
+ if ($outdir eq "/") {
+ error(1, "Cannot use / as the output directory");
+ }
+ if (substr($outdir, -1) eq "/") {
+ $outdir = substr $outdir, 0, -1;
+ }
+}
+if ($opt_o) {
+ if ($opt_o !~ /.tar/) {
+ print "$0: The filename provided, $opt_o, does not contain .tar; using default filename $outfile\n";
+ }
+ else {
+ $outfile = $opt_o;
+ }
+}
+
+snap_paths(@snap_paths_general);
+
+# Check distro
+if (-e "/etc/SuSE-release") {
+ snap_paths(@snap_paths_general_SuSE);
+}
+elsif (-e "/etc/redhat-release") {
+ snap_paths(@snap_paths_general_RedHat);
+}
+
+# Run commands and capture output
+snap_commands(@snap_commands_general);
+
+# Gather detail files if requested (-a option)
+if ($opt_a) {
+ snap_paths(@snap_paths_detailed);
+ snap_commands(@snap_commands_detailed);
+}
+
+($basefile, $extension) = split /\.tar/, $outfile;
+
+system ("tar -cf $basefile.tar $outdir 2>/dev/null");
+
+if ($extension eq ".gz") {
+ system ("gzip -f $basefile.tar");
+}
+elsif ($extension eq "") { }
+else {
+ $outfile = "$basefile.tar";
+ print "$0: Unrecognized extension $extension\n";
+}
+
+print "output written to $outfile\n";
+exit 0;
Property changes on: trunk/powerpc-ibm-utils/scripts/snap
___________________________________________________________________
Name: svn:executable
+ *
More information about the Debootloaders-devel
mailing list