ia64/xen-unstable

changeset 1717:bae23a1177c6

bitkeeper revision 1.1049 (40ec4ff2Ste8alBZJQMMHa4bDp5ShQ)

Merge scramble.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into scramble.cl.cam.ac.uk:/local/scratch/kaf24/hp.bk
author kaf24@scramble.cl.cam.ac.uk
date Wed Jul 07 19:33:06 2004 +0000 (2004-07-07)
parents 15cbfb844361 05488465ed73
children 98bb9542a5bc
files .rootkeys tools/Makefile tools/libxutil/sys_net.c tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendMigrate.py tools/python/xen/xm/create.py tools/xfrd/Make.xfrd tools/xfrd/connection.c tools/xfrd/connection.h tools/xfrd/sxpr_parser.c tools/xfrd/sxpr_parser.h tools/xfrd/xen_domain.c tools/xfrd/xfrd.c tools/xfrd/xfrdClient.py
line diff
     1.1 --- a/.rootkeys	Wed Jul 07 18:57:28 2004 +0000
     1.2 +++ b/.rootkeys	Wed Jul 07 19:33:06 2004 +0000
     1.3 @@ -297,6 +297,8 @@ 40e9808eCsmywryb036TdtRMJHDMmQ tools/xfr
     1.4  40e9808e99OcM547cKMTfmCVSoWVAw tools/xfrd/select.h
     1.5  40e9808e5_PLdodqVOSx0b4T_f5aeg tools/xfrd/sxpr.c
     1.6  40e9808e0O4sHZtkDv5hlSqjYcdQAQ tools/xfrd/sxpr.h
     1.7 +40ec1cc6SIiGbynOi-1NtPesOlzF-Q tools/xfrd/sxpr_parser.c
     1.8 +40ec1cc6wpvvGxZiq4EFvNOcw0tUFg tools/xfrd/sxpr_parser.h
     1.9  40e9808eF3NVldqRNS5IHM8gbFAvpw tools/xfrd/xdr.c
    1.10  40e9808ezXzoRHm7pybXU69NtnjimA tools/xfrd/xdr.h
    1.11  40e9808edpUtf4bJ8IbqClPJj_OvbA tools/xfrd/xen_domain.c
     2.1 --- a/tools/Makefile	Wed Jul 07 18:57:28 2004 +0000
     2.2 +++ b/tools/Makefile	Wed Jul 07 19:33:06 2004 +0000
     2.3 @@ -6,6 +6,7 @@ all:
     2.4  	$(MAKE) -C examples
     2.5  	$(MAKE) -C xentrace
     2.6  	$(MAKE) -C python
     2.7 +	$(MAKE) -C xfrd
     2.8  
     2.9  install: all
    2.10  	$(MAKE) -C libxutil install
    2.11 @@ -14,6 +15,7 @@ install: all
    2.12  	$(MAKE) -C examples install
    2.13  	$(MAKE) -C xentrace install
    2.14  	$(MAKE) -C python install
    2.15 +	$(MAKE) -C xfrd install
    2.16  
    2.17  dist: $(TARGET)
    2.18  	$(MAKE) prefix=`pwd`/../../install dist=yes install
    2.19 @@ -26,4 +28,5 @@ clean:
    2.20  	$(MAKE) -C examples clean
    2.21  	$(MAKE) -C xentrace clean
    2.22  	$(MAKE) -C python clean
    2.23 +	$(MAKE) -C xfrd clean
    2.24  
     3.1 --- a/tools/libxutil/sys_net.c	Wed Jul 07 18:57:28 2004 +0000
     3.2 +++ b/tools/libxutil/sys_net.c	Wed Jul 07 19:33:06 2004 +0000
     3.3 @@ -18,6 +18,12 @@
     3.4  #include "sys_net.h"
     3.5  #include "sys_string.h"
     3.6  
     3.7 +#ifdef __KERNEL__
     3.8 +#  include <linux/errno.h>
     3.9 +#else
    3.10 +#  include <errno.h>
    3.11 +#endif
    3.12 +
    3.13  /** @file
    3.14   * All network data are kept in network order and only converted to
    3.15   * host order for display. Network data includes IP addresses, port numbers and
    3.16 @@ -80,7 +86,7 @@ inline static int indexof(const char *s,
    3.17   *
    3.18   * @param s input string
    3.19   * @param address where to put the address
    3.20 - * @return 0 on success, -1 on error
    3.21 + * @return 0 on success, negative on error
    3.22   */
    3.23  int get_inet_addr(const char *s, unsigned long *address){
    3.24      // Number of bits in a byte.
    3.25 @@ -96,7 +102,7 @@ int get_inet_addr(const char *s, unsigne
    3.26      unsigned long addr = 0;
    3.27      unsigned long v;
    3.28      int i;
    3.29 -    int err = -1;
    3.30 +    int err = -EINVAL;
    3.31      // Bit shift for the current byte.
    3.32      int shift = BYTE_BITS * (WORD_BYTES - 1);
    3.33      char buf[64];
    3.34 @@ -168,18 +174,18 @@ int inet_aton(const char *address, struc
    3.35   *
    3.36   * @param name input hostname or address string
    3.37   * @param address where to put the address
    3.38 - * @return 1 if address found OK, 0 otherwise
    3.39 + * @return 0 if address found OK, nonzero otherwise
    3.40   */
    3.41  int get_host_address(const char *name, unsigned long *address){
    3.42  #ifdef __KERNEL__
    3.43 -    return get_inet_addr(name, address) == 0;
    3.44 +    return get_inet_addr(name, address);
    3.45  #else
    3.46      struct hostent *host = gethostbyname(name);
    3.47      if(!host){
    3.48 -        return 0;
    3.49 +        return -EINVAL;
    3.50      }
    3.51      *address = ((struct in_addr *)(host->h_addr))->s_addr;
    3.52 -    return 1;
    3.53 +    return 0;
    3.54  #endif
    3.55  }
    3.56  
    3.57 @@ -187,33 +193,33 @@ int get_host_address(const char *name, u
    3.58   *
    3.59   * @param name service name
    3.60   * @param port where to put the port
    3.61 - * @return 1 if service port found OK, 0 otherwise
    3.62 + * @return 0 if service port found OK, negative otherwise
    3.63   */
    3.64  int get_service_port(const char *name, unsigned long *port){
    3.65  #ifdef __KERNEL__
    3.66 -    return 0;
    3.67 +    return -ENOSYS;
    3.68  #else
    3.69      struct servent *service;
    3.70      service = getservbyname(name, 0);
    3.71      if(!service){
    3.72 -        return 0;
    3.73 +        return -EINVAL;
    3.74      }
    3.75      *port = service->s_port;
    3.76 -    return 1;
    3.77 +    return 0;
    3.78  #endif
    3.79  }
    3.80  
    3.81  /** Convert a port number (in network order) to a service name.
    3.82   *
    3.83   * @param port the port number
    3.84 - * @return service name if found OK, 0 otherwise
    3.85 + * @return service name if found OK, NULL otherwise
    3.86   */
    3.87  char *get_port_service(unsigned long port){
    3.88  #ifdef __KERNEL__
    3.89 -    return 0;
    3.90 +    return NULL;
    3.91  #else
    3.92      struct servent *service = getservbyport(port, 0);
    3.93 -    return (service ? service->s_name : 0);
    3.94 +    return (service ? service->s_name : NULL);
    3.95  #endif
    3.96  }
    3.97  
    3.98 @@ -221,19 +227,27 @@ char *get_port_service(unsigned long por
    3.99   *
   3.100   * @param s input to convert
   3.101   * @param port where to put the port
   3.102 - * @return 1 if port found OK, 0 otherwise
   3.103 + * @return 0 if port found OK, -1 otherwise
   3.104   */
   3.105  int convert_service_to_port(const char *s, unsigned long *port){
   3.106 -    int ok = 0;
   3.107 +    int err = 0;
   3.108      unsigned long value;
   3.109 -    if(convert_atoul(s, &value)){
   3.110 -        ok = get_service_port(s, &value);
   3.111 +    printf("%s> %s\n", __FUNCTION__, s);
   3.112 +    if(convert_atoul(s, &value) == 0){
   3.113 +        int ok = (0 <= value) && (value <= PORT_MAX);
   3.114 +        printf("> value = %ld\n", value);
   3.115 +        if(ok){
   3.116 +            value = htons((unsigned short)value);
   3.117 +        } else {
   3.118 +            err = -EINVAL;
   3.119 +        }
   3.120      } else {
   3.121 -        ok = (0 <= value) && (value <= PORT_MAX);
   3.122 -        value = htons((unsigned short)value);
   3.123 +        printf("> get_service_port...\n");
   3.124 +        err = get_service_port(s, &value);
   3.125      }
   3.126 -    *port = (ok ? value : 0);
   3.127 -    return ok;
   3.128 +    *port = (err ? 0: value);
   3.129 +    printf("%s< err=%d\n", __FUNCTION__, err);
   3.130 +    return err;
   3.131  }
   3.132  
   3.133  #define MAC_ELEMENT_N  6 // Number of elements in a MAC address.
     4.1 --- a/tools/python/xen/xend/XendDomain.py	Wed Jul 07 18:57:28 2004 +0000
     4.2 +++ b/tools/python/xen/xend/XendDomain.py	Wed Jul 07 19:33:06 2004 +0000
     4.3 @@ -19,6 +19,7 @@ xroot = XendRoot.instance()
     4.4  import XendDB
     4.5  import XendDomainInfo
     4.6  import XendConsole
     4.7 +import XendMigrate
     4.8  import EventServer
     4.9  
    4.10  from xen.xend.server import SrvDaemon
    4.11 @@ -423,7 +424,9 @@ class XendDomain:
    4.12          """
    4.13          # Need a cancel too?
    4.14          # Don't forget to cancel restart for it.
    4.15 -        pass
    4.16 +        dom = int(id)
    4.17 +        xmigrate = XendMigrate.instance()
    4.18 +        return xmigrate.migrate_begin(dom, dst)
    4.19  
    4.20      def domain_save(self, id, dst, progress=0):
    4.21          """Save domain state to file, destroy domain on success.
     5.1 --- a/tools/python/xen/xend/XendMigrate.py	Wed Jul 07 18:57:28 2004 +0000
     5.2 +++ b/tools/python/xen/xend/XendMigrate.py	Wed Jul 07 19:33:06 2004 +0000
     5.3 @@ -14,11 +14,6 @@ import sxp
     5.4  import XendDB
     5.5  import EventServer; eserver = EventServer.instance()
     5.6  
     5.7 -from xen.xend.packing import SxpPacker, SxpUnpacker
     5.8 -from xen.xend import XendDomain
     5.9 -xd = XendDomain.instance()
    5.10 -
    5.11 -
    5.12  XFRD_PORT = 8002
    5.13  
    5.14  XFR_PROTO_MAJOR = 1
    5.15 @@ -27,55 +22,63 @@ XFR_PROTO_MINOR = 0
    5.16  class Migrate(Protocol):
    5.17  
    5.18      def __init__(self, minfo):
    5.19 -        self.packer = None
    5.20 -        self.unpacker = None
    5.21 +        self.parser = sxp.Parser()
    5.22          self.minfo = minfo
    5.23  
    5.24      def connectionMade(self):
    5.25 -        self.packer = SxpPacker(self.transport)
    5.26 -        self.unpacker = SxpPacker()
    5.27          # Send hello.
    5.28 -        self.packer.pack(['xfr.hello', XFR_PROTO_MAJOR, XFR_PROTO_MINOR])
    5.29 +        self.request(['xfr.hello', XFR_PROTO_MAJOR, XFR_PROTO_MINOR])
    5.30          # Send migrate.
    5.31          vmconfig = self.minfo.vmconfig()
    5.32          if not vmconfig:
    5.33              self.loseConnection()
    5.34              return
    5.35 -        self.packer.pack(['xfr.migrate',
    5.36 -                          self.minfo.src_dom,
    5.37 -                          vmconfig,
    5.38 -                          self.minfo.dst_host,
    5.39 -                          self.minfo.dst_port])
    5.40 +        self.request(['xfr.migrate',
    5.41 +                      self.minfo.src_dom,
    5.42 +                      vmconfig,
    5.43 +                      self.minfo.dst_host,
    5.44 +                      self.minfo.dst_port])
    5.45 +
    5.46 +    def request(self, req):
    5.47 +        sxp.show(req, out=self.transport)
    5.48 +        self.transport.write(' \n')
    5.49 +
    5.50 +    def loseConnection(self):
    5.51 +        self.transport.loseConnection()
    5.52  
    5.53      def connectionLost(self, reason):
    5.54          self.minfo.closed(reason)
    5.55  
    5.56 +    def dispatch(self, val):
    5.57 +        op = sxp.name(val)
    5.58 +        op = op.replace('.', '_')
    5.59 +        if op.startswith('xfr_'):
    5.60 +            fn = getattr(self, op, self.unknown)
    5.61 +        else:
    5.62 +            fn = self.unknown()
    5.63 +        fn(val)
    5.64 +
    5.65      def dataReceived(self, data):
    5.66 -        try:
    5.67 -            self.unpacker.reset(data)
    5.68 -            val = self.unpacker.unpack()
    5.69 -            print 'dataReceived>', 'val=', val
    5.70 -            op = val[0]
    5.71 -            op.replace('.', '_')
    5.72 -            if op.startwith('xfr_'):
    5.73 -                fn = getattr(self, op, self.unknown)
    5.74 -            else:
    5.75 -                fn = self.unknown
    5.76 -            fn(val)
    5.77 -        except Exception, ex:
    5.78 -            print 'dataReceived>', ex
    5.79 -            pass
    5.80 -
    5.81 +        self.parser.input(data)
    5.82 +        if self.parser.ready():
    5.83 +            val = self.parser.get_val()
    5.84 +            self.dispatch(val)
    5.85 +        if self.parser.at_eof():
    5.86 +            self.loseConnection()
    5.87 +            
    5.88      def unknown(self, val):
    5.89          print 'unknown>', val
    5.90  
    5.91      def xfr_progress(self, val):
    5.92          print 'xfr_progress>', val
    5.93  
    5.94 -    def xfr_error(self, val):
    5.95 +    def xfr_err(self, val):
    5.96          # If we get an error with non-zero code the migrate failed.
    5.97          # An error with code zero indicates hello success.
    5.98 -        err = int(val[1])
    5.99 +        print 'xfr_err>', val
   5.100 +        v = sxp.child(val)
   5.101 +        print 'xfr_err>', type(v), v
   5.102 +        err = int(sxp.child(val))
   5.103          if not err: return
   5.104          self.minfo.error(err);
   5.105          self.loseConnection()
   5.106 @@ -83,14 +86,15 @@ class Migrate(Protocol):
   5.107      def xfr_ok(self, val):
   5.108          # An ok indicates migrate completed successfully, and contains
   5.109          # the new domain id on the remote system.
   5.110 -        dom = int(val[1])
   5.111 +        print 'xfr_ok>', val
   5.112 +        dom = int(sxp.child(val))
   5.113          self.minfo.ok(dom)
   5.114          self.loseConnection()
   5.115  
   5.116  class MigrateClientFactory(ClientFactory):
   5.117  
   5.118      def __init__(self, minfo):
   5.119 -        ClientFactory.__init__(self)
   5.120 +        #ClientFactory.__init__(self)
   5.121          self.minfo = minfo
   5.122  
   5.123      def startedConnecting(self, connector):
   5.124 @@ -116,7 +120,7 @@ class XendMigrateInfo:
   5.125          self.state = 'begin'
   5.126          self.src_host = socket.gethostname()
   5.127          self.src_dom = dom
   5.128 -        self.dst_host = dst
   5.129 +        self.dst_host = host
   5.130          self.dst_port = port
   5.131          self.dst_dom = None
   5.132          self.start = 0
   5.133 @@ -139,12 +143,18 @@ class XendMigrateInfo:
   5.134          return sxpr
   5.135  
   5.136      def vmconfig(self):
   5.137 -        dominfo = xd.domain_get(self.dom)
   5.138 +        print 'vmconfig>'
   5.139 +        from xen.xend import XendDomain
   5.140 +        xd = XendDomain.instance()
   5.141 +
   5.142 +        dominfo = xd.domain_get(self.src_dom)
   5.143 +        print 'vmconfig>', type(dominfo), dominfo
   5.144          if dominfo:
   5.145 -            val = return sxp.to_string(dominfo)
   5.146 +            val = sxp.to_string(dominfo.sxpr())
   5.147          else:
   5.148              val = None
   5.149 -        return None
   5.150 +        print 'vmconfig<', 'val=', type(val), val
   5.151 +        return val
   5.152  
   5.153      def error(self, err):
   5.154          self.state = 'error'
   5.155 @@ -153,7 +163,7 @@ class XendMigrateInfo:
   5.156          self.state = 'ok'
   5.157          self.dst_dom = dom
   5.158  
   5.159 -    def close(self):
   5.160 +    def closed(self, reason=None):
   5.161          if self.state =='ok':
   5.162              eserver.inject('xend.migrate.ok', self.sxpr())
   5.163          else:
   5.164 @@ -208,15 +218,15 @@ class XendMigrate:
   5.165      def migrate_get(self, id):
   5.166          return self.migrate.get(id)
   5.167      
   5.168 -    def migrate_begin(self, dom, host):
   5.169 +    def migrate_begin(self, dom, host, port=XFRD_PORT):
   5.170          # Check dom for existence, not migrating already.
   5.171          # Subscribe to migrate notifications (for updating).
   5.172          id = self.nextid()
   5.173 -        info = XenMigrateInfo(id, dom, host, XFRD_PORT)
   5.174 +        info = XendMigrateInfo(id, dom, host, port)
   5.175          self._add_migrate(id, info)
   5.176          mcf = MigrateClientFactory(info)
   5.177          reactor.connectTCP('localhost', XFRD_PORT, mcf)
   5.178 -        return info.deferred
   5.179 +        return info
   5.180  
   5.181  def instance():
   5.182      global inst
     6.1 --- a/tools/python/xen/xm/create.py	Wed Jul 07 18:57:28 2004 +0000
     6.2 +++ b/tools/python/xen/xm/create.py	Wed Jul 07 19:33:06 2004 +0000
     6.3 @@ -193,45 +193,45 @@ def strip(pre, s):
     6.4      else:
     6.5          return s
     6.6  
     6.7 -def configure_image(config, opts):
     6.8 +def configure_image(config, vals):
     6.9      """Create the image config.
    6.10      """
    6.11 -    config_image = [ opts.builder ]
    6.12 -    config_image.append([ 'kernel', os.path.abspath(opts.kernel) ])
    6.13 -    if opts.ramdisk:
    6.14 -        config_image.append([ 'ramdisk', os.path.abspath(opts.ramdisk) ])
    6.15 -    if opts.cmdline_ip:
    6.16 -        cmdline_ip = strip('ip=', opts.cmdline_ip)
    6.17 +    config_image = [ vals.builder ]
    6.18 +    config_image.append([ 'kernel', os.path.abspath(vals.kernel) ])
    6.19 +    if vals.ramdisk:
    6.20 +        config_image.append([ 'ramdisk', os.path.abspath(vals.ramdisk) ])
    6.21 +    if vals.cmdline_ip:
    6.22 +        cmdline_ip = strip('ip=', vals.cmdline_ip)
    6.23          config_image.append(['ip', cmdline_ip])
    6.24 -    if opts.root:
    6.25 -        cmdline_root = strip('root=', opts.root)
    6.26 +    if vals.root:
    6.27 +        cmdline_root = strip('root=', vals.root)
    6.28          config_image.append(['root', cmdline_root])
    6.29 -    if opts.extra:
    6.30 -        config_image.append(['args', opts.extra])
    6.31 +    if vals.extra:
    6.32 +        config_image.append(['args', vals.extra])
    6.33      config.append(['image', config_image ])
    6.34      
    6.35 -def configure_disks(config_devs, opts):
    6.36 +def configure_disks(config_devs, vals):
    6.37      """Create the config for disks (virtual block devices).
    6.38      """
    6.39 -    for (uname, dev, mode) in opts.disk:
    6.40 +    for (uname, dev, mode) in vals.disk:
    6.41          config_vbd = ['vbd',
    6.42                        ['uname', uname],
    6.43                        ['dev', dev ],
    6.44                        ['mode', mode ] ]
    6.45          config_devs.append(['device', config_vbd])
    6.46  
    6.47 -def configure_pci(config_devs, opts):
    6.48 +def configure_pci(config_devs, vals):
    6.49      """Create the config for pci devices.
    6.50      """
    6.51 -    for (bus, dev, func) in opts.pci:
    6.52 +    for (bus, dev, func) in vals.pci:
    6.53          config_pci = ['pci', ['bus', bus], ['dev', dev], ['func', func]]
    6.54          config_devs.append(['device', config_pci])
    6.55  
    6.56 -def configure_vifs(config_devs, opts):
    6.57 +def configure_vifs(config_devs, vals):
    6.58      """Create the config for virtual network interfaces.
    6.59      """
    6.60 -    vifs = opts.vif
    6.61 -    vifs_n = max(opts.nics, len(vifs))
    6.62 +    vifs = vals.vif
    6.63 +    vifs_n = max(vals.nics, len(vifs))
    6.64  
    6.65      for idx in range(0, vifs_n):
    6.66          if idx < len(vifs):
    6.67 @@ -248,65 +248,65 @@ def configure_vifs(config_devs, opts):
    6.68              config_vif.append(['bridge', bridge])
    6.69          config_devs.append(['device', config_vif])
    6.70  
    6.71 -def configure_vfr(config, opts):
    6.72 -     if not opts.ipaddr: return
    6.73 +def configure_vfr(config, vals):
    6.74 +     if not vals.ipaddr: return
    6.75       config_vfr = ['vfr']
    6.76       idx = 0 # No way of saying which IP is for which vif?
    6.77 -     for ip in opts.ipaddr:
    6.78 +     for ip in vals.ipaddr:
    6.79           config_vfr.append(['vif', ['id', idx], ['ip', ip]])
    6.80       config.append(config_vfr)
    6.81  
    6.82  
    6.83 -def make_config(opts):
    6.84 +def make_config(vals):
    6.85      """Create the domain configuration.
    6.86      """
    6.87      
    6.88      config = ['vm',
    6.89 -              ['name', opts.name ],
    6.90 -              ['memory', opts.memory ] ]
    6.91 -    if opts.cpu:
    6.92 -        config.append(['cpu', opts.cpu])
    6.93 -    if opts.blkif:
    6.94 +              ['name', vals.name ],
    6.95 +              ['memory', vals.memory ] ]
    6.96 +    if vals.cpu:
    6.97 +        config.append(['cpu', vals.cpu])
    6.98 +    if vals.blkif:
    6.99          config.append(['backend', ['blkif']])
   6.100 -    if opts.netif:
   6.101 +    if vals.netif:
   6.102          config.append(['backend', ['netif']])
   6.103 -    if opts.autorestart:
   6.104 +    if vals.autorestart:
   6.105          config.append(['autorestart'])
   6.106      
   6.107 -    configure_image(config, opts)
   6.108 +    configure_image(config, vals)
   6.109      config_devs = []
   6.110 -    configure_disks(config_devs, opts)
   6.111 -    configure_pci(config_devs, opts)
   6.112 -    configure_vifs(config_devs, opts)
   6.113 +    configure_disks(config_devs, vals)
   6.114 +    configure_pci(config_devs, vals)
   6.115 +    configure_vifs(config_devs, vals)
   6.116      config += config_devs
   6.117      return config
   6.118  
   6.119 -def preprocess_disk(opts):
   6.120 -    if not opts.disk: return
   6.121 +def preprocess_disk(opts, vals):
   6.122 +    if not vals.disk: return
   6.123      disk = []
   6.124 -    for v in opts.disk:
   6.125 +    for v in vals.disk:
   6.126          d = v.split(',')
   6.127          if len(d) != 3:
   6.128              opts.err('Invalid disk specifier: ' + v)
   6.129          disk.append(d)
   6.130 -    opts.disk = disk
   6.131 +    vals.disk = disk
   6.132  
   6.133 -def preprocess_pci(opts):
   6.134 -    if not opts.pci: return
   6.135 +def preprocess_pci(opts, vals):
   6.136 +    if not vals.pci: return
   6.137      pci = []
   6.138 -    for v in opts.pci:
   6.139 +    for v in vals.pci:
   6.140          d = v.split(',')
   6.141          if len(d) != 3:
   6.142              opts.err('Invalid pci specifier: ' + v)
   6.143          # Components are in hex: add hex specifier.
   6.144          hexd = map(lambda v: '0x'+v, d)
   6.145          pci.append(hexd)
   6.146 -    opts.pci = pci
   6.147 +    vals.pci = pci
   6.148  
   6.149 -def preprocess_vifs(opts):
   6.150 -    if not opts.vif: return
   6.151 +def preprocess_vifs(opts, vals):
   6.152 +    if not vals.vif: return
   6.153      vifs = []
   6.154 -    for vif in opts.vif:
   6.155 +    for vif in vals.vif:
   6.156          d = {}
   6.157          a = vif.split(',')
   6.158          for b in a:
   6.159 @@ -317,43 +317,42 @@ def preprocess_vifs(opts):
   6.160                  opts.err('Invalid vif specifier: ' + vif)
   6.161              d[k] = v
   6.162          vifs.append(d)
   6.163 -    opts.vif = vifs
   6.164 +    vals.vif = vifs
   6.165  
   6.166 -def preprocess_ip(opts):
   6.167 -    setip = (opts.hostname or opts.netmask
   6.168 -             or opts.gateway or opts.dhcp or opts.interface)
   6.169 +def preprocess_ip(opts, vals):
   6.170 +    setip = (vals.hostname or vals.netmask
   6.171 +             or vals.gateway or vals.dhcp or vals.interface)
   6.172      if not setip: return
   6.173 -    #if not opts
   6.174 -    ip = (opts.ip
   6.175 +    ip = (vals.ip
   6.176            + ':'
   6.177 -          + ':' + opts.gateway
   6.178 -          + ':' + opts.netmask
   6.179 -          + ':' + opts.hostname
   6.180 -          + ':' + opts.interface
   6.181 -          + ':' + opts.dhcp)
   6.182 -    opts.cmdline_ip = ip
   6.183 +          + ':' + vals.gateway
   6.184 +          + ':' + vals.netmask
   6.185 +          + ':' + vals.hostname
   6.186 +          + ':' + vals.interface
   6.187 +          + ':' + vals.dhcp)
   6.188 +    vals.cmdline_ip = ip
   6.189  
   6.190 -def preprocess_nfs(opts):
   6.191 -    if (opts.nfs_root or opts.nfs_server):
   6.192 -        if (not opts.nfs_root) or (not opts.nfs_server):
   6.193 +def preprocess_nfs(opts, vals):
   6.194 +    if (vals.nfs_root or vals.nfs_server):
   6.195 +        if (not vals.nfs_root) or (not vals.nfs_server):
   6.196              opts.err('Must set nfs root and nfs server')
   6.197      else:
   6.198          return
   6.199 -    nfs = 'nfsroot=' + opts.nfs_server + ':' + opts.nfs_root
   6.200 -    opts.extra = nfs + ' ' + opts.extra
   6.201 +    nfs = 'nfsroot=' + vals.nfs_server + ':' + vals.nfs_root
   6.202 +    vals.extra = nfs + ' ' + vals.extra
   6.203      
   6.204 -def preprocess(opts):
   6.205 -    if not opts.kernel:
   6.206 +def preprocess(opts, vals):
   6.207 +    if not vals.kernel:
   6.208          opts.err("No kernel specified")
   6.209 -    preprocess_disk(opts)
   6.210 -    preprocess_pci(opts)
   6.211 -    preprocess_vifs(opts)
   6.212 -    preprocess_ip(opts)
   6.213 -    preprocess_nfs(opts)
   6.214 +    preprocess_disk(opts, vals)
   6.215 +    preprocess_pci(opts, vals)
   6.216 +    preprocess_vifs(opts, vals)
   6.217 +    preprocess_ip(opts, vals)
   6.218 +    preprocess_nfs(opts, vals)
   6.219           
   6.220  def make_domain(opts, config):
   6.221      """Create, build and start a domain.
   6.222 -    Returns: [int] the ID of the new domain.
   6.223 +    Returns: pair: [int] the ID of the new domain, [int] console port
   6.224      """
   6.225      if opts.vals.load:
   6.226          filename = os.path.abspath(opts.vals.load)
   6.227 @@ -393,7 +392,7 @@ def main(argv):
   6.228          pass
   6.229      else:
   6.230          opts.load_defaults()
   6.231 -    preprocess(opts.vals)
   6.232 +    preprocess(opts, opts.vals)
   6.233      config = make_config(opts.vals)
   6.234      if opts.vals.dryrun:
   6.235          PrettyPrint.prettyprint(config)
     7.1 --- a/tools/xfrd/Make.xfrd	Wed Jul 07 18:57:28 2004 +0000
     7.2 +++ b/tools/xfrd/Make.xfrd	Wed Jul 07 19:33:06 2004 +0000
     7.3 @@ -15,7 +15,7 @@ UTIL_LIB_SRC += lzi_stream.c
     7.4  UTIL_LIB_SRC += marshal.c
     7.5  UTIL_LIB_SRC += string_stream.c
     7.6  UTIL_LIB_SRC += sxpr.c
     7.7 -#UTIL_LIB_SRC += sxpr_parser.c
     7.8 +UTIL_LIB_SRC += sxpr_parser.c
     7.9  UTIL_LIB_SRC += sys_net.c
    7.10  UTIL_LIB_SRC += sys_string.c
    7.11  #UTIL_LIB_SRC += util.c
     8.1 --- a/tools/xfrd/connection.c	Wed Jul 07 18:57:28 2004 +0000
     8.2 +++ b/tools/xfrd/connection.c	Wed Jul 07 19:33:06 2004 +0000
     8.3 @@ -8,6 +8,7 @@
     8.4  #include "connection.h"
     8.5  #include "file_stream.h"
     8.6  #include "lzi_stream.h"
     8.7 +#include "sxpr_parser.h"
     8.8  
     8.9  #define dprintf(fmt, args...) fprintf(stdout, "[DEBUG] %s" fmt, __FUNCTION__, ##args)
    8.10  #define wprintf(fmt, args...) fprintf(stderr, "[WARN]  %s" fmt, __FUNCTION__, ##args)
    8.11 @@ -161,3 +162,34 @@ void Conn_close(Conn *conn){
    8.12      if(conn->out) IOStream_close(conn->out);
    8.13      shutdown(conn->sock, 2);
    8.14  }
    8.15 +
    8.16 +int Conn_sxpr(Conn *conn, Sxpr *sxpr){
    8.17 +    int err = 0;
    8.18 +    Sxpr val = ONONE;
    8.19 +    int c = 0;
    8.20 +
    8.21 +    dprintf(">\n");
    8.22 +    if(!conn->parser){
    8.23 +        conn->parser = Parser_new();
    8.24 +        set_error_stream(conn->parser, iostdout);
    8.25 +    }
    8.26 +    while(!err && c >= 0 && !Parser_ready(conn->parser)){
    8.27 +        c = IOStream_getc(conn->in);
    8.28 +        printf("%c", (char)c);
    8.29 +        if(c < 0){
    8.30 +            err = Parser_input_eof(conn->parser);
    8.31 +        } else {
    8.32 +            err = Parser_input_char(conn->parser, c);
    8.33 +        }
    8.34 +    }
    8.35 +    if(Parser_ready(conn->parser)){
    8.36 +        val = Parser_get_val(conn->parser);
    8.37 +    }
    8.38 +    if(err){
    8.39 +        objfree(val);
    8.40 +        val = ONONE;
    8.41 +    }
    8.42 +    *sxpr = val;
    8.43 +    dprintf("< err=%d\n", err);
    8.44 +    return err;
    8.45 +}
     9.1 --- a/tools/xfrd/connection.h	Wed Jul 07 18:57:28 2004 +0000
     9.2 +++ b/tools/xfrd/connection.h	Wed Jul 07 19:33:06 2004 +0000
     9.3 @@ -5,6 +5,7 @@
     9.4  #include <netinet/in.h>
     9.5  
     9.6  #include "iostream.h"
     9.7 +#include "sxpr_parser.h"
     9.8  
     9.9  /** A connection.
    9.10   * The underlying transport is a socket. 
    9.11 @@ -15,6 +16,7 @@ typedef struct Conn {
    9.12      int sock;
    9.13      IOStream *in;
    9.14      IOStream *out;
    9.15 +    Parser *parser;
    9.16  } Conn;
    9.17  
    9.18  enum {
    9.19 @@ -29,4 +31,6 @@ extern int Conn_init(Conn *conn, int fla
    9.20  extern int Conn_connect(Conn *conn, int flags, struct in_addr ipaddr, uint16_t port);
    9.21  extern void Conn_close(Conn *conn);
    9.22  
    9.23 +extern int Conn_sxpr(Conn *conn, Sxpr *sxpr);
    9.24 +
    9.25  #endif /* ! _VFC_CONNECTION_H_ */
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/xfrd/sxpr_parser.c	Wed Jul 07 19:33:06 2004 +0000
    10.3 @@ -0,0 +1,943 @@
    10.4 +
    10.5 +#ifdef __KERNEL__
    10.6 +#  include <linux/config.h>
    10.7 +#  include <linux/module.h>
    10.8 +#  include <linux/kernel.h>
    10.9 +#  include <linux/string.h>
   10.10 +#  include <linux/errno.h>
   10.11 +#else
   10.12 +#  include <stdlib.h>
   10.13 +#  include <errno.h>
   10.14 +#endif
   10.15 +
   10.16 +#include "iostream.h"
   10.17 +#include "lexis.h"
   10.18 +#include "sxpr_parser.h"
   10.19 +#include "sys_string.h"
   10.20 +#include "enum.h"
   10.21 +
   10.22 +/** @file
   10.23 + * Sxpr parsing.
   10.24 + *
   10.25 + * So that the parser does not leak memory, all sxprs constructed by
   10.26 + * the parser must be freed on error.  On successful parse the sxpr
   10.27 + * returned becomes the responsibility of the caller.
   10.28 + *
   10.29 + * @author Mike Wray <mike.wray@hpl.hp.com>
   10.30 + */
   10.31 +
   10.32 +#define dprintf(fmt, args...) IOStream_print(iostdout, "[DEBUG] %s" fmt, __FUNCTION__, ##args)
   10.33 +#define printf(fmt, args...)   IOStream_print(iostdout, fmt, ##args)
   10.34 +
   10.35 +static void reset(Parser *z);
   10.36 +static int inputchar(Parser *p, char c);
   10.37 +static int savechar(Parser *p, char c);
   10.38 +extern void parse_error(Parser *in);
   10.39 +extern void parse_error_id(Parser *in, ParseErrorId id);
   10.40 +
   10.41 +static int begin_start(Parser *p, char c);
   10.42 +static int state_start(Parser *p, char c);
   10.43 +static int end_start(Parser *p);
   10.44 +
   10.45 +static int begin_comment(Parser *p, char c);
   10.46 +static int state_comment(Parser *p, char c);
   10.47 +static int end_comment(Parser *p);
   10.48 +
   10.49 +static int begin_string(Parser *p, char c);
   10.50 +static int state_string(Parser *p, char c);
   10.51 +static int end_string(Parser *p);
   10.52 +static int state_escape(Parser *p, char c);
   10.53 +static int state_octal(Parser *p, char c);
   10.54 +static int state_hex(Parser *p, char c);
   10.55 +
   10.56 +static int begin_atom(Parser *p, char c);
   10.57 +static int state_atom(Parser *p, char c);
   10.58 +static int end_atom(Parser *p);
   10.59 +
   10.60 +static int state_list(Parser *p, char c);
   10.61 +static int begin_list(Parser *p, char c);
   10.62 +static int end_list(Parser *p);
   10.63 +
   10.64 +/** Print a parse error.
   10.65 + *
   10.66 + * @param in parser
   10.67 + * @param msg format followed by printf arguments
   10.68 + */
   10.69 +void eprintf(Parser *in, char *msg, ...){
   10.70 +    va_list args;
   10.71 +    if(in->error_out){
   10.72 +        va_start(args, msg);
   10.73 +        IOStream_vprint(in->error_out, msg, args);
   10.74 +        va_end(args);
   10.75 +    }
   10.76 +}
   10.77 +
   10.78 +/** Print a parse warning.
   10.79 + *
   10.80 + * @param in parser
   10.81 + * @param msg format followed by printf arguments
   10.82 + */
   10.83 +void wprintf(Parser *in, char *msg, ...){
   10.84 +    va_list args;
   10.85 +    if(in->error_out){
   10.86 +        va_start(args, msg);
   10.87 +        IOStream_vprint(in->error_out, msg, args);
   10.88 +        va_end(args);
   10.89 +    }
   10.90 +}
   10.91 +
   10.92 +/*============================================================================*/
   10.93 +
   10.94 +/** Record defining the message for a parse error. */
   10.95 +typedef struct {
   10.96 +  ParseErrorId id;
   10.97 +  char *message;
   10.98 +} ParseError;
   10.99 +
  10.100 +/** Format for printing parse error messages. */
  10.101 +#define PARSE_ERR_FMT "parse error> line %3d, column %2d: %s"
  10.102 +
  10.103 +/** Message catalog for the parse error codes. */
  10.104 +static ParseError catalog[] = {
  10.105 +  { PARSE_ERR_UNSPECIFIED,            "unspecified error" },
  10.106 +  { PARSE_ERR_NOMEM,                  "out of memory" },
  10.107 +  { PARSE_ERR_UNEXPECTED_EOF,         "unexpected end of input" },
  10.108 +  { PARSE_ERR_TOKEN_TOO_LONG,         "token too long" },
  10.109 +  { PARSE_ERR_INVALID_SYNTAX,         "syntax error" },
  10.110 +  { PARSE_ERR_INVALID_ESCAPE,         "invalid escape" },
  10.111 +  { 0, NULL }
  10.112 +};
  10.113 +
  10.114 +/** Number of entries in the message catalog. */
  10.115 +const static int catalog_n = sizeof(catalog)/sizeof(ParseError);
  10.116 +
  10.117 +void ParserState_free(ParserState *z){
  10.118 +    if(!z) return;
  10.119 +    objfree(z->val);
  10.120 +    deallocate(z);
  10.121 +}
  10.122 +
  10.123 +int ParserState_new(ParserStateFn *fn, char *name,
  10.124 +                    ParserState *parent, ParserState **val){
  10.125 +    int err = 0;
  10.126 +    ParserState *z;
  10.127 +    z = ALLOCATE(ParserState);
  10.128 +    if(z){
  10.129 +        z->name = name;
  10.130 +        z->fn = fn;
  10.131 +        z->parent = parent;
  10.132 +        z->val = ONULL;
  10.133 +    } else {
  10.134 +        err = -ENOMEM;
  10.135 +    }
  10.136 +    if(!err) *val = z;
  10.137 +    return err;
  10.138 +}
  10.139 +
  10.140 +/** Free a parser.
  10.141 + * No-op if the parser is null.
  10.142 + *
  10.143 + * @param z parser 
  10.144 + */
  10.145 +void Parser_free(Parser *z){
  10.146 +    if(!z) return;
  10.147 +    objfree(z->val);
  10.148 +    z->val = ONONE;
  10.149 +    deallocate(z);
  10.150 +}
  10.151 +
  10.152 +/** Create a new parser. The error stream defaults to null.
  10.153 + */
  10.154 +Parser * Parser_new(void){
  10.155 +    Parser *z = ALLOCATE(Parser);
  10.156 +    int err = -ENOMEM;
  10.157 +  
  10.158 +    if(!z) goto exit;
  10.159 +    err = 0;
  10.160 +    reset(z);
  10.161 +  exit:
  10.162 +    if(err){
  10.163 +        Parser_free(z);
  10.164 +        z = NULL;
  10.165 +    }
  10.166 +    return z;
  10.167 +}
  10.168 +
  10.169 +/** Get the next character.
  10.170 + * Records the character read in the parser,
  10.171 + * and sets the line and character counts.
  10.172 + *
  10.173 + * @param p parser
  10.174 + * @return error flag: 0 on success, non-zero on error
  10.175 + */
  10.176 +static int inputchar(Parser *p, char c){
  10.177 +    int err = 0;
  10.178 +    if(c=='\n'){
  10.179 +        p->line_no++;
  10.180 +        p->char_no = 0;
  10.181 +    } else {
  10.182 +        p->char_no++;
  10.183 +    }
  10.184 +    return err;
  10.185 +}
  10.186 +
  10.187 +static int savechar(Parser *p, char c){
  10.188 +    int err = 0;
  10.189 +    if(p->buf_i >= p->buf_n){
  10.190 +        err = -ENOMEM;
  10.191 +        goto exit;
  10.192 +    }
  10.193 +    p->buf[p->buf_i] = c;
  10.194 +    p->buf_i++;
  10.195 +  exit:
  10.196 +    return err;
  10.197 +}
  10.198 +
  10.199 +int Parser_input_char(Parser *p, char c){
  10.200 +    int err = 0;
  10.201 +    if(at_eof(p)){
  10.202 +        //skip;
  10.203 +    } else {
  10.204 +        inputchar(p, c);
  10.205 +    }
  10.206 +    if(!p->state){
  10.207 +        err = begin_start(p, c);
  10.208 +        if(err) goto exit;
  10.209 +    }
  10.210 +    err = p->state->fn(p, c);
  10.211 +  exit:
  10.212 +    return err;
  10.213 +}
  10.214 +
  10.215 +int Parser_input_eof(Parser *p){
  10.216 +    int err = 0;
  10.217 +    p->eof = 1;
  10.218 +    err = Parser_input_char(p, IOSTREAM_EOF);
  10.219 +    return err;
  10.220 +}
  10.221 +
  10.222 +int Parser_input(Parser *p, char *buf, int buf_n){
  10.223 +    int err = 0;
  10.224 +    int i = 0;
  10.225 +    if(buf_n <= 0){
  10.226 +        err = Parser_input_eof(p);
  10.227 +        goto exit;
  10.228 +    }
  10.229 +    for(i = 0; i<buf_n; i++){
  10.230 +        err = Parser_input_char(p, buf[i]);
  10.231 +        if(err) goto exit;
  10.232 +    }
  10.233 +  exit:
  10.234 +    err = (err < 0 ? err : buf_n);
  10.235 +    return err;
  10.236 +}
  10.237 +
  10.238 +int Parser_push(Parser *p, ParserStateFn *fn, char *name){
  10.239 +    int err = 0;
  10.240 +    err = ParserState_new(fn, name, p->state, &p->state);
  10.241 +    return err;
  10.242 +}
  10.243 +        
  10.244 +int Parser_pop(Parser *p){
  10.245 +    int err = 0;
  10.246 +    ParserState *s = p->state;
  10.247 +    p->state = s->parent;
  10.248 +    ParserState_free(s);
  10.249 +    return err;
  10.250 +}
  10.251 +
  10.252 +int Parser_return(Parser *p){
  10.253 +    int err = 0;
  10.254 +    Sxpr val = ONONE;
  10.255 +    if(!p->state){
  10.256 +        err = -EINVAL;
  10.257 +        goto exit;
  10.258 +    }
  10.259 +    val = p->state->val;
  10.260 +    p->state->val = ONONE;
  10.261 +    err = Parser_pop(p);
  10.262 +    if(err) goto exit;
  10.263 +    if(p->state){
  10.264 +        err = cons_push(&p->state->val, val);
  10.265 +    } else {
  10.266 +        val = nrev(val);
  10.267 +        p->val = val;
  10.268 +    }
  10.269 +  exit:
  10.270 +    if(err){
  10.271 +        objfree(val);
  10.272 +    }
  10.273 +    return err;
  10.274 +}
  10.275 +
  10.276 +/** Determine if a character is a separator.
  10.277 + *
  10.278 + * @param p parser
  10.279 + * @param c character to test
  10.280 + * @return 1 if a separator, 0 otherwise
  10.281 + */
  10.282 +static int is_separator(Parser *p, char c){
  10.283 +    return in_sep_class(c);
  10.284 +}
  10.285 +
  10.286 +/** Return the current token.
  10.287 + * The return value points at the internal buffer, so
  10.288 + * it must not be modified (or freed). Use copy_token() if you need a copy.
  10.289 + *
  10.290 + * @param p parser
  10.291 + * @return token
  10.292 + */
  10.293 +char *peek_token(Parser *p){
  10.294 +    return p->buf;
  10.295 +}
  10.296 +
  10.297 +/** Return a copy of the current token.
  10.298 + * The returned value should be freed when finished with.
  10.299 + *
  10.300 + * @param p parser
  10.301 + * @return copy of token
  10.302 + */
  10.303 +char *copy_token(Parser *p){
  10.304 +    return strdup(peek_token(p));
  10.305 +}
  10.306 +
  10.307 +static int do_intern(Parser *p){
  10.308 +    int err = 0;
  10.309 +    Sxpr obj = intern(peek_token(p));
  10.310 +    if(NOMEMP(obj)){
  10.311 +        err = -ENOMEM;
  10.312 +    } else {
  10.313 +        p->state->val = obj;
  10.314 +    }
  10.315 +    return err;
  10.316 +}
  10.317 +
  10.318 +static int do_string(Parser *p){
  10.319 +    int err = 0;
  10.320 +    Sxpr obj;
  10.321 +    obj = string_new(peek_token(p));
  10.322 +    if(NOMEMP(obj)){
  10.323 +        err = -ENOMEM;
  10.324 +    } else {
  10.325 +        p->state->val = obj;
  10.326 +    }
  10.327 +    return err;
  10.328 +}
  10.329 +
  10.330 +void newtoken(Parser *p){
  10.331 +    memset(p->buf, 0, p->buf_n);
  10.332 +    p->buf_i = 0;
  10.333 +    p->tok_begin_line = p->line_no;
  10.334 +    p->tok_begin_char = p->char_no;
  10.335 +}
  10.336 +
  10.337 +int get_escape(char c, char *d){
  10.338 +    int err = 0;
  10.339 +    switch(c){
  10.340 +    case 'a':            *d = '\a'; break;
  10.341 +    case 'b':            *d = '\b'; break;
  10.342 +    case 'f':            *d = '\f'; break;
  10.343 +    case 'n':            *d = '\n'; break;
  10.344 +    case 'r':            *d = '\r'; break;
  10.345 +    case 't':            *d = '\t'; break;
  10.346 +    case 'v':            *d = '\v'; break;
  10.347 +    case c_escape:       *d = c_escape; break;
  10.348 +    case c_single_quote: *d = c_single_quote; break;
  10.349 +    case c_double_quote: *d = c_double_quote; break;
  10.350 +    default:
  10.351 +        err = -EINVAL;
  10.352 +    }
  10.353 +    return err;
  10.354 +}
  10.355 +
  10.356 +int Parser_ready(Parser *p){
  10.357 +    return CONSP(p->val) || (p->start_state && CONSP(p->start_state->val));
  10.358 +}
  10.359 +
  10.360 +Sxpr Parser_get_val(Parser *p){
  10.361 +    Sxpr v = ONONE;
  10.362 +    if(CONSP(p->val)){
  10.363 +        v = CAR(p->val);
  10.364 +        p->val = CDR(p->val);
  10.365 +    } else if (CONSP(p->start_state->val)){
  10.366 +        p->val = p->start_state->val;
  10.367 +        p->val = nrev(p->val);
  10.368 +        p->start_state->val = ONULL;
  10.369 +        v = CAR(p->val);
  10.370 +        p->val = CDR(p->val);
  10.371 +    }        
  10.372 +    return v;
  10.373 +}
  10.374 +
  10.375 +Sxpr Parser_get_all(Parser *p){
  10.376 +    Sxpr v = ONULL;
  10.377 +    if(CONSP(p->val)){
  10.378 +        v = p->val;
  10.379 +        p->val = ONONE;
  10.380 +    } else if(CONSP(p->start_state->val)){
  10.381 +        v = p->start_state->val;
  10.382 +        p->start_state->val = ONULL;
  10.383 +        v = nrev(v);
  10.384 +    }
  10.385 +    return v;
  10.386 +}
  10.387 +    
  10.388 +int begin_start(Parser *p, char c){
  10.389 +    int err = 0;
  10.390 +    err = Parser_push(p, state_start, "start");
  10.391 +    if(err) goto exit;
  10.392 +    p->start_state = p->state;
  10.393 +  exit:
  10.394 +    return err;
  10.395 +}
  10.396 +
  10.397 +int state_start(Parser *p, char c){
  10.398 +    int err = 0;
  10.399 +    if(at_eof(p)){
  10.400 +        err = end_start(p);
  10.401 +    } else if(in_space_class(c)){
  10.402 +        //skip
  10.403 +    } else if(in_comment_class(c)){
  10.404 +        begin_comment(p, c);
  10.405 +    } else if(c == c_list_open){
  10.406 +        begin_list(p, c);
  10.407 +    } else if(c == c_list_close){
  10.408 +        parse_error(p);
  10.409 +        err = -EINVAL;
  10.410 +    } else if(in_string_quote_class(c)){
  10.411 +        begin_string(p, c);
  10.412 +    } else if(in_printable_class(c)){
  10.413 +        begin_atom(p, c);
  10.414 +    } else if(c == 0x04){
  10.415 +        //ctrl-D, EOT: end-of-text.
  10.416 +        Parser_input_eof(p);
  10.417 +    } else {
  10.418 +        parse_error(p);
  10.419 +        err = -EINVAL;
  10.420 +    }
  10.421 +    return err;
  10.422 +}
  10.423 +
  10.424 +int end_start(Parser *p){
  10.425 +    int err = 0;
  10.426 +    err = Parser_return(p);
  10.427 +    return err;
  10.428 +}
  10.429 +
  10.430 +int begin_comment(Parser *p, char c){
  10.431 +    int err = 0;
  10.432 +    err = Parser_push(p, state_comment, "comment");
  10.433 +    if(err) goto exit;
  10.434 +    err = inputchar(p, c);
  10.435 +  exit:
  10.436 +    return err;
  10.437 +}
  10.438 +
  10.439 +int state_comment(Parser *p, char c){
  10.440 +    int err = 0;
  10.441 +    if(c == '\n' || at_eof(p)){
  10.442 +        err = end_comment(p);
  10.443 +    } else {
  10.444 +        err = inputchar(p, c);
  10.445 +    }
  10.446 +    return err;
  10.447 +}
  10.448 +
  10.449 +int end_comment(Parser *p){
  10.450 +    return Parser_pop(p);
  10.451 +}
  10.452 +
  10.453 +int begin_string(Parser *p, char c){
  10.454 +    int err = 0;
  10.455 +    err = Parser_push(p, state_string, "string");
  10.456 +    if(err) goto exit;
  10.457 +    newtoken(p);
  10.458 +    p->state->delim = c;
  10.459 +  exit:
  10.460 +    return err;
  10.461 +}
  10.462 +
  10.463 +int state_string(Parser *p, char c){
  10.464 +    int err = 0;
  10.465 +    if(at_eof(p)){
  10.466 +        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
  10.467 +        err = -EINVAL;
  10.468 +    } else if(c == p->state->delim){
  10.469 +        err = end_string(p);
  10.470 +    } else if(c == '\\'){
  10.471 +        err = Parser_push(p, state_escape, "escape");
  10.472 +    } else {
  10.473 +        err = savechar(p, c);
  10.474 +    }
  10.475 +    return err;
  10.476 +}
  10.477 +
  10.478 +int end_string(Parser *p){
  10.479 +    int err = 0;
  10.480 +    err = do_string(p);
  10.481 +    if(err) goto exit;
  10.482 +    err = Parser_return(p);
  10.483 +  exit:
  10.484 +    return err;
  10.485 +}
  10.486 +
  10.487 +int state_escape(Parser *p, char c){
  10.488 +    int err = 0;
  10.489 +    char d;
  10.490 +    if(at_eof(p)){
  10.491 +        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
  10.492 +        err = -EINVAL;
  10.493 +        goto exit;
  10.494 +    }
  10.495 +    if(get_escape(c, &d) == 0){
  10.496 +        err = savechar(p, d);
  10.497 +        if(err) goto exit;
  10.498 +        err = Parser_pop(p);
  10.499 +    } else if(c == 'x'){
  10.500 +        p->state->fn = state_hex;
  10.501 +        p->state->ival = 0;
  10.502 +        p->state->count = 0;
  10.503 +    } else {
  10.504 +        p->state->fn = state_octal;
  10.505 +        p->state->ival = 0;
  10.506 +        p->state->count = 0;
  10.507 +        err = Parser_input_char(p, c);
  10.508 +    }
  10.509 +  exit:
  10.510 +    return err;
  10.511 +}
  10.512 +
  10.513 +int octaldone(Parser *p){
  10.514 +    int err = 0;
  10.515 +    char d = (char)(p->state->ival & 0xff);
  10.516 +    err = Parser_pop(p);
  10.517 +    if(err) goto exit;
  10.518 +    err = Parser_input_char(p, d);
  10.519 +  exit:
  10.520 +    return err;
  10.521 +}
  10.522 +
  10.523 +int octaldigit(Parser *p, char c){
  10.524 +    int err = 0;
  10.525 +    p->state->ival *= 8;
  10.526 +    p->state->ival += c - '0'; 
  10.527 +    p->state->count++;
  10.528 +    if(err) goto exit;
  10.529 +    if(p->state->ival < 0 || p->state->ival > 0xff){
  10.530 +        parse_error(p);
  10.531 +        err = -EINVAL;
  10.532 +        goto exit;
  10.533 +    }
  10.534 +    if(p->state->count == 3){
  10.535 +        err = octaldone(p);
  10.536 +    }
  10.537 +  exit:
  10.538 +    return err;
  10.539 +}
  10.540 +
  10.541 +int state_octal(Parser *p, char c){
  10.542 +    int err = 0;
  10.543 +    if(at_eof(p)){
  10.544 +        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
  10.545 +        err = -EINVAL;
  10.546 +        goto exit;
  10.547 +    } else if('0' <= c && c <= '7'){
  10.548 +        err = octaldigit(p, c);
  10.549 +    } else {
  10.550 +        err = octaldone(p);
  10.551 +        if(err) goto exit;
  10.552 +        Parser_input_char(p, c);
  10.553 +    }
  10.554 +  exit:
  10.555 +    return err;
  10.556 +}
  10.557 +
  10.558 +int hexdone(Parser *p){
  10.559 +    int err = 0;
  10.560 +    char d = (char)(p->state->ival & 0xff);
  10.561 +    err = Parser_pop(p);
  10.562 +    if(err) goto exit;
  10.563 +    err = Parser_input_char(p, d);
  10.564 +  exit:
  10.565 +    return err;
  10.566 +}
  10.567 +    
  10.568 +int hexdigit(Parser *p, char c, char d){
  10.569 +    int err = 0;
  10.570 +    p->state->ival *= 16;
  10.571 +    p->state->ival += c - d; 
  10.572 +    p->state->count++;
  10.573 +    if(err) goto exit;
  10.574 +    if(p->state->ival < 0 || p->state->ival > 0xff){
  10.575 +        parse_error(p);
  10.576 +        err = -EINVAL;
  10.577 +        goto exit;
  10.578 +    }
  10.579 +    if(p->state->count == 2){
  10.580 +        err = hexdone(p);
  10.581 +    }
  10.582 +  exit:
  10.583 +    return err;
  10.584 +}
  10.585 +    
  10.586 +int state_hex(Parser *p, char c){
  10.587 +    int err = 0;
  10.588 +    if(at_eof(p)){
  10.589 +        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
  10.590 +        err = -EINVAL;
  10.591 +        goto exit;
  10.592 +    } else if('0' <= c && c <= '9'){
  10.593 +        err = hexdigit(p, c, '0');
  10.594 +    } else if('A' <= c && c <= 'F'){
  10.595 +        err = hexdigit(p, c, 'A');
  10.596 +    } else if('a' <= c && c <= 'f'){
  10.597 +        err = hexdigit(p, c, 'a');
  10.598 +    } else if(p->state->count){
  10.599 +        err =hexdone(p);
  10.600 +        if(err) goto exit;
  10.601 +        Parser_input_char(p, c);
  10.602 +    }
  10.603 +  exit:
  10.604 +    return err;
  10.605 +}
  10.606 +
  10.607 +int begin_atom(Parser *p, char c){
  10.608 +    int err = 0;
  10.609 +    err = Parser_push(p, state_atom, "atom");
  10.610 +    if(err) goto exit;
  10.611 +    newtoken(p);
  10.612 +    err = savechar(p, c);
  10.613 +  exit:
  10.614 +    return err;
  10.615 +}
  10.616 +
  10.617 +int state_atom(Parser *p, char c){
  10.618 +    int err = 0;
  10.619 +    if(at_eof(p)){
  10.620 +        err = end_atom(p);
  10.621 +    } else if(is_separator(p, c) ||
  10.622 +              in_space_class(c) ||
  10.623 +              in_comment_class(c)){
  10.624 +        err = end_atom(p);
  10.625 +        if(err) goto exit;
  10.626 +        err = Parser_input_char(p, c);
  10.627 +    } else {
  10.628 +        err = savechar(p, c);
  10.629 +    }
  10.630 +  exit:
  10.631 +    return err;
  10.632 +}
  10.633 +
  10.634 +int end_atom(Parser *p){
  10.635 +    int err = 0;
  10.636 +    err = do_intern(p);
  10.637 +    if(err) goto exit;
  10.638 +    err = Parser_return(p);
  10.639 +  exit:
  10.640 +    return err;
  10.641 +}
  10.642 +
  10.643 +int state_list(Parser *p, char c){
  10.644 +    int err = 0;
  10.645 +    if(at_eof(p)){
  10.646 +        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
  10.647 +        err = -EINVAL;
  10.648 +    } else if(c == c_list_close){
  10.649 +        p->state->val = nrev(p->state->val);
  10.650 +        err = end_list(p);
  10.651 +    } else {
  10.652 +        err = state_start(p, c);
  10.653 +    }
  10.654 +    return err;
  10.655 +    
  10.656 +}
  10.657 +
  10.658 +int begin_list(Parser *p, char c){
  10.659 +    return Parser_push(p, state_list, "list");
  10.660 +}
  10.661 +
  10.662 +int end_list(Parser *p){
  10.663 +    return Parser_return(p);
  10.664 +}
  10.665 +
  10.666 +/** Reset the fields of a parser to initial values.
  10.667 + *
  10.668 + * @param z parser
  10.669 + */
  10.670 +static void reset(Parser *z){
  10.671 +  IOStream *error_out = z->error_out;
  10.672 +  int flags = z->flags;
  10.673 +  memzero(z, sizeof(Parser));
  10.674 +  z->buf_n = sizeof(z->buf) - 1;
  10.675 +  z->buf_i = 0;
  10.676 +  z->line_no = 1;
  10.677 +  z->char_no = 0;
  10.678 +  z->error_out = error_out;
  10.679 +  z->flags = flags;
  10.680 +}
  10.681 +
  10.682 +/** Set the parser error stream.
  10.683 + * Parse errors are reported on the the error stream if it is non-null.
  10.684 + * 
  10.685 + * @param z parser
  10.686 + * @param error_out error stream
  10.687 + */
  10.688 +void set_error_stream(Parser *z, IOStream *error_out){
  10.689 +  if(z){
  10.690 +    z->error_out = error_out;
  10.691 +  }
  10.692 +}
  10.693 +
  10.694 +/** Get the parser error message for an error code.
  10.695 + *
  10.696 + * @param id error code
  10.697 + * @return error message (empty string if the code is unknown)
  10.698 + */
  10.699 +static char *get_message(ParseErrorId id){
  10.700 +  int i;
  10.701 +  for(i=0; i<catalog_n; i++){
  10.702 +    if(id == catalog[i].id){
  10.703 +      return catalog[i].message;
  10.704 +    }
  10.705 +  }
  10.706 +  return "";
  10.707 +}
  10.708 +
  10.709 +/** Get the line number.
  10.710 + *
  10.711 + * @param in parser
  10.712 + */
  10.713 +int get_line(Parser *in){
  10.714 +  return in->line_no;
  10.715 +}
  10.716 +
  10.717 +/** Get the column number.
  10.718 + *
  10.719 + * @param in parser
  10.720 + */
  10.721 +int get_column(Parser *in){
  10.722 +  return in->char_no;
  10.723 +}
  10.724 +
  10.725 +/** Get the line number the current token started on.
  10.726 + *
  10.727 + * @param in parser
  10.728 + */
  10.729 +int get_tok_line(Parser *in){
  10.730 +  return in->tok_begin_line;
  10.731 +}
  10.732 +
  10.733 +/** Get the column number the current token started on.
  10.734 + *
  10.735 + * @param in parser
  10.736 + */
  10.737 +int get_tok_column(Parser *in){
  10.738 +  return in->tok_begin_char;
  10.739 +}
  10.740 +
  10.741 +/** Report a parse error.
  10.742 + * Does nothing if the error stream is null or there is no error.
  10.743 + *
  10.744 + * @param in parser
  10.745 + */
  10.746 +static void report_error(Parser *in){
  10.747 +  if(in->error_out && in->err){
  10.748 +    char *msg = get_message(in->err);
  10.749 +    char *tok = peek_token(in);
  10.750 +    IOStream_print(in->error_out, PARSE_ERR_FMT,
  10.751 +		   get_tok_line(in), get_tok_column(in), msg);
  10.752 +    if(tok && tok[0]){
  10.753 +        IOStream_print(in->error_out, " '%s'", tok);
  10.754 +    }
  10.755 +    IOStream_print(in->error_out, "\n");
  10.756 +  }
  10.757 +}
  10.758 +
  10.759 +/** Get the error message for the current parse error code.
  10.760 + * Does nothing if there is no error.
  10.761 + *
  10.762 + * @param in parser
  10.763 + * @param buf where to place the message
  10.764 + * @param n maximum number of characters to place in buf
  10.765 + * @return current error code (zero for no error)
  10.766 + */
  10.767 +int parse_error_message(Parser *in, char *buf, int n){
  10.768 +    if(in->err){
  10.769 +        char *msg = get_message(in->err);
  10.770 +        snprintf(buf, n, PARSE_ERR_FMT, get_tok_line(in), get_tok_column(in), msg);
  10.771 +    }
  10.772 +    return in->err;
  10.773 +}
  10.774 +
  10.775 +/** Flag an unspecified parse error. All subsequent reads will fail.
  10.776 + *
  10.777 + * @param in parser
  10.778 + */
  10.779 +void parse_error(Parser *in){
  10.780 +    parse_error_id(in, PARSE_ERR_INVALID_SYNTAX);
  10.781 +}
  10.782 +
  10.783 +/** Flag a parse error. All subsequent reads will fail.
  10.784 + * Does not change the parser error code if it is already set.
  10.785 + *
  10.786 + * @param in parser
  10.787 + * @param id error code
  10.788 + */
  10.789 +void parse_error_id(Parser *in, ParseErrorId id){
  10.790 +    if(!in->err){
  10.791 +        in->err = id;
  10.792 +        report_error(in);
  10.793 +    }
  10.794 +}
  10.795 +
  10.796 +/** Test if the parser's error flag is set.
  10.797 + *
  10.798 + * @param in parser
  10.799 + * @return 1 if set, 0 otherwise
  10.800 + */
  10.801 +int has_error(Parser *in){
  10.802 +    return (in->err > 0);
  10.803 +}
  10.804 +
  10.805 +/** Test if the parser is at end of input.
  10.806 + *
  10.807 + * @param in parser
  10.808 + * @return 1 if at EOF, 0 otherwise
  10.809 + */
  10.810 +int at_eof(Parser *p){
  10.811 +    return p->eof;
  10.812 +}
  10.813 +
  10.814 +//#define SXPR_PARSER_MAIN
  10.815 +#ifdef SXPR_PARSER_MAIN
  10.816 +/* Stuff for standalone testing. */
  10.817 +
  10.818 +#include "file_stream.h"
  10.819 +#include "string_stream.h"
  10.820 +
  10.821 +int stringof(Sxpr exp, char **s){
  10.822 +    int err = 0;
  10.823 +    if(ATOMP(exp)){
  10.824 +        *s = atom_name(exp);
  10.825 +    } else if(STRINGP(exp)){
  10.826 +        *s = string_string(exp);
  10.827 +    } else {
  10.828 +        err = -EINVAL;
  10.829 +        *s = NULL;
  10.830 +    }
  10.831 +    return err;
  10.832 +}
  10.833 +
  10.834 +int child_string(Sxpr exp, Sxpr key, char **s){
  10.835 +    int err = 0;
  10.836 +    Sxpr val = sxpr_child_value(exp, key, ONONE);
  10.837 +    err = stringof(val, s);
  10.838 +    return err;
  10.839 +}
  10.840 +
  10.841 +int intof(Sxpr exp, int *v){
  10.842 +    int err = 0;
  10.843 +    char *s;
  10.844 +    unsigned long l;
  10.845 +    if(INTP(exp)){
  10.846 +        *v = OBJ_INT(exp);
  10.847 +    } else {
  10.848 +        err = stringof(exp, &s);
  10.849 +        if(err) goto exit;
  10.850 +        err = convert_atoul(s, &l);
  10.851 +        *v = (int)l;
  10.852 +    }
  10.853 + exit:
  10.854 +    return err;
  10.855 +}
  10.856 +
  10.857 +int child_int(Sxpr exp, Sxpr key, int *v){
  10.858 +    int err = 0;
  10.859 +    Sxpr val = sxpr_child_value(exp, key, ONONE);
  10.860 +    err = intof(val, v);
  10.861 +    return err;
  10.862 +}
  10.863 +
  10.864 +int eval_vnet(Sxpr exp){
  10.865 +    int err = 0;
  10.866 +    Sxpr oid = intern("id");
  10.867 +    int id;
  10.868 +    err = child_int(exp, oid, &id);
  10.869 +    if(err) goto exit;
  10.870 +    dprintf("> vnet id=%d\n", id);
  10.871 + exit:
  10.872 +    dprintf("< err=%d\n", err);
  10.873 +    return err;
  10.874 +}
  10.875 +
  10.876 +int eval_connect(Sxpr exp){
  10.877 +    int err = 0;
  10.878 +    Sxpr ovif = intern("vif");
  10.879 +    Sxpr ovnet = intern("vnet");
  10.880 +    char *vif;
  10.881 +    int vnet;
  10.882 +
  10.883 +    err = child_string(exp, ovif, &vif);
  10.884 +    if(err) goto exit;
  10.885 +    err = child_int(exp, ovnet, &vnet);
  10.886 +    if(err) goto exit;
  10.887 +    dprintf("> connect vif=%s vnet=%d\n", vif, vnet);
  10.888 + exit:
  10.889 +    dprintf("< err=%d\n", err);
  10.890 +    return err;
  10.891 +}
  10.892 +
  10.893 +int eval(Sxpr exp){
  10.894 +    int err = 0;
  10.895 +    Sxpr oconnect = intern("connect");
  10.896 +    Sxpr ovnet = intern("vnet");
  10.897 +    
  10.898 +    if(sxpr_elementp(exp, ovnet)){
  10.899 +        err = eval_vnet(exp);
  10.900 +    } else if(sxpr_elementp(exp, oconnect)){
  10.901 +        err = eval_connect(exp);
  10.902 +    } else {
  10.903 +        err = -EINVAL;
  10.904 +    }
  10.905 +    return err;
  10.906 +}
  10.907 +
  10.908 +/** Main program for testing.
  10.909 + * Parses input and prints it.
  10.910 + *
  10.911 + * @param argc number of arguments
  10.912 + * @param argv arguments
  10.913 + * @return error code
  10.914 + */
  10.915 +int main(int argc, char *argv[]){
  10.916 +    Parser *pin;
  10.917 +    int err = 0;
  10.918 +    char buf[1024];
  10.919 +    int k;
  10.920 +    Sxpr obj;
  10.921 +    //Sxpr l, x;
  10.922 +    int i = 0;
  10.923 +
  10.924 +    pin = Parser_new();
  10.925 +    set_error_stream(pin, iostdout);
  10.926 +    dprintf("> parse...\n");
  10.927 +    while(1){
  10.928 +        k = fread(buf, 1, 1, stdin);
  10.929 +        err = Parser_input(pin, buf, k);
  10.930 +        while(Parser_ready(pin)){
  10.931 +            obj = Parser_get_val(pin);
  10.932 +            printf("obj %d\n", i++);
  10.933 +            objprint(iostdout, obj, 0); printf("\n");
  10.934 +        }
  10.935 +        if(k <= 0) break;
  10.936 +    }
  10.937 +/*     obj = Parser_get_all(pin); */
  10.938 +/*     for(l = obj ; CONSP(l); l = CDR(l)){ */
  10.939 +/*         x = CAR(l); */
  10.940 +/*         objprint(iostdout, x, 0); printf("\n"); */
  10.941 +/*         eval(x); */
  10.942 +/*     } */
  10.943 +    dprintf("> err=%d\n", err);
  10.944 +    return 0;
  10.945 +}
  10.946 +#endif
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/xfrd/sxpr_parser.h	Wed Jul 07 19:33:06 2004 +0000
    11.3 @@ -0,0 +1,133 @@
    11.4 +/*
    11.5 + *
    11.6 + * This library is free software; you can redistribute it and/or modify
    11.7 + * it under the terms of the GNU Lesser General Public License as
    11.8 + * published by the Free Software Foundation; either version 2.1 of the
    11.9 + * License, or  (at your option) any later version. This library is 
   11.10 + * distributed in the  hope that it will be useful, but WITHOUT ANY
   11.11 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.12 + * FITNESS FOR A PARTICULAR PURPOSE.
   11.13 + * See the GNU Lesser General Public License for more details.
   11.14 + *
   11.15 + * You should have received a copy of the GNU Lesser General Public License
   11.16 + * along with this library; if not, write to the Free Software Foundation,
   11.17 + * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   11.18 + */
   11.19 +
   11.20 +#ifndef _XUTIL_SXPR_PARSER_H_
   11.21 +#define _XUTIL_SXPR_PARSER_H_
   11.22 +
   11.23 +#include "sxpr.h"
   11.24 +#include "iostream.h"
   11.25 +
   11.26 +/** @file
   11.27 + * Sxpr parsing definitions.
   11.28 + */
   11.29 +
   11.30 +/** Size of a parser input buffer.
   11.31 + * Tokens read must fit into this size (including trailing null).
   11.32 + */
   11.33 +#define PARSER_BUF_SIZE 1024
   11.34 +
   11.35 +struct Parser;
   11.36 +typedef int ParserStateFn(struct Parser *, char c);
   11.37 +
   11.38 +typedef struct ParserState {
   11.39 +    struct ParserState *parent;
   11.40 +    Sxpr val;
   11.41 +    int ival;
   11.42 +    int count;
   11.43 +    char delim;
   11.44 +    ParserStateFn *fn;
   11.45 +    char *name;
   11.46 +} ParserState;
   11.47 +
   11.48 +/** Structure representing an input source for the parser.
   11.49 + * Can read from any IOStream implementation.
   11.50 + */
   11.51 +typedef struct Parser {
   11.52 +    Sxpr val;
   11.53 +    /** Error reporting stream (null for no reports). */
   11.54 +    IOStream *error_out;
   11.55 +    int eof;
   11.56 +    /** Error flag. Non-zero if there has been a read error. */
   11.57 +    int err;
   11.58 +    /** Line number on input (from 1). */
   11.59 +    int line_no;
   11.60 +    /** Column number of input (reset on new line). */
   11.61 +    int char_no;
   11.62 +    /** Lookahead character. */
   11.63 +    char c;
   11.64 +    /** Buffer for reading tokens. */
   11.65 +    char buf[PARSER_BUF_SIZE];
   11.66 +    /** Size of token buffer. */
   11.67 +    int buf_n;
   11.68 +    int buf_i;
   11.69 +    /** Line the last token started on. */
   11.70 +    int tok_begin_line;
   11.71 +    /** Character number the last token started on. */
   11.72 +    int tok_begin_char;
   11.73 +    /** Parsing flags. */
   11.74 +    int flags;
   11.75 +    ParserState *state;
   11.76 +    ParserState *start_state;
   11.77 +} Parser;
   11.78 +
   11.79 +/** Parser error codes. */
   11.80 +typedef enum {
   11.81 +    PARSE_ERR_NONE=0,
   11.82 +    PARSE_ERR_UNSPECIFIED,
   11.83 +    PARSE_ERR_NOMEM,
   11.84 +    PARSE_ERR_UNEXPECTED_EOF,
   11.85 +    PARSE_ERR_TOKEN_TOO_LONG,
   11.86 +    PARSE_ERR_INVALID_SYNTAX,
   11.87 +    PARSE_ERR_INVALID_ESCAPE,
   11.88 +} ParseErrorId;
   11.89 +
   11.90 +
   11.91 +/** Parser flags. */
   11.92 +//enum {
   11.93 +//};
   11.94 +
   11.95 +/** Raise some parser flags.
   11.96 + *
   11.97 + * @param in parser
   11.98 + * @param flags flags mask
   11.99 + */
  11.100 +inline static void parser_flags_raise(Parser *in, int flags){
  11.101 +    in->flags |= flags;
  11.102 +}
  11.103 +
  11.104 +/** Lower some parser flags.
  11.105 + *
  11.106 + * @param in parser
  11.107 + * @param flags flags mask
  11.108 + */
  11.109 +inline static void parser_flags_lower(Parser *in, int flags){
  11.110 +    in->flags &= ~flags;
  11.111 +}
  11.112 +
  11.113 +/** Clear all parser flags.
  11.114 + *
  11.115 + * @param in parser
  11.116 + */
  11.117 +inline static void parser_flags_clear(Parser *in){
  11.118 +    in->flags = 0;
  11.119 +}
  11.120 +
  11.121 +extern void Parser_free(Parser *z);
  11.122 +extern Parser * Parser_new(void);
  11.123 +extern int Parser_input(Parser *p, char *buf, int buf_n);
  11.124 +extern int Parser_input_eof(Parser *p);
  11.125 +extern int Parser_input_char(Parser *p, char c);
  11.126 +extern void set_error_stream(Parser *z, IOStream *error_out);
  11.127 +
  11.128 +extern int parse_error_message(Parser *in, char *buf, int n);
  11.129 +extern int has_error(Parser *in);
  11.130 +extern int at_eof(Parser *in);
  11.131 +
  11.132 +int Parser_ready(Parser *p);
  11.133 +Sxpr Parser_get_val(Parser *p);
  11.134 +Sxpr Parser_get_all(Parser *p);
  11.135 +
  11.136 +#endif /* ! _XUTIL_SXPR_PARSER_H_ */
    12.1 --- a/tools/xfrd/xen_domain.c	Wed Jul 07 18:57:28 2004 +0000
    12.2 +++ b/tools/xfrd/xen_domain.c	Wed Jul 07 19:33:06 2004 +0000
    12.3 @@ -38,7 +38,7 @@ int xen_domain_snd(Conn *xend, IOStream 
    12.4          if(d > buf_n) d = buf_n;
    12.5          err = marshal_bytes(io, buf, d);
    12.6          if(err) goto exit;
    12.7 -        //dprintf("> k=%d n=%d\n", k, n);
    12.8 +        dprintf("> k=%d n=%d\n", k, n);
    12.9      }
   12.10      
   12.11    exit:
   12.12 @@ -68,7 +68,7 @@ int xen_domain_rcv(IOStream *io, uint32_
   12.13          if(d > buf_n) d = buf_n;
   12.14          err = unmarshal_bytes(io, buf, d);
   12.15          if(err) goto exit;
   12.16 -        //dprintf("> k=%d n=%d\n", k, n);
   12.17 +        dprintf("> k=%d n=%d\n", k, n);
   12.18      }
   12.19    exit:
   12.20  #else    
    13.1 --- a/tools/xfrd/xfrd.c	Wed Jul 07 18:57:28 2004 +0000
    13.2 +++ b/tools/xfrd/xfrd.c	Wed Jul 07 19:33:06 2004 +0000
    13.3 @@ -36,7 +36,7 @@
    13.4  #include "sys_net.h"
    13.5  #include "sys_string.h"
    13.6  
    13.7 -#include "xdr.h"
    13.8 +//#include "xdr.h"
    13.9  #include "enum.h"
   13.10  #include "xfrd.h"
   13.11  
   13.12 @@ -362,10 +362,10 @@ int addrof(Sxpr exp, uint32_t *v){
   13.13      err = stringof(exp, &h);
   13.14      if(err) goto exit;
   13.15      if(get_host_address(h, &a)){
   13.16 -        *v = a;
   13.17 -    } else {
   13.18          err = -EINVAL;
   13.19 +        goto exit;
   13.20      }
   13.21 +    *v = a;
   13.22    exit:
   13.23      dprintf("< err=%d v=%x\n", err, *v);
   13.24      return err;
   13.25 @@ -383,11 +383,12 @@ int portof(Sxpr exp, uint16_t *v){
   13.26          unsigned long p;
   13.27          err = stringof(exp, &s);
   13.28          if(err) goto exit;
   13.29 -        if(get_service_port(s, &p)){
   13.30 -            *v = p;
   13.31 -        } else {
   13.32 +        err = convert_service_to_port(s, &p);
   13.33 +        if(err){
   13.34              err = -EINVAL;
   13.35 +            goto exit;
   13.36          }
   13.37 +        *v = p;
   13.38      }
   13.39    exit:
   13.40      dprintf("< err=%d v=%u\n", err, *v);
   13.41 @@ -414,20 +415,12 @@ time_t stats(time_t t0, uint64_t offset,
   13.42   */
   13.43  int xfr_error(Conn *conn, int errcode){
   13.44      int err = 0;
   13.45 +
   13.46      if(!conn->out) return -ENOTCONN;
   13.47 -    err = pack_type(conn->out, T_CONS);
   13.48 -    if(err) goto exit;
   13.49 -    err = pack_bool(conn->out, 1);
   13.50 -    if(err) goto exit;
   13.51 -    err = pack_sxpr(conn->out, oxfr_err);
   13.52 -    if(err) goto exit;
   13.53 -    err = pack_bool(conn->out, 1);
   13.54 -    if(err) goto exit;
   13.55 -    err = pack_sxpr(conn->out, mkint(errcode));
   13.56 -    if(err) goto exit;
   13.57 -    err = pack_bool(conn->out, 0);
   13.58 -  exit:
   13.59 -    return err;
   13.60 +    if(errcode <0) errcode = -errcode;
   13.61 +    err = IOStream_print(conn->out, "(%s %d)",
   13.62 +                         atom_name(oxfr_err), errcode);
   13.63 +    return (err < 0 ? err : 0);
   13.64  }
   13.65  
   13.66  /** Read a response message - error or ok.
   13.67 @@ -441,7 +434,7 @@ int xfr_response(Conn *conn){
   13.68  
   13.69      dprintf(">\n");
   13.70      if(!conn->out) return -ENOTCONN;
   13.71 -    err = unpack_sxpr(conn->in, &sxpr);
   13.72 +    err = Conn_sxpr(conn, &sxpr);
   13.73      if(err) goto exit;
   13.74      if(sxpr_elementp(sxpr, oxfr_err)){
   13.75          int errcode;
   13.76 @@ -468,7 +461,7 @@ int xfr_hello(Conn *conn){
   13.77      Sxpr sxpr;
   13.78      if(!conn->in) return -ENOTCONN;
   13.79      dprintf(">\n");
   13.80 -    err = unpack_sxpr(conn->in, &sxpr);
   13.81 +    err = Conn_sxpr(conn, &sxpr);
   13.82      if(err) goto exit;
   13.83      if(!sxpr_elementp(sxpr, oxfr_hello)){
   13.84          dprintf("> sxpr_elementp test failed\n");
   13.85 @@ -503,21 +496,12 @@ int xfr_hello(Conn *conn){
   13.86  int xfr_send_hello(Conn *conn){
   13.87      int err = 0;
   13.88      dprintf(">\n");
   13.89 -    err = pack_type(conn->out, T_CONS);
   13.90 -    if(err) goto exit;
   13.91 -    err = pack_bool(conn->out, 1);
   13.92 -    if(err) goto exit;
   13.93 -    err = pack_sxpr(conn->out, oxfr_hello);
   13.94 -    if(err) goto exit;
   13.95 -    err = pack_bool(conn->out, 1);
   13.96 -    if(err) goto exit;
   13.97 -    err = pack_sxpr(conn->out, mkint(XFR_PROTO_MAJOR));
   13.98 -    if(err) goto exit;
   13.99 -    err = pack_bool(conn->out, 1);
  13.100 -    if(err) goto exit;
  13.101 -    err = pack_sxpr(conn->out, mkint(XFR_PROTO_MINOR));
  13.102 -    if(err) goto exit;
  13.103 -    err = pack_bool(conn->out, 0);
  13.104 +
  13.105 +    err = IOStream_print(conn->out, "(%s %d %d)",
  13.106 +                         atom_name(oxfr_hello),
  13.107 +                         XFR_PROTO_MAJOR,
  13.108 +                         XFR_PROTO_MINOR);
  13.109 +    if(err < 0) goto exit;
  13.110      IOStream_flush(conn->out);
  13.111      dprintf("> xfr_response...\n");
  13.112      err = xfr_response(conn);
  13.113 @@ -528,55 +512,26 @@ int xfr_send_hello(Conn *conn){
  13.114  
  13.115  int xfr_send_xfr(Conn *conn, uint32_t vmid){
  13.116      int err;
  13.117 -    err = pack_type(conn->out, T_CONS);
  13.118 -    if(err) goto exit;
  13.119 -    err = pack_bool(conn->out, 1);
  13.120 -    if(err) goto exit;
  13.121 -    err = pack_sxpr(conn->out, oxfr_xfr);
  13.122 -    if(err) goto exit;
  13.123 -    err = pack_bool(conn->out, 1);
  13.124 -    if(err) goto exit;
  13.125 -    err = pack_sxpr(conn->out, mkint(vmid));
  13.126 -    if(err) goto exit;
  13.127 -    err = pack_bool(conn->out, 0);
  13.128 -    if(err) goto exit;
  13.129 -  exit:
  13.130 -    return err;
  13.131 +
  13.132 +    err = IOStream_print(conn->out, "(%s %d)",
  13.133 +                         atom_name(oxfr_xfr), vmid);
  13.134 +    return (err < 0 ? err : 0);
  13.135  }
  13.136  
  13.137  int xfr_send_ok(Conn *conn, uint32_t vmid){
  13.138      int err = 0;
  13.139 -    err = pack_type(conn->out, T_CONS);
  13.140 -    if(err) goto exit;
  13.141 -    err = pack_bool(conn->out, 1);
  13.142 -    if(err) goto exit;
  13.143 -    err = pack_sxpr(conn->out, oxfr_ok);
  13.144 -    if(err) goto exit;
  13.145 -    err = pack_bool(conn->out, 1);
  13.146 -    if(err) goto exit;
  13.147 -    err = pack_sxpr(conn->out, mkint(vmid));
  13.148 -    if(err) goto exit;
  13.149 -    err = pack_bool(conn->out, 0);
  13.150 -  exit:
  13.151 -    return err;
  13.152 +
  13.153 +    err = IOStream_print(conn->out, "(%s %d)",
  13.154 +                         atom_name(oxfr_ok), vmid);
  13.155 +    return (err < 0 ? err : 0);
  13.156  }
  13.157  
  13.158  int xfr_send_suspend(Conn *conn, uint32_t vmid){
  13.159      int err = 0;
  13.160  
  13.161 -    err = pack_type(conn->out, T_CONS);
  13.162 -    if(err) goto exit;
  13.163 -    err = pack_bool(conn->out, 1);
  13.164 -    if(err) goto exit;
  13.165 -    err = pack_sxpr(conn->out, oxfr_suspend);
  13.166 -    if(err) goto exit;
  13.167 -    err = pack_bool(conn->out, 1);
  13.168 -    if(err) goto exit;
  13.169 -    err = pack_sxpr(conn->out, mkint(vmid));
  13.170 -    if(err) goto exit;
  13.171 -    err = pack_bool(conn->out, 0);
  13.172 -  exit:
  13.173 -    return err;
  13.174 +    err = IOStream_print(conn->out, "(%s %d)",
  13.175 +                         atom_name(oxfr_suspend), vmid);
  13.176 +    return (err < 0 ? err : 0);
  13.177  }
  13.178  
  13.179  /** Get vm state. Send transfer message.
  13.180 @@ -594,11 +549,12 @@ int xfr_send_state(XfrState *state, Conn
  13.181      // Send xfr message and the domain state.
  13.182      err = xfr_send_xfr(peer, state->vmid);
  13.183      if(err) goto exit;
  13.184 -    err = xen_domain_snd(xend, peer->out, state->vmid, state->vmconfig, state->vmconfig_n);
  13.185 +    err = xen_domain_snd(xend, peer->out,
  13.186 +                         state->vmid, state->vmconfig, state->vmconfig_n);
  13.187      if(err) goto exit;
  13.188      IOStream_flush(peer->out);
  13.189      // Read the response from the peer.
  13.190 -    err = unpack_sxpr(peer->in, &sxpr);
  13.191 +    err = Conn_sxpr(peer, &sxpr);
  13.192      if(err) goto exit;
  13.193      if(sxpr_elementp(sxpr, oxfr_err)){
  13.194          // Error.
  13.195 @@ -785,10 +741,14 @@ int xfrd_service(Args *args, int peersoc
  13.196      dprintf(">\n");
  13.197      err = Conn_init(conn, flags, peersock, peer_in);
  13.198      if(err) goto exit;
  13.199 +    dprintf(">xfr_hello... \n");
  13.200      err = xfr_hello(conn);
  13.201      if(err) goto exit;
  13.202 -    err = unpack_sxpr(conn->in, &sxpr);
  13.203 +    dprintf("> sxpr...\n");
  13.204 +    err = Conn_sxpr(conn, &sxpr);
  13.205      if(err) goto exit;
  13.206 +    dprintf("> sxpr=\n");
  13.207 +    objprint(iostdout, sxpr, PRINT_TYPE); IOStream_print(iostdout, "\n");
  13.208      if(sxpr_elementp(sxpr, oxfr_migrate)){
  13.209          // Migrate message from xend.
  13.210          uint32_t addr;
    14.1 --- a/tools/xfrd/xfrdClient.py	Wed Jul 07 18:57:28 2004 +0000
    14.2 +++ b/tools/xfrd/xfrdClient.py	Wed Jul 07 19:33:06 2004 +0000
    14.3 @@ -34,13 +34,11 @@ class TCPClient:
    14.4          
    14.5          self.sockin = self.sock.makefile("r")
    14.6          self.sockout = self.sock.makefile("w")
    14.7 -        self.packer = SxpPacker(self.sockout)
    14.8 -        self.unpacker = SxpUnpacker(self.sockin)
    14.9          #pass
   14.10  
   14.11      def request(self, req):
   14.12          print "request>", req
   14.13 -        self.packer.pack(req)
   14.14 +        sxp.show(req, out=self.sockout)
   14.15          self.sockout.flush()
   14.16          print "request<"
   14.17  
   14.18 @@ -52,10 +50,10 @@ class TCPClient:
   14.19  
   14.20      def read(self):
   14.21          while(1):
   14.22 -            v = self.unpacker.unpack()
   14.23 +            v = self.sockin.read()
   14.24              print 'read>', v
   14.25 -            if v[0] == 'xfr.err' and v[1]: return
   14.26 -            if v[0] == 'xfr.ok': return
   14.27 +            #if v[0] == 'xfr.err' and v[1]: return
   14.28 +            #if v[0] == 'xfr.ok': return
   14.29  
   14.30  XFR_PROTO_MAJOR = 1
   14.31  XFR_PROTO_MINOR = 0