示例#1
0
 def _select(self, config, ls):
     if len(ls) != 2:
         log.warning('invalid select statement')
     else:
         r = self.macros.set_read_map(ls[1])
         log.trace('config: %s: _select: %s %s %r' % \
                       (self.init_name, r, ls[1], self.macros.maps()))
示例#2
0
 def _process_data(self, results, directive, info, data):
     new_data = []
     for l in results[1]:
         if l.startswith('%error'):
             l = self._expand(l)
             raise error.general('config error: %s' % (l[7:]))
         elif l.startswith('%warning'):
             l = self._expand(l)
             log.stderr('warning: %s' % (l[9:]))
             log.warning(l[9:])
         if not directive:
             l = self._expand(l)
             ls = self.tags.split(l, 1)
             log.trace('config: %s: _tag: %s %s' % (self.init_name, l, ls))
             if len(ls) > 1:
                 info = ls[0].lower()
                 if info[-1] == ':':
                     info = info[:-1]
                 info_data = ls[1].strip()
             else:
                 info_data = ls[0].strip()
             if info is not None:
                 self._info_append(info, info_data)
             else:
                 log.warning("invalid format: '%s'" % (info_data[:-1]))
         else:
             log.trace('config: %s: _data: %s %s' % (self.init_name, l, new_data))
             new_data.append(l)
     return (directive, info, data + new_data)
示例#3
0
 def __init__(self, name, opts, macros = None, directives = None, ignores = None):
     self.opts = opts
     if macros is None:
         self.macros = opts.defaults
     else:
         self.macros = macros
     self.init_name = name
     self.directives = ['%include']
     if directives:
         self.directives += directives
     self.ignores = ignores
     log.trace('config: %s' % (name))
     self.disable_macro_reassign = False
     self.configpath = []
     self.wss = re.compile(r'\s+')
     self.tags = re.compile(r':+')
     self.sf = re.compile(r'%\([^\)]+\)')
     for arg in self.opts.args:
         if arg.startswith('--with-') or arg.startswith('--without-'):
             label = arg[2:].lower().replace('-', '_')
             self.macros.define(label)
     self._includes = []
     self.load_depth = 0
     self.lc = 0
     self.name = 'none'
示例#4
0
 def _ifs(self, config, ls, label, iftrue, isvalid, dir, info):
     in_iftrue = True
     data = []
     while True:
         if isvalid and \
                 ((iftrue and in_iftrue) or (not iftrue and not in_iftrue)):
             this_isvalid = True
         else:
             this_isvalid = False
         r = self._parse(config, dir, info, roc = True, isvalid = this_isvalid)
         if r[0] == 'control':
             if r[1] == '%end':
                 self._error(label + ' without %endif')
                 raise error.general('terminating build')
             if r[1] == '%endif':
                 log.trace('config: %s: _ifs: %s %s' % (self.init_name, r[1], this_isvalid))
                 return data
             if r[1] == '%else':
                 in_iftrue = False
         elif r[0] == 'directive':
             if this_isvalid:
                 if r[1] == '%include':
                     self.load(r[2][0])
                     continue
                 dir, info, data = self._process_directive(r, dir, info, data)
         elif r[0] == 'data':
             if this_isvalid:
                 dir, info, data = self._process_data(r, dir, info, data)
         else:
             dir, info, data = self._process_block(r, dir, info, data)
