#!@PYTHON@ # # $Id$ # # Copyright (c) 2009 NLNet Labs. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) 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 OF THIS SOFTWARE, EVEN # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # """Simple command line interface to the command channel of the signer engine""" import optparse # # simple python command line interface to the signer engine # import sys import socket import os import subprocess def send_msg(msg, c_sock): """Send a message to the engine""" c_sock.send(msg) if msg[:4] == "stop": print "Sent stop command to engine" sys.exit(0) msg = '' chunk = '' prevchunk = '' while not (chunk == '\n' and prevchunk == '\n'): prevchunk = chunk chunk = c_sock.recv(1) if chunk == '': raise RuntimeError, "socket connection broken" if chunk != '\n': msg = msg + chunk else: print msg msg = "" def run(c_sock): """Read commands from stdin, and send them to the engine. Responses are printed to stdout""" print "cmd> ", cmd = sys.stdin.readline() cmd = cmd.strip() + "\n" while cmd: if cmd[:4] == "quit" or cmd[:4] == "exit": sys.exit(0) send_msg(cmd, c_sock) print "cmd> ", cmd = sys.stdin.readline() cmd = cmd.strip() + "\n" def engine_cli(args, file): """Command interface to engine, args is a List of strings, if not None or empty, the list will be concatenated and sent to the engine at host:port""" try: cl_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) print "connecting to " + file cl_sock.connect(file) if args and len(args) > 0: send_msg(" ".join(args) + "\n", cl_sock) else: run(cl_sock) cl_sock.shutdown(0) return 0 except socket.error, serr: if args and len(args) > 0: start_cmd = " ".join(args) if start_cmd[:5] == "start": try: p = subprocess.Popen("@OPENDNSSEC_SIGNER_ENGINE@", shell=True) retcode = os.waitpid(p.pid, 0)[1] if retcode < 0: print "Engine was terminated by signal" else: return retcode except OSError, e: print "Unable to start engine: " + e return 1 if (hasattr(serr, "errno") and serr.errno == 2) or \ isinstance(serr, socket.error) and serr[0] == 2: print "Unable to connect to engine. It might not be running." else: print "Error opening domain socket %s: %s" % (file, str(serr)) print serr.__class__ raise serr return 1 def parse_args(): """Parse options""" try: parser = optparse.OptionParser("Usage: %prog [options] command\n\nThe command 'help' shows a complete list of commands") #parser.add_option("-n", "--host", dest="host", default="localhost") parser.add_option("-a", "--all", action="store_true", dest="all", default=False, help="when using the command sign, sign all zones") parser.add_option("-f", "--file", dest="file", help="connect to domain socket ", default="@localstatedir@".replace("${prefix}", "@prefix@")+\ os.sep + \ "run" + os.sep +\ "opendnssec" + os.sep + \ "engine.sock") (options, arguments) = parser.parse_args() if options.all: arguments.append("--all") return engine_cli(arguments, options.file) except ValueError, vae: print str(vae) return 1 if __name__ == "__main__": # if we have no arguments, go to interactive mode try: result = parse_args() sys.exit(result) except Exception, e: sys.exit(2)