diff options
author | takeshi_hoshina <takeshi_hoshina@mail.toyota.co.jp> | 2020-11-02 11:07:33 +0900 |
---|---|---|
committer | takeshi_hoshina <takeshi_hoshina@mail.toyota.co.jp> | 2020-11-02 11:07:33 +0900 |
commit | 1c7d6584a7811b7785ae5c1e378f14b5ba0971cf (patch) | |
tree | cd70a267a5ef105ba32f200aa088e281fbd85747 /external/poky/bitbake/bin | |
parent | 4204309872da5cb401cbb2729d9e2d4869a87f42 (diff) |
basesystem-jjsandbox/ToshikazuOhiwa/master-jj
recipes
Diffstat (limited to 'external/poky/bitbake/bin')
-rwxr-xr-x | external/poky/bitbake/bin/bitbake | 16 | ||||
-rwxr-xr-x | external/poky/bitbake/bin/bitbake-diffsigs | 14 | ||||
-rwxr-xr-x | external/poky/bitbake/bin/bitbake-hashclient | 170 | ||||
-rwxr-xr-x | external/poky/bitbake/bin/bitbake-hashserv | 62 | ||||
-rwxr-xr-x | external/poky/bitbake/bin/bitbake-layers | 16 | ||||
-rwxr-xr-x | external/poky/bitbake/bin/bitbake-prserv | 4 | ||||
-rwxr-xr-x | external/poky/bitbake/bin/bitbake-selftest | 16 | ||||
-rwxr-xr-x | external/poky/bitbake/bin/bitbake-worker | 22 | ||||
-rwxr-xr-x | external/poky/bitbake/bin/bitdoc | 14 | ||||
-rwxr-xr-x | external/poky/bitbake/bin/git-make-shallow | 4 | ||||
-rwxr-xr-x | external/poky/bitbake/bin/toaster | 31 | ||||
-rwxr-xr-x | external/poky/bitbake/bin/toaster-eventreplay | 17 |
12 files changed, 289 insertions, 97 deletions
diff --git a/external/poky/bitbake/bin/bitbake b/external/poky/bitbake/bin/bitbake index 57dec2a4..6c73710c 100755 --- a/external/poky/bitbake/bin/bitbake +++ b/external/poky/bitbake/bin/bitbake @@ -1,6 +1,4 @@ #!/usr/bin/env python3 -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- # # Copyright (C) 2003, 2004 Chris Larson # Copyright (C) 2003, 2004 Phil Blundell @@ -9,18 +7,8 @@ # Copyright (C) 2005 ROAD GmbH # Copyright (C) 2006 Richard Purdie # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. +# SPDX-License-Identifier: GPL-2.0-only # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import os import sys @@ -38,7 +26,7 @@ from bb.main import bitbake_main, BitBakeConfigParameters, BBMainException if sys.getfilesystemencoding() != "utf-8": sys.exit("Please use a locale setting which supports UTF-8 (such as LANG=en_US.UTF-8).\nPython can't change the filesystem locale after loading so we need a UTF-8 when Python starts or things won't work.") -__version__ = "1.40.0" +__version__ = "1.46.0" if __name__ == "__main__": if __version__ != bb.__version__: diff --git a/external/poky/bitbake/bin/bitbake-diffsigs b/external/poky/bitbake/bin/bitbake-diffsigs index fa430bb3..19420a2d 100755 --- a/external/poky/bitbake/bin/bitbake-diffsigs +++ b/external/poky/bitbake/bin/bitbake-diffsigs @@ -5,18 +5,8 @@ # # Copyright (C) 2012-2013, 2017 Intel Corporation # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. +# SPDX-License-Identifier: GPL-2.0-only # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import os import sys @@ -105,7 +95,7 @@ def recursecb(key, hash1, hash2): out2 = bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb, color=color) for change in out2: for line in change.splitlines(): - recout.append(' ' + line) + recout.append(' ' + line) return recout diff --git a/external/poky/bitbake/bin/bitbake-hashclient b/external/poky/bitbake/bin/bitbake-hashclient new file mode 100755 index 00000000..29ab65f1 --- /dev/null +++ b/external/poky/bitbake/bin/bitbake-hashclient @@ -0,0 +1,170 @@ +#! /usr/bin/env python3 +# +# Copyright (C) 2019 Garmin Ltd. +# +# SPDX-License-Identifier: GPL-2.0-only +# + +import argparse +import hashlib +import logging +import os +import pprint +import sys +import threading +import time + +try: + import tqdm + ProgressBar = tqdm.tqdm +except ImportError: + class ProgressBar(object): + def __init__(self, *args, **kwargs): + pass + + def __enter__(self): + return self + + def __exit__(self, *args, **kwargs): + pass + + def update(self): + pass + +sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)), 'lib')) + +import hashserv + +DEFAULT_ADDRESS = 'unix://./hashserve.sock' +METHOD = 'stress.test.method' + + +def main(): + def handle_stats(args, client): + if args.reset: + s = client.reset_stats() + else: + s = client.get_stats() + pprint.pprint(s) + return 0 + + def handle_stress(args, client): + def thread_main(pbar, lock): + nonlocal found_hashes + nonlocal missed_hashes + nonlocal max_time + + client = hashserv.create_client(args.address) + + for i in range(args.requests): + taskhash = hashlib.sha256() + taskhash.update(args.taskhash_seed.encode('utf-8')) + taskhash.update(str(i).encode('utf-8')) + + start_time = time.perf_counter() + l = client.get_unihash(METHOD, taskhash.hexdigest()) + elapsed = time.perf_counter() - start_time + + with lock: + if l: + found_hashes += 1 + else: + missed_hashes += 1 + + max_time = max(elapsed, max_time) + pbar.update() + + max_time = 0 + found_hashes = 0 + missed_hashes = 0 + lock = threading.Lock() + total_requests = args.clients * args.requests + start_time = time.perf_counter() + with ProgressBar(total=total_requests) as pbar: + threads = [threading.Thread(target=thread_main, args=(pbar, lock), daemon=False) for _ in range(args.clients)] + for t in threads: + t.start() + + for t in threads: + t.join() + + elapsed = time.perf_counter() - start_time + with lock: + print("%d requests in %.1fs. %.1f requests per second" % (total_requests, elapsed, total_requests / elapsed)) + print("Average request time %.8fs" % (elapsed / total_requests)) + print("Max request time was %.8fs" % max_time) + print("Found %d hashes, missed %d" % (found_hashes, missed_hashes)) + + if args.report: + with ProgressBar(total=args.requests) as pbar: + for i in range(args.requests): + taskhash = hashlib.sha256() + taskhash.update(args.taskhash_seed.encode('utf-8')) + taskhash.update(str(i).encode('utf-8')) + + outhash = hashlib.sha256() + outhash.update(args.outhash_seed.encode('utf-8')) + outhash.update(str(i).encode('utf-8')) + + client.report_unihash(taskhash.hexdigest(), METHOD, outhash.hexdigest(), taskhash.hexdigest()) + + with lock: + pbar.update() + + parser = argparse.ArgumentParser(description='Hash Equivalence Client') + parser.add_argument('--address', default=DEFAULT_ADDRESS, help='Server address (default "%(default)s")') + parser.add_argument('--log', default='WARNING', help='Set logging level') + + subparsers = parser.add_subparsers() + + stats_parser = subparsers.add_parser('stats', help='Show server stats') + stats_parser.add_argument('--reset', action='store_true', + help='Reset server stats') + stats_parser.set_defaults(func=handle_stats) + + stress_parser = subparsers.add_parser('stress', help='Run stress test') + stress_parser.add_argument('--clients', type=int, default=10, + help='Number of simultaneous clients') + stress_parser.add_argument('--requests', type=int, default=1000, + help='Number of requests each client will perform') + stress_parser.add_argument('--report', action='store_true', + help='Report new hashes') + stress_parser.add_argument('--taskhash-seed', default='', + help='Include string in taskhash') + stress_parser.add_argument('--outhash-seed', default='', + help='Include string in outhash') + stress_parser.set_defaults(func=handle_stress) + + args = parser.parse_args() + + logger = logging.getLogger('hashserv') + + level = getattr(logging, args.log.upper(), None) + if not isinstance(level, int): + raise ValueError('Invalid log level: %s' % args.log) + + logger.setLevel(level) + console = logging.StreamHandler() + console.setLevel(level) + logger.addHandler(console) + + func = getattr(args, 'func', None) + if func: + client = hashserv.create_client(args.address) + # Try to establish a connection to the server now to detect failures + # early + client.connect() + + return func(args, client) + + return 0 + + +if __name__ == '__main__': + try: + ret = main() + except Exception: + ret = 1 + import traceback + traceback.print_exc() + sys.exit(ret) diff --git a/external/poky/bitbake/bin/bitbake-hashserv b/external/poky/bitbake/bin/bitbake-hashserv new file mode 100755 index 00000000..1bc1f91f --- /dev/null +++ b/external/poky/bitbake/bin/bitbake-hashserv @@ -0,0 +1,62 @@ +#! /usr/bin/env python3 +# +# Copyright (C) 2018 Garmin Ltd. +# +# SPDX-License-Identifier: GPL-2.0-only +# + +import os +import sys +import logging +import argparse +import sqlite3 + +sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)), 'lib')) + +import hashserv + +VERSION = "1.0.0" + +DEFAULT_BIND = 'unix://./hashserve.sock' + + +def main(): + parser = argparse.ArgumentParser(description='Hash Equivalence Reference Server. Version=%s' % VERSION, + epilog='''The bind address is the path to a unix domain socket if it is + prefixed with "unix://". Otherwise, it is an IP address + and port in form ADDRESS:PORT. To bind to all addresses, leave + the ADDRESS empty, e.g. "--bind :8686". To bind to a specific + IPv6 address, enclose the address in "[]", e.g. + "--bind [::1]:8686"''' + ) + + parser.add_argument('--bind', default=DEFAULT_BIND, help='Bind address (default "%(default)s")') + parser.add_argument('--database', default='./hashserv.db', help='Database file (default "%(default)s")') + parser.add_argument('--log', default='WARNING', help='Set logging level') + + args = parser.parse_args() + + logger = logging.getLogger('hashserv') + + level = getattr(logging, args.log.upper(), None) + if not isinstance(level, int): + raise ValueError('Invalid log level: %s' % args.log) + + logger.setLevel(level) + console = logging.StreamHandler() + console.setLevel(level) + logger.addHandler(console) + + server = hashserv.create_server(args.bind, args.database) + server.serve_forever() + return 0 + + +if __name__ == '__main__': + try: + ret = main() + except Exception: + ret = 1 + import traceback + traceback.print_exc() + sys.exit(ret) diff --git a/external/poky/bitbake/bin/bitbake-layers b/external/poky/bitbake/bin/bitbake-layers index d184011e..149f1b1a 100755 --- a/external/poky/bitbake/bin/bitbake-layers +++ b/external/poky/bitbake/bin/bitbake-layers @@ -7,18 +7,8 @@ # Copyright (C) 2011 Mentor Graphics Corporation # Copyright (C) 2011-2015 Intel Corporation # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. +# SPDX-License-Identifier: GPL-2.0-only # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import logging import os @@ -62,7 +52,9 @@ def main(): # Need to re-run logger_create with color argument # (will be the same logger since it has the same name) - bb.msg.logger_create('bitbake-layers', output=sys.stdout, color=global_args.color) + bb.msg.logger_create('bitbake-layers', output=sys.stdout, + color=global_args.color, + level=logger.getEffectiveLevel()) plugins = [] tinfoil = bb.tinfoil.Tinfoil(tracking=True) diff --git a/external/poky/bitbake/bin/bitbake-prserv b/external/poky/bitbake/bin/bitbake-prserv index f38d2dd8..1e9b6cbc 100755 --- a/external/poky/bitbake/bin/bitbake-prserv +++ b/external/poky/bitbake/bin/bitbake-prserv @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-only +# + import os import sys,logging import optparse diff --git a/external/poky/bitbake/bin/bitbake-selftest b/external/poky/bitbake/bin/bitbake-selftest index cfa7ac53..041a2719 100755 --- a/external/poky/bitbake/bin/bitbake-selftest +++ b/external/poky/bitbake/bin/bitbake-selftest @@ -2,18 +2,8 @@ # # Copyright (C) 2012 Richard Purdie # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. +# SPDX-License-Identifier: GPL-2.0-only # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import os import sys, logging @@ -22,6 +12,7 @@ sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)), 'lib import unittest try: import bb + import hashserv import layerindexlib except RuntimeError as exc: sys.exit(str(exc)) @@ -33,7 +24,10 @@ tests = ["bb.tests.codeparser", "bb.tests.event", "bb.tests.fetch", "bb.tests.parse", + "bb.tests.persist_data", + "bb.tests.runqueue", "bb.tests.utils", + "hashserv.tests", "layerindexlib.tests.layerindexobj", "layerindexlib.tests.restapi", "layerindexlib.tests.cooker"] diff --git a/external/poky/bitbake/bin/bitbake-worker b/external/poky/bitbake/bin/bitbake-worker index 0e669054..97cc0fd6 100755 --- a/external/poky/bitbake/bin/bitbake-worker +++ b/external/poky/bitbake/bin/bitbake-worker @@ -1,4 +1,7 @@ #!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-only +# import os import sys @@ -62,7 +65,6 @@ if 0: format_str = "%(levelname)s: %(message)s" conlogformat = bb.msg.BBLogFormatter(format_str) consolelog = logging.FileHandler(logfilename) - bb.msg.addDefaultlogFilter(consolelog) consolelog.setFormatter(conlogformat) logger.addHandler(consolelog) @@ -136,7 +138,7 @@ def sigterm_handler(signum, frame): os.killpg(0, signal.SIGTERM) sys.exit() -def fork_off_task(cfg, data, databuilder, workerdata, fn, task, taskname, appends, taskdepdata, extraconfigdata, quieterrors=False, dry_run_exec=False): +def fork_off_task(cfg, data, databuilder, workerdata, fn, task, taskname, taskhash, unihash, appends, taskdepdata, extraconfigdata, quieterrors=False, dry_run_exec=False): # We need to setup the environment BEFORE the fork, since # a fork() or exec*() activates PSEUDO... @@ -233,10 +235,13 @@ def fork_off_task(cfg, data, databuilder, workerdata, fn, task, taskname, append the_data.setVar(varname, value) bb.parse.siggen.set_taskdata(workerdata["sigdata"]) + if "newhashes" in workerdata: + bb.parse.siggen.set_taskhashes(workerdata["newhashes"]) ret = 0 the_data = bb_cache.loadDataFull(fn, appends) - the_data.setVar('BB_TASKHASH', workerdata["runq_hash"][task]) + the_data.setVar('BB_TASKHASH', taskhash) + the_data.setVar('BB_UNIHASH', unihash) bb.utils.set_process_name("%s:%s" % (the_data.getVar("PN"), taskname.replace("do_", ""))) @@ -375,6 +380,7 @@ class BitbakeWorker(object): self.handle_item(b"cookerconfig", self.handle_cookercfg) self.handle_item(b"extraconfigdata", self.handle_extraconfigdata) self.handle_item(b"workerdata", self.handle_workerdata) + self.handle_item(b"newtaskhashes", self.handle_newtaskhashes) self.handle_item(b"runtask", self.handle_runtask) self.handle_item(b"finishnow", self.handle_finishnow) self.handle_item(b"ping", self.handle_ping) @@ -407,12 +413,16 @@ class BitbakeWorker(object): def handle_workerdata(self, data): self.workerdata = pickle.loads(data) - bb.msg.loggerDefaultDebugLevel = self.workerdata["logdefaultdebug"] + bb.msg.loggerDefaultLogLevel = self.workerdata["logdefaultlevel"] bb.msg.loggerDefaultVerbose = self.workerdata["logdefaultverbose"] bb.msg.loggerVerboseLogs = self.workerdata["logdefaultverboselogs"] bb.msg.loggerDefaultDomains = self.workerdata["logdefaultdomain"] for mc in self.databuilder.mcdata: self.databuilder.mcdata[mc].setVar("PRSERV_HOST", self.workerdata["prhost"]) + self.databuilder.mcdata[mc].setVar("BB_HASHSERVE", self.workerdata["hashservaddr"]) + + def handle_newtaskhashes(self, data): + self.workerdata["newhashes"] = pickle.loads(data) def handle_ping(self, _): workerlog_write("Handling ping\n") @@ -427,10 +437,10 @@ class BitbakeWorker(object): sys.exit(0) def handle_runtask(self, data): - fn, task, taskname, quieterrors, appends, taskdepdata, dry_run_exec = pickle.loads(data) + fn, task, taskname, taskhash, unihash, quieterrors, appends, taskdepdata, dry_run_exec = pickle.loads(data) workerlog_write("Handling runtask %s %s %s\n" % (task, fn, taskname)) - pid, pipein, pipeout = fork_off_task(self.cookercfg, self.data, self.databuilder, self.workerdata, fn, task, taskname, appends, taskdepdata, self.extraconfigdata, quieterrors, dry_run_exec) + pid, pipein, pipeout = fork_off_task(self.cookercfg, self.data, self.databuilder, self.workerdata, fn, task, taskname, taskhash, unihash, appends, taskdepdata, self.extraconfigdata, quieterrors, dry_run_exec) self.build_pids[pid] = task self.build_pipes[pid] = runQueueWorkerPipe(pipein, pipeout) diff --git a/external/poky/bitbake/bin/bitdoc b/external/poky/bitbake/bin/bitdoc index 27446788..9bd02be6 100755 --- a/external/poky/bitbake/bin/bitdoc +++ b/external/poky/bitbake/bin/bitdoc @@ -1,21 +1,9 @@ #!/usr/bin/env python3 -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- # # Copyright (C) 2005 Holger Hans Peter Freyther # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. +# SPDX-License-Identifier: GPL-2.0-only # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import optparse, os, sys diff --git a/external/poky/bitbake/bin/git-make-shallow b/external/poky/bitbake/bin/git-make-shallow index 296d3a3d..57069f7e 100755 --- a/external/poky/bitbake/bin/git-make-shallow +++ b/external/poky/bitbake/bin/git-make-shallow @@ -1,4 +1,8 @@ #!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-only +# + """git-make-shallow: make the current git repository shallow Remove the history of the specified revisions, then optionally filter the diff --git a/external/poky/bitbake/bin/toaster b/external/poky/bitbake/bin/toaster index ecf66fa5..6b90ee18 100755 --- a/external/poky/bitbake/bin/toaster +++ b/external/poky/bitbake/bin/toaster @@ -3,27 +3,18 @@ # toaster - shell script to start Toaster # Copyright (C) 2013-2015 Intel Corp. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# SPDX-License-Identifier: GPL-2.0-or-later # -# You should have received a copy of the GNU General Public License -# along with this program. If not, see http://www.gnu.org/licenses/. HELP=" -Usage: source toaster start|stop [webport=<address:port>] [noweb] [nobuild] [toasterdir] +Usage 1: source toaster start|stop [webport=<address:port>] [noweb] [nobuild] [toasterdir] Optional arguments: [nobuild] Setup the environment for capturing builds with toaster but disable managed builds [noweb] Setup the environment for capturing builds with toaster but don't start the web server [webport] Set the development server (default: localhost:8000) [toasterdir] Set absolute path to be used as TOASTER_DIR (default: BUILDDIR/../) +Usage 2: source toaster manage [createsuperuser|lsupdates|migrate|makemigrations|checksettings|collectstatic|...] " custom_extention() @@ -218,13 +209,21 @@ for param in $*; do toasterdir=*) TOASTERDIR="${param#*=}" ;; + manage ) + CMD=$param + manage_cmd="" + ;; --help) echo "$HELP" return 0 ;; *) - echo "$HELP" - return 1 + if [ "manage" == "$CMD" ] ; then + manage_cmd="$manage_cmd $param" + else + echo "$HELP" + exit 1 + fi ;; esac @@ -316,6 +315,10 @@ case $CMD in stop_system echo "Successful ${CMD}." ;; + manage ) + cd $BBBASEDIR/lib/toaster + $MANAGE $manage_cmd + ;; esac custom_extention toaster_postpend $CMD $ADDR_PORT diff --git a/external/poky/bitbake/bin/toaster-eventreplay b/external/poky/bitbake/bin/toaster-eventreplay index 80967a09..8fa4ab71 100755 --- a/external/poky/bitbake/bin/toaster-eventreplay +++ b/external/poky/bitbake/bin/toaster-eventreplay @@ -1,25 +1,12 @@ #!/usr/bin/env python3 -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- # # Copyright (C) 2014 Alex Damian # +# SPDX-License-Identifier: GPL-2.0-only +# # This file re-uses code spread throughout other Bitbake source files. # As such, all other copyrights belong to their own right holders. # -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. """ This command takes a filename as a single parameter. The filename is read |