示例#5
0
 def open(self, command, capture = True, shell = False,
          cwd = None, env = None,
          stdin = None, stdout = None, stderr = None,
          timeout = None):
     """Open a command with arguments. Provide the arguments as a list or
     a string."""
     if self.verbose:
         s = command
         if type(command) is list:
             def add(x, y): return x + ' ' + str(y)
             s = functools.reduce(add, command, '')[1:]
         what = 'spawn'
         if shell:
             what = 'shell'
         log.output(what + ': ' + s)
     if self.output is None:
         raise error.general('capture needs an output handler')
     if shell and self.shell_exe:
         command = arg_list(command)
         command[:0] = self.shell_exe
     if not stdin and self.input:
         stdin = subprocess.PIPE
     if not stdout:
         stdout = subprocess.PIPE
     if not stderr:
         stderr = subprocess.PIPE
     proc = None
     if cwd is None:
         cwd = self.path
     if env is None:
         env = self.environment
     try:
         # Work around a problem on Windows with commands that
         # have a '.' and no extension. Windows needs the full
         # command name.
         if sys.platform == "win32" and type(command) is list:
             if command[0].find('.') >= 0:
                 r, e = os.path.splitext(command[0])
                 if e not in ['.exe', '.com', '.bat']:
                     command[0] = command[0] + '.exe'
         log.trace('exe: %s' % (command))
         proc = subprocess.Popen(command, shell = shell,
                                 cwd = cwd, env = env,
                                 stdin = stdin, stdout = stdout,
                                 stderr = stderr,
                                 close_fds = False)
         if not capture:
             return (0, proc)
         if self.output is None:
             raise error.general('capture needs an output handler')
         exit_code = self.capture(proc, command, timeout)
         if self.verbose:
             log.output('exit: ' + str(exit_code))
     except OSError as ose:
         exit_code = ose.errno
         if self.verbose:
             log.output('exit: ' + str(ose))
     return (exit_code, proc)
示例#6
0
 def _disable(self, config, ls):
     if len(ls) != 2:
         log.warning('invalid disable statement')
     else:
         if ls[1] == 'select':
             self.macros.lock_read_map()
             log.trace('config: %s: _disable_select: %s' % (self.init_name, ls[1]))
         else:
             log.warning('invalid disable statement: %s' % (ls[1]))
示例#7
0
文件: git.py 项目: zulusw/rtems-tools
 def _run(self, args, check=False):
     e = execute.capture_execution()
     if path.exists(self.path):
         cwd = self.path
     else:
         cwd = None
     cmd = [self.git] + args
     log.trace('cmd: (%s) %s' % (str(cwd), ' '.join(cmd)))
     exit_code, proc, output = e.spawn(cmd, cwd=path.host(cwd))
     log.trace(output)
     if check:
         self._git_exit_code(exit_code, cmd, output)
     return exit_code, output
示例#8
0
 def load(self, name):
     names = self.expand(name).split(':')
     for n in names:
         log.trace('opening: %s' % (n))
         if path.exists(n):
             try:
                 mc = open(path.host(n), 'r')
                 macros = self.parse(mc)
                 mc.close()
                 self.files += [n]
                 return
             except IOError as err:
                 pass
     raise error.general('opening macro file: %s' % \
                             (path.host(self.expand(name))))
示例#9
0
 def start(self):
     '''Start the TFTP server. Returns once started.'''
     # pylint: disable=attribute-defined-outside-init
     if log.tracing:
         log.trace('] tftp: server: %s:%i' % (self.host, self.port))
     if self.host == 'all':
         host = ''
     else:
         host = self.host
     try:
         self.server = udp_server((host, self.port), udp_handler)
     except Exception as exp:
         raise error.general('tftp server create: %s' % (exp))
     # We cannot set tftp in __init__ because the object is created
     # in a separate package.
     self.server.tftp = self
     self.server_thread = threading.Thread(target=self.server.serve_forever)
     self.server_thread.daemon = True
     self.server_thread.start()
示例#10
0
 def handle(self):
     client_ip = self.client_address[0]
     client_port = self.client_address[1]
     client = '%s:%i' % (client_ip, client_port)
     session = tftp_session()
     finished = session.data(client_ip, client_port, self.request[0])
     if not finished:
         timeout = session.get_timeout(self.server.proxy.session_timeout, 1)
         host = self.server.proxy.get_host(client_ip)
         if host is not None:
             session_count = self.server.proxy.get_session_count()
             log.notice(' ] %6d: session: %s -> %s: start' %
                        (session_count, client, host))
             host_ip, host_server_port = host_port_split(host)
             host_port = host_server_port
             sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
             sock.settimeout(timeout)
             log.trace(
                 '  > ' +
                 session.decode(client_ip, client_port, self.request[0]))
             sock.sendto(self.request[0], (host_ip, host_port))
             while not finished:
                 try:
                     data, address = sock.recvfrom(16 * 1024)
                 except socket.error as se:
                     log.notice(' ] session: %s -> %s: error: %s' %
                                (client, host, se))
                     return
                 except socket.gaierror as se:
                     log.notice(' ] session: %s -> %s: error: %s' %
                                (client, host, se))
                     return
                 except:
                     return
                 finished = session.data(address[0], address[1], data)
                 if address[0] == host_ip:
                     if host_port == host_server_port:
                         host_port = address[1]
                     if address[1] == host_port:
                         log.trace(
                             '  < ' +
                             session.decode(address[0], address[1], data))
                         sock.sendto(data, (client_ip, client_port))
                 elif address[0] == client_ip and address[1] == client_port:
                     log.trace('  > ' +
                               session.decode(address[0], address[1], data))
                     sock.sendto(data, (host_ip, host_port))
             log.notice(' ] %6d: session: %s -> %s: end' %
                        (session_count, client, host))
         else:
             mac = getmac.get_mac_address(ip=client_ip)
             log.trace(' . request: host not found: %s (%s)' %
                       (client, mac))
示例#11
0
def host_setup(opts):
    """ Basic sanity check. All executables and directories must exist."""

    checks = {
        'none': _check_none,
        'triplet': _check_triplet,
        'dir': _check_dir,
        'exe': _check_exe
    }

    sane = True

    for d in list(opts.defaults.keys()):
        try:
            (test, constraint, value) = opts.defaults.get(d)
        except:
            if opts.defaults.get(d) is None:
                raise error.general('invalid default: %s: not found' % (d))
            else:
                raise error.general('invalid default: %s [%r]' %
                                    (d, opts.defaults.get(d)))
        if test != 'none':
            value = opts.defaults.expand(value)
            if test not in checks:
                raise error.general('invalid check test: %s [%r]' %
                                    (test, opts.defaults.get(d)))
            ok = checks[test](opts, d, value, constraint)
            if ok:
                tag = ' '
            else:
                tag = '*'
            log.trace('%c %15s: %r -> "%s"' %
                      (tag, d, opts.defaults.get(d), value))
            if sane and not ok:
                sane = False

    return sane
示例#12
0
def _check_exe(_opts, macro, value, constraint, silent=False):

    if len(value) == 0 or constraint == 'none':
        return True

    orig_value = value

    if path.isabspath(value):
        if path.isfile(value):
            return True
        if os.name == 'nt':
            if path.isfile('%s.exe' % (value)):
                return True
        value = path.basename(value)
        absexe = True
    else:
        absexe = False

    paths = os.environ['PATH'].split(os.pathsep)

    if _check_paths(value, paths):
        if absexe:
            if not silent:
                log.notice(
                    'warning: exe: absolute exe found in path: (%s) %s' %
                    (macro, orig_value))
        return True

    if constraint == 'optional':
        if not silent:
            log.trace('warning: exe: optional exe not found: (%s) %s' %
                      (macro, orig_value))
        return True

    if not silent:
        log.notice('error: exe: not found: (%s) %s' % (macro, orig_value))
    return False
示例#13
0
 def handle_session(self, index):
     '''Handle the TFTP session data.'''
     # pylint: disable=too-many-locals
     # pylint: disable=broad-except
     # pylint: disable=too-many-branches
     # pylint: disable=too-many-statements
     client_ip = self.client_address[0]
     client_port = self.client_address[1]
     client = '%s:%i' % (client_ip, client_port)
     self._notice('] tftp: %d: start: %s' % (index, client))
     try:
         session = tftp_session(client_ip, client_port,
                                self.server.tftp.base,
                                self.server.tftp.forced_file,
                                self.server.tftp.reader)
         data = bytearray(self.request[0])
         response = session.process(client_ip, client_port, data)
         if response is not None:
             if log.tracing and self.server.tftp.packet_trace:
                 log.trace(' > ' +
                           session.decode(client_ip, client_port, data))
             timeout = session.get_timeout(self.server.tftp.timeout, 1)
             sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
             sock.bind(('', 0))
             sock.settimeout(timeout)
             while response is not None:
                 if log.tracing and self.server.tftp.packet_trace:
                     log.trace(
                         ' < ' +
                         session.decode(client_ip, client_port, response))
                 sock.sendto(response, (client_ip, client_port))
                 if session.finished:
                     break
                 try:
                     data, address = sock.recvfrom(2 + 2 +
                                                   session.get_block_size())
                     data = bytearray(data)
                     if log.tracing and self.server.tftp.packet_trace:
                         log.trace(
                             ' > ' +
                             session.decode(address[0], address[1], data))
                 except socket.error as serr:
                     if log.tracing:
                         log.trace('] tftp: %d: receive: %s: error: %s' \
                                   % (index, client, serr))
                     return
                 except socket.gaierror as serr:
                     if log.tracing:
                         log.trace('] tftp: %d: receive: %s: error: %s' \
                                   % (index, client, serr))
                     return
                 response = session.process(address[0], address[1], data)
     except error.general as gerr:
         self._notice('] tftp: %dd: error: %s' % (index, gerr))
     except error.internal as ierr:
         self._notice('] tftp: %d: error: %s' % (index, ierr))
     except error.exit:
         pass
     except KeyboardInterrupt:
         pass
     except Exception as exp:
         if self.server.tftp.exception_is_raise:
             raise
         self._notice('] tftp: %d: error: %s: %s' % (index, type(exp), exp))
     self._notice('] tftp: %d: end: %s' % (index, client))
示例#14
0
 def _notice(self, text):
     if self.server.tftp.notices:
         log.notice(text)
     else:
         log.trace(text)
示例#15
0
 def _error_response(self, code, message):
     if log.tracing:
         log.trace('tftp: error: %s:%d: %d: %s' %
                   (self.host, self.port, code, message))
     self.finished = True
     return self._response('ERROR', self._pack_bytes([code, message, 0]))
示例#16
0
    def _if(self, config, ls, isvalid, dir, info, invert = False):

        def add(x, y):
            return x + ' ' + str(y)

        istrue = False
        if isvalid:
            if len(ls) == 2:
                s = ls[1]
            else:
                s = (ls[1] + ' ' + ls[2])
            ifls = s.split()
            if len(ifls) == 1:
                #
                # Check if '%if %{x} == %{nil}' has both parts as nothing
                # which means '%if ==' is always True and '%if !=' is always false.
                #
                if ifls[0] == '==':
                    istrue = True
                elif ifls[0] == '!=':
                    istrue = False
                else:
                    istrue = _check_bool(ifls[0])
                    if istrue == None:
                        self._error('invalid if bool value: ' + functools.reduce(add, ls, ''))
                        istrue = False
            elif len(ifls) == 2:
                if ifls[0] == '!':
                    istrue = _check_bool(ifls[1])
                    if istrue == None:
                        self._error('invalid if bool value: ' + functools.reduce(add, ls, ''))
                        istrue = False
                    else:
                        istrue = not istrue
                else:
                    #
                    # Check is something is being checked against empty,
                    #   ie '%if %{x} == %{nil}'
                    # The logic is 'something == nothing' is False and
                    # 'something != nothing' is True.
                    #
                    if ifls[1] == '==':
                        istrue = False
                    elif  ifls[1] == '!=':
                        istrue = True
                    else:
                        self._error('invalid if bool operator: ' + functools.reduce(add, ls, ''))
            elif len(ifls) == 3:
                if ifls[1] == '==':
                    if ifls[0] == ifls[2]:
                        istrue = True
                    else:
                        istrue = False
                elif ifls[1] == '!=' or ifls[1] == '=!':
                    if ifls[0] != ifls[2]:
                        istrue = True
                    else:
                        istrue = False
                elif ifls[1] == '>':
                    if ifls[0] > ifls[2]:
                        istrue = True
                    else:
                        istrue = False
                elif ifls[1] == '>=' or ifls[1] == '=>':
                    if ifls[0] >= ifls[2]:
                        istrue = True
                    else:
                        istrue = False
                elif ifls[1] == '<=' or ifls[1] == '=<':
                    if ifls[0] <= ifls[2]:
                        istrue = True
                    else:
                        istrue = False
                elif ifls[1] == '<':
                    if ifls[0] < ifls[2]:
                        istrue = True
                    else:
                        istrue = False
                else:
                    self._error('invalid %if operator: ' + functools.reduce(add, ls, ''))
            else:
                self._error('malformed if: ' + functools.reduce(add, ls, ''))
            if invert:
                istrue = not istrue
            log.trace('config: %s: _if:  %s %s' % (self.init_name, ifls, str(istrue)))
        return self._ifs(config, ls, '%if', istrue, isvalid, dir, info)
示例#17
0
    def _parse(self, config, dir, info, roc = False, isvalid = True):
        # roc = return on control

        def _clean(line):
            line = line[0:-1]
            b = line.find('#')
            if b >= 0:
                line = line[1:b]
            return line.strip()

        #
        # Need to add code to count matching '{' and '}' and if they
        # do not match get the next line and add to the string until
        # they match. This closes an opening '{' that is on another
        # line.
        #
        for l in config:
            self.lc += 1
            l = _clean(l)
            if len(l) == 0:
                continue
            log.trace('config: %s: %03d: %s %s' % \
                          (self.init_name, self.lc, str(isvalid), l))
            lo = l
            if isvalid:
                l = self._expand(l)
            if len(l) == 0:
                continue
            if l[0] == '%':
                ls = self.wss.split(l, 2)
                los = self.wss.split(lo, 2)
                if ls[0] == '%disable':
                    if isvalid:
                        self._disable(config, ls)
                elif ls[0] == '%select':
                    if isvalid:
                        self._select(config, ls)
                elif ls[0] == '%error':
                    if isvalid:
                        return ('data', ['%%error %s' % (self._name_line_msg(l[7:]))])
                elif ls[0] == '%warning':
                    if isvalid:
                        return ('data', ['%%warning %s' % (self._name_line_msg(l[9:]))])
                elif ls[0] == '%define' or ls[0] == '%global':
                    if isvalid:
                        self._define(config, ls)
                elif ls[0] == '%undefine':
                    if isvalid:
                        self._undefine(config, ls)
                elif ls[0] == '%if':
                    d = self._if(config, ls, isvalid, dir, info)
                    if len(d):
                        log.trace('config: %s: %%if: %s' % (self.init_name, d))
                        return ('data', d)
                elif ls[0] == '%ifn':
                    d = self._if(config, ls, isvalid, dir, info, True)
                    if len(d):
                        log.trace('config: %s: %%ifn: %s' % (self.init_name, d))
                        return ('data', d)
                elif ls[0] == '%ifos':
                    d = self._ifos(config, ls, isvalid, dir, info)
                    if len(d):
                        return ('data', d)
                elif ls[0] == '%ifarch':
                    d = self._ifarch(config, True, ls, isvalid, dir, info)
                    if len(d):
                        return ('data', d)
                elif ls[0] == '%ifnarch':
                    d = self._ifarch(config, False, ls, isvalid, dir, info)
                    if len(d):
                        return ('data', d)
                elif ls[0] == '%endif':
                    if roc:
                        return ('control', '%endif', '%endif')
                    log.warning("unexpected '" + ls[0] + "'")
                elif ls[0] == '%else':
                    if roc:
                        return ('control', '%else', '%else')
                    log.warning("unexpected '" + ls[0] + "'")
                elif ls[0].startswith('%defattr'):
                    return ('data', [l])
                elif ls[0] == '%bcond_with':
                    if isvalid:
                        #
                        # Check if already defined. Would be by the command line or
                        # even a host specific default.
                        #
                        if self._label('with_' + ls[1]) not in self.macros:
                            self._define(config, (ls[0], 'without_' + ls[1]))
                elif ls[0] == '%bcond_without':
                    if isvalid:
                        if self._label('without_' + ls[1]) not in self.macros:
                            self._define(config, (ls[0], 'with_' + ls[1]))
                else:
                    pt = self._parse_token(lo, los, l, ls)
                    if pt is not None:
                        return pt
                    if self.ignores is not None:
                        for r in self.ignores:
                            if r.match(ls[0]) is not None:
                                return ('data', [l])
                    if isvalid:
                        for d in self.directives:
                            if ls[0].strip() == d:
                                return ('directive', ls[0].strip(), ls[1:])
                        log.warning("unknown directive: '" + ls[0] + "'")
                        return ('data', [lo])
            else:
                return ('data', [lo])
        return ('control', '%end', '%end')
示例#18
0
    def load(self, name):

        def common_end(left, right):
            end = ''
            while len(left) and len(right):
                if left[-1] != right[-1]:
                    return end
                end = left[-1] + end
                left = left[:-1]
                right = right[:-1]
            return end

        if self.load_depth == 0:
            self.in_error = False
            self.lc = 0
            self.name = name
            self.conditionals = {}

        self.load_depth += 1

        save_name = self.name
        save_lc = self.lc

        self.name = name
        self.lc = 0

        #
        # Locate the config file. Expand any macros then add the
        # extension. Check if the file exists, therefore directly
        # referenced. If not see if the file contains ':' or the path
        # separator. If it does split the path else use the standard config dir
        # path in the defaults.
        #
        exname = self.expand(name)

        #
        # Macro could add an extension.
        #
        if exname.endswith('.cfg'):
            configname = exname
        else:
            configname = '%s.cfg' % (exname)
            name = '%s.cfg' % (name)

        if ':' in configname:
            cfgname = path.basename(configname)
        else:
            cfgname = common_end(configname, name)

        if not path.exists(configname):
            if ':' in configname:
                configdirs = path.dirname(configname).split(':')
            else:
                configdirs = self.define('_configdir').split(':')
            for cp in configdirs:
                configname = path.join(path.abspath(cp), cfgname)
                if path.exists(configname):
                    break
                configname = None
            if configname is None:
                raise error.general('no config file found: %s' % (cfgname))

        try:
            log.trace('config: %s: _open: %s' % (self.init_name, path.host(configname)))
            config = open(path.host(configname), 'r')
        except IOError as err:
            raise error.general('error opening config file: %s' % (path.host(configname)))
        self.configpath += [configname]

        self._includes += [configname]

        try:
            dir = None
            info = None
            data = []
            while True:
                r = self._parse(config, dir, info)
                if r[0] == 'control':
                    if r[1] == '%end':
                        break
                    log.warning("unexpected '%s'" % (r[1]))
                elif r[0] == 'directive':
                    if r[1] == '%include':
                        self.load(r[2][0])
                        continue
                    dir, info, data = self._process_directive(r, dir, info, data)
                elif r[0] == 'data':
                    dir, info, data = self._process_data(r, dir, info, data)
                else:
                    self._error("%d: invalid parse state: '%s" % (self.lc, r[0]))
            if dir is not None:
                self._directive_extend(dir, data)
        except:
            config.close()
            raise

        config.close()

        self.name = save_name
        self.lc = save_lc

        self.load_depth -= 1