Example #1
0
    def getData(self, mibname):
        debug.logger & debug.flagReader and debug.logger(
            '%slooking for MIB %s' % (self._recursive and 'recursively ' or '', mibname))
        for path in self.getSubdirs(self._path, self._recursive,
                                    self._ignoreErrors):
            for mibalias, mibfile in self.getMibVariants(mibname):
                f = os.path.join(decode(path), decode(mibfile))
                debug.logger & debug.flagReader and debug.logger('trying MIB %s' % f)
                if os.path.exists(f) and os.path.isfile(f):
                    try:
                        mtime = os.stat(f)[8]
                        debug.logger & debug.flagReader and debug.logger(
                            'source MIB %s mtime is %s, fetching data...' % (
                                f, time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(mtime))))
                        return MibInfo(path='file://%s' % f, file=mibfile, name=mibalias, mtime=mtime), decode(
                            open(f, mode='rb').read(self.maxMibSize))
                    except (OSError, IOError):
                        debug.logger & debug.flagReader and debug.logger(
                            'source file %s open failure: %s' % (f, sys.exc_info()[1]))
                        if not self._ignoreErrors:
                            raise error.PySmiError('file %s access error: %s' % (f, sys.exc_info()[1]))

                    raise error.PySmiReaderFileNotModifiedError('source MIB %s is older than needed' % f, reader=self)

        raise error.PySmiReaderFileNotFoundError('source MIB %s not found' % mibname, reader=self)
Example #2
0
    def getData(self, mibname):
        if self._ssl:
            conn = ftplib.FTP_TLS()
        else:
            conn = ftplib.FTP()

        try:
            conn.connect(self._host, self._port, self._timeout)
        except ftplib.all_errors:
            raise error.PySmiReaderFileNotFoundError(
                'failed to connect to FTP server %s:%s: %s' % (self._host, self._port, sys.exc_info()[1]), reader=self)

        try:
            conn.login(self._user, self._password)
        except ftplib.all_errors:
            conn.close()
            raise error.PySmiReaderFileNotFoundError('failed to log in to FTP server %s:%s as %s/%s: %s' % (
            self._host, self._port, self._user, self._password, sys.exc_info()[1]), reader=self)

        mibname = decode(mibname)

        debug.logger & debug.flagReader and debug.logger('looking for MIB %s' % mibname)

        for mibalias, mibfile in self.getMibVariants(mibname):
            location = self._locationTemplate.replace('@mib@', mibfile)
            mtime = time.time()
            debug.logger & debug.flagReader and debug.logger(
                'trying to fetch MIB %s from %s:%s' % (location, self._host, self._port))
            data = []
            try:
                try:
                    response = conn.sendcmd('MDTM %s' % location)
                except ftplib.all_errors:
                    debug.logger & debug.flagReader and debug.logger(
                        'server %s:%s does not support MDTM command, fetching file %s' % (
                        self._host, self._port, location))
                else:
                    debug.logger & debug.flagReader and debug.logger(
                        'server %s:%s MDTM response is %s' % (self._host, self._port, response))
                    if response[:3] == 213:
                        mtime = time.mktime(time.strptime(response[4:], "%Y%m%d%H%M%S"))
                debug.logger & debug.flagReader and debug.logger('fetching source MIB %s, mtime %s' % (
                location, time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(mtime))))
                conn.retrlines('RETR %s' % location, lambda x, y=data: y.append(x))
            except ftplib.all_errors:
                debug.logger & debug.flagReader and debug.logger(
                    'failed to fetch MIB %s from %s:%s: %s' % (location, self._host, self._port, sys.exc_info()[1]))
                continue

            data = decode('\n'.join(data))

            debug.logger & debug.flagReader and debug.logger('fetched %s bytes in %s' % (len(data), location))

            conn.close()
            return MibInfo(path='ftp://%s%s' % (self._host, location), file=mibfile, name=mibalias, mtime=mtime), data

        conn.close()

        raise error.PySmiReaderFileNotFoundError('source MIB %s not found' % mibname, reader=self)
Example #3
0
    def getData(self, mibname):
        headers = {'Accept': 'text/plain'}
        if sys.version_info[:2] < (2, 6):
            conn = httplib.HTTPConnection(self._host, self._port)
        else:
            conn = httplib.HTTPConnection(self._host,
                                          self._port,
                                          timeout=self._timeout)

        mibname = decode(mibname)

        debug.logger & debug.flagReader and debug.logger(
            'looking for MIB %s' % mibname)

        for mibalias, mibfile in self.getMibVariants(mibname):
            location = self._locationTemplate.replace('@mib@', mibfile)
            debug.logger & debug.flagReader and debug.logger(
                'trying to fetch MIB from %s://%s:%s%s' %
                (self._schema, self._host, self._port, location))
            try:
                conn.request('GET', location, '', headers)
                response = conn.getresponse()
            except Exception:
                debug.logger & debug.flagReader and debug.logger(
                    'failed to fetch MIB from %s://%s:%s%s: %s' %
                    (self._schema, self._host, self._port, location,
                     sys.exc_info()[1]))
                continue

            debug.logger & debug.flagReader and debug.logger(
                'HTTP response %s' % response.status)

            if response.status == 200:
                try:
                    mtime = time.mktime(
                        time.strptime(response.getheader('Last-Modified'),
                                      "%a, %d %b %Y %H:%M:%S %Z"))
                except Exception:
                    debug.logger & debug.flagReader and debug.logger(
                        'malformed HTTP headers: %s' % sys.exc_info()[1])
                    mtime = time.time()

                debug.logger & debug.flagReader and debug.logger(
                    'fetching source MIB %s, mtime %s' %
                    (location, response.getheader('Last-Modified')))

                return MibInfo(
                    path='%s://%s:%s%s' %
                    (self._schema, self._host, self._port, location),
                    file=mibfile,
                    name=mibalias,
                    mtime=mtime), decode(response.read(self.maxMibSize))

        raise error.PySmiReaderFileNotFoundError('source MIB %s not found' %
                                                 mibname,
                                                 reader=self)
Example #4
0
    def getData(self, mibname):
        headers = {'Accept': 'text/plain', 'User-Agent': self._user_agent}

        mibname = decode(mibname)

        debug.logger & debug.flagReader and debug.logger(
            'looking for MIB %s' % mibname)

        for mibalias, mibfile in self.getMibVariants(mibname):
            if self.MIB_MAGIC in self._url:
                url = self._url.replace(self.MIB_MAGIC, mibfile)
            else:
                url = self._url + mibfile

            debug.logger & debug.flagReader and debug.logger(
                'trying to fetch MIB from %s' % url)

            try:
                req = Request(url, headers=headers)
                response = urlopen(req)

            except Exception:
                debug.logger & debug.flagReader and debug.logger(
                    'failed to fetch MIB from %s: %s' %
                    (url, sys.exc_info()[1]))
                continue

            debug.logger & debug.flagReader and debug.logger(
                'HTTP response %s' % response.code)

            if response.code == 200:
                try:
                    mtime = time.mktime(
                        time.strptime(response.getheader('Last-Modified'),
                                      "%a, %d %b %Y %H:%M:%S %Z"))

                except Exception:
                    debug.logger & debug.flagReader and debug.logger(
                        'malformed HTTP headers: %s' % sys.exc_info()[1])
                    mtime = time.time()

                debug.logger & debug.flagReader and debug.logger(
                    'fetching source MIB %s, mtime %s' %
                    (url, response.getheader('Last-Modified')))

                return MibInfo(path=url,
                               file=mibfile,
                               name=mibalias,
                               mtime=mtime), decode(
                                   response.read(self.maxMibSize))

        raise error.PySmiReaderFileNotFoundError('source MIB %s not found' %
                                                 mibname,
                                                 reader=self)
Example #5
0
    def getData(self, mibname, **options):
        debug.logger & debug.flagReader and debug.logger(
            '%slooking for MIB %s' %
            (self._recursive and 'recursively ' or '', mibname))

        for path in self.getSubdirs(self._path, self._recursive,
                                    self._ignoreErrors):

            for mibalias, mibfile in self.getMibVariants(mibname, **options):
                f = os.path.join(decode(path), decode(mibfile))

                debug.logger & debug.flagReader and debug.logger(
                    'trying MIB %s' % f)

                if os.path.exists(f) and os.path.isfile(f):
                    try:
                        mtime = os.stat(f)[8]

                        debug.logger & debug.flagReader and debug.logger(
                            'source MIB %s mtime is %s, fetching data...' %
                            (f,
                             time.strftime("%a, %d %b %Y %H:%M:%S GMT",
                                           time.gmtime(mtime))))

                        fp = open(f, mode='rb')
                        mibData = fp.read(self.maxMibSize)
                        fp.close()

                        if len(mibData) == self.maxMibSize:
                            raise IOError('MIB %s too large' % f)

                        return MibInfo(path='file://%s' % f,
                                       file=mibfile,
                                       name=mibalias,
                                       mtime=mtime), decode(mibData)

                    except (OSError, IOError):
                        debug.logger & debug.flagReader and debug.logger(
                            'source file %s open failure: %s' %
                            (f, sys.exc_info()[1]))

                        if not self._ignoreErrors:
                            raise error.PySmiError('file %s access error: %s' %
                                                   (f, sys.exc_info()[1]))

                    raise error.PySmiReaderFileNotModifiedError(
                        'source MIB %s is older than needed' % f, reader=self)

        raise error.PySmiReaderFileNotFoundError('source MIB %s not found' %
                                                 mibname,
                                                 reader=self)
Example #6
0
    def __init__(self, path):
        """Creates an instance of *FileReader* class.

           Args:
               path: writable directory to store created files
        """
        self._path = decode(os.path.normpath(path))
Example #7
0
    def fileExists(self, mibname, mtime, rebuild=False):
        if rebuild:
            debug.logger & debug.flagSearcher and debug.logger('pretend %s is very old' % mibname)
            return

        mibname = decode(mibname)
        basename = os.path.join(self._path, mibname)

        for sfx in self.exts:
            f = basename + sfx
            if not os.path.exists(f) or not os.path.isfile(f):
                debug.logger & debug.flagSearcher and debug.logger('%s not present or not a file' % f)
                continue

            try:
                fileTime = os.stat(f)[8]

            except OSError:
                raise error.PySmiSearcherError('failure opening compiled file %s: %s' % (f, sys.exc_info()[1]),
                                               searcher=self)

            debug.logger & debug.flagSearcher and debug.logger(
                'found %s, mtime %s' % (f, time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(fileTime))))

            if fileTime >= mtime:
                raise error.PySmiFileNotModifiedError()

        raise error.PySmiFileNotFoundError('no compiled file %s found' % mibname, searcher=self)
Example #8
0
    def getData(self, mibname, **options):
        debug.logger & debug.flagReader and debug.logger('looking for MIB %s at %s' % (mibname, self._name))

        if self._pendingError:
            raise self._pendingError

        if not self._members:
            raise error.PySmiReaderFileNotFoundError('source MIB %s not found' % mibname, reader=self)

        for mibalias, mibfile in self.getMibVariants(mibname, **options):

            debug.logger & debug.flagReader and debug.logger('trying MIB %s' % mibfile)

            try:
                refs = self._members[mibfile]

            except KeyError:
                continue

            mibData, mtime = self._readZipFile(refs)

            if not mibData:
                continue

            debug.logger & debug.flagReader and debug.logger(
                'source MIB %s, mtime %s, read from %s/%s' % (mibfile, time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(mtime)), self._name, mibfile)
            )

            if len(mibData) == self.maxMibSize:
                raise IOError('MIB %s/%s too large' % (self._name, mibfile))

            return MibInfo(path='zip://%s/%s' % (self._name, mibfile),
                           file=mibfile, name=mibalias, mtime=mtime), decode(mibData)

        raise error.PySmiReaderFileNotFoundError('source MIB %s not found' % mibname, reader=self)
Example #9
0
    def __init__(self, host, port, locationTemplate, timeout=5, ssl=False):
        """Create an instance of *HttpReader* bound to specific URL.

           Note:
               The `http_proxy` and `https_proxy` environment variables are
               respected by the underlying `urllib` stdlib module.

           Args:
               host (str): domain name or IP address of web server
               port (int): TCP port web server is listening
               locationTemplate (str): location part of the URL optionally containing @mib@
                   magic placeholder to be replaced with MIB name. If @mib@ magic is not present,
                   MIB name is appended to `locationTemplate`

           Keyword Args:
               timeout (int): response timeout
               ssl (bool): access HTTPS web site
        """
        self._url = '%s://%s:%d%s' % (ssl and 'https' or 'http',
                                      host, port, decode(locationTemplate))

        socket.setdefaulttimeout(timeout)
        self._user_agent = 'pysmi-%s; python-%s.%s.%s; %s' % (
            pysmi_version, sys.version_info[0], sys.version_info[1],
            sys.version_info[2], sys.platform
        )
Example #10
0
    def fileExists(self, mibname, mtime, rebuild=False):
        if rebuild:
            debug.logger & debug.flagSearcher and debug.logger(
                'pretend %s is very old' % mibname)
            return
        mibname = decode(mibname)
        pyfile = os.path.join(self._path, mibname)
        for fmt in imp.PY_COMPILED, imp.PY_SOURCE:
            for pySfx, pyMode in self.suffixes[fmt]:
                f = pyfile + pySfx
                if not os.path.exists(f) or not os.path.isfile(f):
                    debug.logger & debug.flagSearcher and debug.logger(
                        '%s not present or not a file' % f)
                    continue
                if fmt == imp.PY_COMPILED:
                    try:
                        pyData = open(f, pyMode).read(8)
                    except IOError:
                        raise error.PySmiSearcherError(
                            'failure opening compiled file %s: %s' %
                            (f, sys.exc_info()[1]),
                            searcher=self)
                    if pyData[:4] == imp.get_magic():
                        pyData = pyData[4:]
                        pyTime = struct.unpack('<L', pyData[:4])[0]
                        debug.logger & debug.flagSearcher and debug.logger(
                            'found %s, mtime %s' %
                            (f,
                             time.strftime("%a, %d %b %Y %H:%M:%S GMT",
                                           time.gmtime(pyTime))))
                        if pyTime >= mtime:
                            raise error.PySmiFileNotModifiedError()
                        else:
                            raise error.PySmiFileNotFoundError(
                                'older file %s exists %s' % mibname,
                                searcher=self)
                    else:
                        debug.logger & debug.flagSearcher and debug.logger(
                            'bad magic in %s' % f)
                        continue
                else:
                    try:
                        pyTime = os.stat(f)[8]
                    except OSError:
                        raise error.PySmiSearcherError(
                            'failure opening compiled file %s: %s' %
                            (f, sys.exc_info()[1]),
                            searcher=self)

                    debug.logger & debug.flagSearcher and debug.logger(
                        'found %s, mtime %s' %
                        (f,
                         time.strftime("%a, %d %b %Y %H:%M:%S GMT",
                                       time.gmtime(pyTime))))
                    if pyTime >= mtime:
                        raise error.PySmiFileNotModifiedError()

        raise error.PySmiFileNotFoundError('no compiled file %s found' %
                                           mibname,
                                           searcher=self)
Example #11
0
    def getData(self, mibname, zipBlob=None):
        debug.logger & debug.flagReader and debug.logger('looking for MIB %s at %s' % (mibname, self._name))

        if self._pendingError:
            raise self._pendingError

        if not self._members:
            raise error.PySmiReaderFileNotFoundError('source MIB %s not found' % mibname, reader=self)

        for mibalias, mibfile in self.getMibVariants(mibname):

            debug.logger & debug.flagReader and debug.logger('trying MIB %s' % mibfile)

            try:
                refs = self._members[mibfile]

            except KeyError:
                continue

            mibData, mtime = self._readZipFile(refs)

            if not mibData:
                continue

            debug.logger & debug.flagReader and debug.logger(
                'source MIB %s, mtime %s, read from %s/%s' % (mibfile, time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(mtime)), self._name, mibfile)
            )

            if len(mibData) == self.maxMibSize:
                raise IOError('MIB %s/%s too large' % (self._name, mibfile))

            return MibInfo(path='zip://%s/%s' % (self._name, mibfile),
                           file=mibfile, name=mibalias, mtime=mtime), decode(mibData)

        raise error.PySmiReaderFileNotFoundError('source MIB %s not found' % mibname, reader=self)
Example #12
0
 def getSubdirs(self, path, recursive=True, ignoreErrors=True):
     if not recursive:
         return [path]
     dirs = [path]
     try:
         subdirs = os.listdir(path)
     except OSError:
         if ignoreErrors:
             return dirs
         else:
             raise error.PySmiError('directory %s access error: %s' % (path, sys.exc_info()[1]))
     for d in subdirs:
         d = os.path.join(decode(path), decode(d))
         if os.path.isdir(d):
             dirs.extend(self.getSubdirs(d, recursive))
     return dirs
Example #13
0
    def __init__(self, path):
        """Create an instance of *PyFileSearcher* bound to specific directory.

           Args:
             path (str): path to local directory
        """
        self._path = os.path.normpath(decode(path))
Example #14
0
    def __init__(self, path):
        """Creates an instance of *PyFileWriter* class.

           Args:
               path: writable directory to store Python modules
        """
        self._path = decode(os.path.normpath(path))
Example #15
0
    def __init__(self, path):
        """Create an instance of *PyFileSearcher* bound to specific directory.

           Args:
             path (str): path to local directory
        """
        self._path = os.path.normpath(decode(path))
Example #16
0
    def __init__(self, path):
        """Creates an instance of *PyFileWriter* class.

           Args:
               path: writable directory to store Python modules
        """
        self._path = decode(os.path.normpath(path))
Example #17
0
 def getSubdirs(self, path, recursive=True, ignoreErrors=True):
     if not recursive:
         return [path]
     dirs = [path]
     try:
         subdirs = os.listdir(path)
     except OSError:
         if ignoreErrors:
             return dirs
         else:
             raise error.PySmiError('directory %s access error: %s' % (path, sys.exc_info()[1]))
     for d in subdirs:
         d = os.path.join(decode(path), decode(d))
         if os.path.isdir(d):
             dirs.extend(self.getSubdirs(d, recursive))
     return dirs
Example #18
0
    def putData(self, mibname, data, comments=[], dryRun=False):
        if dryRun:
            debug.logger & debug.flagWriter and debug.logger('dry run mode')
            return
        if not os.path.exists(self._path):
            try:
                os.makedirs(self._path)
            except OSError:
                raise error.PySmiWriterError(
                    'failure creating destination directory %s: %s' %
                    (self._path, sys.exc_info()[1]),
                    writer=self)

        if comments:
            data = '#\n' + ''.join(['# %s\n' % x
                                    for x in comments]) + '#\n' + data

        pyfile = os.path.join(
            self._path, decode(mibname)) + self.suffixes[imp.PY_SOURCE][0][0]

        try:
            fd, tfile = tempfile.mkstemp(dir=self._path)
            os.write(fd, encode(data))
            os.close(fd)
            os.rename(tfile, pyfile)
        except (OSError, IOError, UnicodeEncodeError):
            exc = sys.exc_info()
            try:
                os.unlink(tfile)
            except OSError:
                pass
            raise error.PySmiWriterError('failure writing file %s: %s' %
                                         (pyfile, exc[1]),
                                         file=pyfile,
                                         writer=self)

        debug.logger & debug.flagWriter and debug.logger(
            'created file %s' % pyfile)

        if self.pyCompile:
            try:
                if sys.version_info[0:2] > (3, 1):
                    py_compile.compile(pyfile,
                                       doraise=True,
                                       optimize=self.pyOptimizationLevel)
                else:
                    py_compile.compile(pyfile, doraise=True)
            except (SyntaxError, py_compile.PyCompileError):
                pass  # XXX
            except:
                try:
                    os.unlink(pyfile)
                except Exception:
                    pass
                raise error.PySmiWriterError('failure compiling %s: %s' %
                                             (pyfile, sys.exc_info()[1]),
                                             file=mibname,
                                             writer=self)

        debug.logger & debug.flagWriter and debug.logger('%s stored' % mibname)
Example #19
0
    def __init__(self, host, port, locationTemplate, timeout=5, ssl=False):
        """Create an instance of *HttpReader* bound to specific URL.

           Note:
               The `http_proxy` and `https_proxy` environment variables are
               respected by the underlying `urllib` stdlib module.

           Args:
               host (str): domain name or IP address of web server
               port (int): TCP port web server is listening
               locationTemplate (str): location part of the URL optionally containing @mib@
                   magic placeholder to be replaced with MIB name. If @mib@ magic is not present,
                   MIB name is appended to `locationTemplate`

           Keyword Args:
               timeout (int): response timeout
               ssl (bool): access HTTPS web site
        """
        self._url = '%s://%s:%d%s' % (ssl and 'https' or 'http', host, port,
                                      decode(locationTemplate))

        socket.setdefaulttimeout(timeout)
        self._user_agent = 'pysmi-%s; python-%s.%s.%s; %s' % (
            pysmi_version, sys.version_info[0], sys.version_info[1],
            sys.version_info[2], sys.platform)
Example #20
0
    def fileWrite(self, fileName, data, comments=[], dryRun=False):
        fileName = fileName.replace('-','_')
        if dryRun:
            debug.logger & debug.flagWriter and debug.logger('dry run mode')
            return
        if not os.path.exists(self._path):
            try:
                os.makedirs(self._path)
            except OSError:
                raise error.PySmiWriterError('failure creating destination directory %s: %s' % (self._path, sys.exc_info()[1]), writer=self)
        if comments:
            data = '//\n' + ''.join(['//%s\n'% x for x in comments]) + '//\n' + data
        fileName = os.path.join(self._path,decode(fileName))

        try:
            fd, tfile = tempfile.mkstemp(dir = self._path)
            os.write(fd, encode(data))
            os.close(fd)
            if(os.path.isfile(fileName)):
                os.remove(fileName)
            os.rename(tfile, fileName)
        except (OSError, IOError, UnicodeEncodeError):
            exc = sys.exc_info()
            try:
                os.unlink(tfile)
            except OSError:
                pass
            raise error.PySmiWriterError('failure writing file %s: %s' % (fileName, exc[1]),file=fileName,write=self)
Example #21
0
    def __init__(self, path):
        """Creates an instance of *FileReader* class.

           Args:
               path: writable directory to store created files
        """
        self._path = decode(os.path.normpath(path))
Example #22
0
    def fileExists(self, mibname, mtime, rebuild=False):
        if rebuild:
            debug.logger & debug.flagSearcher and debug.logger('pretend %s is very old' % mibname)
            return

        mibname = decode(mibname)
        pyfile = os.path.join(self._path, mibname)

        for pySfx in BYTECODE_SUFFIXES:
            f = pyfile + pySfx

            if not os.path.exists(f) or not os.path.isfile(f):
                debug.logger & debug.flagSearcher and debug.logger('%s not present or not a file' % f)
                continue

            try:
                fp = open(f, 'rb')
                pyData = fp.read(8)
                fp.close()

            except IOError:
                raise error.PySmiSearcherError('failure opening compiled file %s: %s' % (f, sys.exc_info()[1]),
                                               searcher=self)
            if pyData[:4] == imp.get_magic():
                pyData = pyData[4:]
                pyTime = struct.unpack('<L', pyData[:4])[0]
                debug.logger & debug.flagSearcher and debug.logger(
                    'found %s, mtime %s' % (f, time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(pyTime))))
                if pyTime >= mtime:
                    raise error.PySmiFileNotModifiedError()

                else:
                    raise error.PySmiFileNotFoundError('older file %s exists' % mibname, searcher=self)

            else:
                debug.logger & debug.flagSearcher and debug.logger('bad magic in %s' % f)
                continue

        for pySfx in SOURCE_SUFFIXES:
            f = pyfile + pySfx

            if not os.path.exists(f) or not os.path.isfile(f):
                debug.logger & debug.flagSearcher and debug.logger('%s not present or not a file' % f)
                continue

            try:
                pyTime = os.stat(f)[8]

            except OSError:
                raise error.PySmiSearcherError('failure opening compiled file %s: %s' % (f, sys.exc_info()[1]),
                                               searcher=self)

            debug.logger & debug.flagSearcher and debug.logger(
                'found %s, mtime %s' % (f, time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(pyTime))))

            if pyTime >= mtime:
                raise error.PySmiFileNotModifiedError()

        raise error.PySmiFileNotFoundError('no compiled file %s found' % mibname, searcher=self)
Example #23
0
    def fileExists(self, mibname, mtime, rebuild=False):
        if rebuild:
            debug.logger & debug.flagSearcher and debug.logger('pretend %s is very old' % mibname)
            return
        mibname = decode(mibname)
        try:
            p = __import__(self._package, globals(), locals(), ['__init__'])
            if hasattr(p, '__loader__') and hasattr(p.__loader__, '_files'):
                self.__loader = p.__loader__
                self._package = self._package.replace('.', os.sep)
                debug.logger & debug.flagSearcher and debug.logger(
                    '%s is an importable egg at %s' % (self._package, os.path.split(p.__file__)[0]))
            elif hasattr(p, '__file__'):
                debug.logger & debug.flagSearcher and debug.logger(
                    '%s is not an egg, trying it as a package directory' % self._package)
                return PyFileSearcher(os.path.split(p.__file__)[0]).fileExists(mibname, mtime, rebuild=rebuild)
            else:
                raise error.PySmiFileNotFoundError('%s is neither importable nor a file' % self._package, searcher=self)

        except ImportError:
            raise error.PySmiFileNotFoundError('%s is not importable, trying as a path' % self._package, searcher=self)

        for fmt in imp.PY_COMPILED, imp.PY_SOURCE:
            for pySfx, pyMode in self.suffixes[fmt]:
                f = os.path.join(self._package, mibname.upper()) + pySfx
                if f not in self.__loader._files:
                    debug.logger & debug.flagSearcher and debug.logger('%s is not in %s' % (f, self._package))
                    continue
                if fmt == imp.PY_COMPILED:
                    pyData = self.__loader.get_data(f)
                    if pyData[:4] == imp.get_magic():
                        pyData = pyData[4:]
                        pyTime = struct.unpack('<L', pyData[:4])[0]
                        debug.logger & debug.flagSearcher and debug.logger(
                            'found %s, mtime %s' % (f, time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(pyTime))))
                        if pyTime >= mtime:
                            raise error.PySmiFileNotModifiedError()
                        else:
                            raise error.PySmiFileNotFoundError('older file %s exists' % mibname, searcher=self)
                    else:
                        debug.logger & debug.flagSearcher and debug.logger('bad magic in %s' % f)
                        continue
                else:
                    pyTime = self._parseDosTime(
                        self.__loader._files[f][6],
                        self.__loader._files[f][5]
                    )

                    debug.logger & debug.flagSearcher and debug.logger(
                        'found %s, mtime %s' % (f, time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(pyTime))))
                    if pyTime >= mtime:
                        raise error.PySmiFileNotModifiedError()
                    else:
                        raise error.PySmiFileNotFoundError('older file %s exists' % mibname, searcher=self)

        raise error.PySmiFileNotFoundError('no file %s found' % mibname, searcher=self)
Example #24
0
    def getData(self, mibname, **options):
        headers = {
            'Accept': 'text/plain',
            'User-Agent': self._user_agent
        }

        mibname = decode(mibname)

        debug.logger & debug.flagReader and debug.logger('looking for MIB %s' % mibname)

        for mibalias, mibfile in self.getMibVariants(mibname, **options):
            if self.MIB_MAGIC in self._url:
                url = self._url.replace(self.MIB_MAGIC, mibfile)
            else:
                url = self._url + mibfile

            debug.logger & debug.flagReader and debug.logger('trying to fetch MIB from %s' % url)

            try:
                req = Request(url, headers=headers)
                response = urlopen(req)

            except Exception:
                debug.logger & debug.flagReader and debug.logger('failed to fetch MIB from %s: %s' % (url, sys.exc_info()[1]))
                continue

            debug.logger & debug.flagReader and debug.logger('HTTP response %s' % response.code)

            if response.code == 200:
                try:
                    mtime = time.mktime(time.strptime(response.getheader('Last-Modified'), "%a, %d %b %Y %H:%M:%S %Z"))

                except Exception:
                    debug.logger & debug.flagReader and debug.logger('malformed HTTP headers: %s' % sys.exc_info()[1])
                    mtime = time.time()

                debug.logger & debug.flagReader and debug.logger(
                    'fetching source MIB %s, mtime %s' % (url, response.getheader('Last-Modified')))

                return MibInfo(path=url, file=mibfile, name=mibalias, mtime=mtime), decode(response.read(self.maxMibSize))

        raise error.PySmiReaderFileNotFoundError('source MIB %s not found' % mibname, reader=self)
Example #25
0
    def getData(self, mibname):
        headers = {
            'Accept': 'text/plain'
        }
        if sys.version_info[:2] < (2, 6):
            conn = httplib.HTTPConnection(self._host, self._port)
        else:
            conn = httplib.HTTPConnection(self._host, self._port, timeout=self._timeout)

        mibname = decode(mibname)

        debug.logger & debug.flagReader and debug.logger('looking for MIB %s' % mibname)

        for mibalias, mibfile in self.getMibVariants(mibname):
            location = self._locationTemplate.replace('@mib@', mibfile)
            debug.logger & debug.flagReader and debug.logger(
                'trying to fetch MIB from %s://%s:%s%s' % (self._schema, self._host, self._port, location))
            try:
                conn.request('GET', location, '', headers)
                response = conn.getresponse()
            except Exception:
                debug.logger & debug.flagReader and debug.logger('failed to fetch MIB from %s://%s:%s%s: %s' % (
                    self._schema, self._host, self._port, location, sys.exc_info()[1]))
                continue

            debug.logger & debug.flagReader and debug.logger('HTTP response %s' % response.status)

            if response.status == 200:
                try:
                    mtime = time.mktime(time.strptime(response.getheader('Last-Modified'), "%a, %d %b %Y %H:%M:%S %Z"))
                except Exception:
                    debug.logger & debug.flagReader and debug.logger('malformed HTTP headers: %s' % sys.exc_info()[1])
                    mtime = time.time()

                debug.logger & debug.flagReader and debug.logger(
                    'fetching source MIB %s, mtime %s' % (location, response.getheader('Last-Modified')))

                return MibInfo(path='%s://%s:%s%s' % (self._schema, self._host, self._port, location), file=mibfile,
                               name=mibalias, mtime=mtime), decode(response.read(self.maxMibSize))

        raise error.PySmiReaderFileNotFoundError('source MIB %s not found' % mibname, reader=self)
Example #26
0
    def putData(self, mibname, data, comments=(), dryRun=False):
        if dryRun:
            debug.logger & debug.flagWriter and debug.logger('dry run mode')
            return
        if not os.path.exists(self._path):
            try:
                os.makedirs(self._path)
            except OSError:
                raise error.PySmiWriterError(
                    'failure creating destination directory %s: %s' % (self._path, sys.exc_info()[1]), writer=self)

        if comments:
            data = '#\n' + ''.join(['# %s\n' % x for x in comments]) + '#\n' + data

        pyfile = os.path.join(self._path, decode(mibname)) + self.suffixes[imp.PY_SOURCE][0][0]

        tfile = None

        try:
            fd, tfile = tempfile.mkstemp(dir=self._path)
            os.write(fd, encode(data))
            os.close(fd)
            os.rename(tfile, pyfile)
        except (OSError, IOError, UnicodeEncodeError):
            exc = sys.exc_info()
            if tfile:
                try:
                    os.unlink(tfile)
                except OSError:
                    pass
            raise error.PySmiWriterError('failure writing file %s: %s' % (pyfile, exc[1]), file=pyfile, writer=self)

        debug.logger & debug.flagWriter and debug.logger('created file %s' % pyfile)

        if self.pyCompile:
            try:
                if sys.version_info[0:2] > (3, 1):
                    # noinspection PyArgumentList
                    py_compile.compile(pyfile, doraise=True, optimize=self.pyOptimizationLevel)
                else:
                    py_compile.compile(pyfile, doraise=True)
            except (SyntaxError, py_compile.PyCompileError):
                pass  # XXX
            except:
                try:
                    os.unlink(pyfile)
                except Exception:
                    pass
                raise error.PySmiWriterError('failure compiling %s: %s' % (pyfile, sys.exc_info()[1]), file=mibname,
                                             writer=self)

        debug.logger & debug.flagWriter and debug.logger('%s stored' % mibname)
Example #27
0
    def getData(self, mibname, dryRun=False):
        filename = os.path.join(self._path, decode(mibname)) + self.suffix

        f = None

        try:
            f = open(filename)
            data = f.read()
            f.close()
            return data

        except (OSError, IOError, UnicodeEncodeError):
            if f:
                f.close()
            return ''
Example #28
0
    def getData(self, mibname, dryRun=False):
        filename = os.path.join(self._path, decode(mibname)) + self.suffix

        f = None

        try:
            f = open(filename)
            data = f.read()
            f.close()
            return data

        except (OSError, IOError, UnicodeEncodeError):
            if f:
                f.close()
            return ''
Example #29
0
    def getData(self, mibname):
        filename = decode(mibname)

        f = None

        try:
            f = open(filename)
            data = f.read()
            f.close()
            return data

        except (OSError, IOError, UnicodeEncodeError):
            if f:
                f.close()
            return ''
Example #30
0
    def putData(self, mibname, data, comments=(), dryRun=False):
        if dryRun:
            debug.logger & debug.flagWriter and debug.logger('dry run mode')
            return

        if not os.path.exists(self._path):
            try:
                os.makedirs(self._path)

            except OSError:
                raise error.PySmiWriterError(
                    'failure creating destination directory %s: %s' %
                    (self._path, sys.exc_info()[1]),
                    writer=self)

        if comments:
            data = '#\n' + ''.join(['# %s\n' % x
                                    for x in comments]) + '#\n' + data

        filename = os.path.join(self._path, decode(mibname)) + self.suffix

        tfile = None

        try:
            fd, tfile = tempfile.mkstemp(dir=self._path)
            os.write(fd, encode(data))
            os.close(fd)
            os.rename(tfile, filename)

        except (OSError, IOError, UnicodeEncodeError):
            exc = sys.exc_info()
            if tfile:
                try:
                    os.unlink(tfile)

                except OSError:
                    pass

            raise error.PySmiWriterError('failure writing file %s: %s' %
                                         (filename, exc[1]),
                                         file=filename,
                                         writer=self)

        debug.logger & debug.flagWriter and debug.logger('%s stored in %s' %
                                                         (mibname, filename))
Example #31
0
    def __init__(self, host, port, locationTemplate, timeout=5, ssl=False):
        """Create an instance of *HttpReader* bound to specific URL.

           Args:
               host (str): domain name or IP address of web server
               port (int): TCP port web server is listening
               locationTemplate (str): location part of the URL containing @mib@ magic placeholder to be replaced with MIB name fetch.
           Keyword Args:
               timeout (int): response timeout
               ssl (bool): access HTTPS web site
        """
        self._schema = ssl and 'https' or 'http'
        self._host = host
        self._port = port
        self._locationTemplate = decode(locationTemplate)
        self._timeout = timeout
        if '@mib@' not in locationTemplate:
            raise error.PySmiError('@mib@ placeholder not specified in location at %s' % self)
Example #32
0
    def __init__(self, host, port, locationTemplate, timeout=5, ssl=False):
        """Create an instance of *HttpReader* bound to specific URL.

           Args:
               host (str): domain name or IP address of web server
               port (int): TCP port web server is listening
               locationTemplate (str): location part of the URL containing @mib@ magic placeholder to be replaced with MIB name fetch.
           Keyword Args:
               timeout (int): response timeout
               ssl (bool): access HTTPS web site
        """
        self._schema = ssl and 'https' or 'http'
        self._host = host
        self._port = port
        self._locationTemplate = decode(locationTemplate)
        self._timeout = timeout
        if '@mib@' not in locationTemplate:
            raise error.PySmiError('@mib@ placeholder not specified in location at %s' % self)
Example #33
0
    def __init__(self, host, port, locationTemplate, timeout=5, ssl=False):
        """Create an instance of *HttpReader* bound to specific URL.

           Args:
               host (str): domain name or IP address of web server
               port (int): TCP port web server is listening
               locationTemplate (str): location part of the URL optionally containing @mib@
                   magic placeholder to be replaced with MIB name. If @mib@ magic is not present,
                   MIB name is appended to `locationTemplate`

           Keyword Args:
               timeout (int): response timeout
               ssl (bool): access HTTPS web site
        """
        self._schema = ssl and 'https' or 'http'
        self._host = host
        self._port = port
        self._locationTemplate = decode(locationTemplate)
        self._timeout = timeout
        self._user_agent = 'pysmi-%s; python-%s.%s.%s; %s' % (
            pysmi_version, sys.version_info[0], sys.version_info[1],
            sys.version_info[2], sys.platform)
Example #34
0
    def putData(self, mibname, data, comments=(), dryRun=False):
        if dryRun:
            debug.logger & debug.flagWriter and debug.logger('dry run mode')
            return

        if not os.path.exists(self._path):
            try:
                os.makedirs(self._path)

            except OSError:
                raise error.PySmiWriterError(
                    'failure creating destination directory %s: %s' % (self._path, sys.exc_info()[1]), writer=self)

        if comments:
            data = '#\n' + ''.join(['# %s\n' % x for x in comments]) + '#\n' + data

        filename = os.path.join(self._path, decode(mibname)) + self.suffix

        tfile = None

        try:
            fd, tfile = tempfile.mkstemp(dir=self._path)
            os.write(fd, encode(data))
            os.close(fd)
            os.rename(tfile, filename)

        except (OSError, IOError, UnicodeEncodeError):
            exc = sys.exc_info()
            if tfile:
                try:
                    os.unlink(tfile)

                except OSError:
                    pass

            raise error.PySmiWriterError('failure writing file %s: %s' % (filename, exc[1]), file=filename, writer=self)

        debug.logger & debug.flagWriter and debug.logger('%s stored in %s' % (mibname, filename))
Example #35
0
    def fileExists(self, mibname, mtime, rebuild=False):
        if rebuild:
            debug.logger & debug.flagSearcher and debug.logger(
                'pretend %s is very old' % mibname)
            return

        mibname = decode(mibname)
        basename = os.path.join(self._path, mibname)

        for sfx in self.exts:
            f = basename + sfx
            if not os.path.exists(f) or not os.path.isfile(f):
                debug.logger & debug.flagSearcher and debug.logger(
                    '%s not present or not a file' % f)
                continue

            try:
                fileTime = os.stat(f)[8]

            except OSError:
                raise error.PySmiSearcherError(
                    'failure opening compiled file %s: %s' %
                    (f, sys.exc_info()[1]),
                    searcher=self)

            debug.logger & debug.flagSearcher and debug.logger(
                'found %s, mtime %s' %
                (f,
                 time.strftime("%a, %d %b %Y %H:%M:%S GMT",
                               time.gmtime(fileTime))))

            if fileTime >= mtime:
                raise error.PySmiFileNotModifiedError()

        raise error.PySmiFileNotFoundError('no compiled file %s found' %
                                           mibname,
                                           searcher=self)
Example #36
0
    def fileWrite(self, fileName, data, comments=[], dryRun=False):
        fileName = fileName.replace('-', '_')
        if dryRun:
            debug.logger & debug.flagWriter and debug.logger('dry run mode')
            return
        if not os.path.exists(self._path):
            try:
                os.makedirs(self._path)
            except OSError:
                raise error.PySmiWriterError(
                    'failure creating destination directory %s: %s' %
                    (self._path, sys.exc_info()[1]),
                    writer=self)
        if comments:
            data = '//\n' + ''.join(['//%s\n' % x
                                     for x in comments]) + '//\n' + data
        fileName = os.path.join(self._path, decode(fileName))

        try:
            fd, tfile = tempfile.mkstemp(dir=self._path)
            os.write(fd, encode(data))
            os.close(fd)
            if (os.path.isfile(fileName)):
                os.remove(fileName)
            os.rename(tfile, fileName)
            fd,
        except (OSError, IOError, UnicodeEncodeError):
            exc = sys.exc_info()
            try:
                os.unlink(tfile)
            except OSError:
                pass
            raise error.PySmiWriterError('failure writing file %s: %s' %
                                         (fileName, exc[1]),
                                         file=fileName,
                                         write=self)
Example #37
0
 def __init__(self, path):
     self._path = decode(os.path.normpath(path))
Example #38
0
    def fileExists(self, mibname, mtime, rebuild=False):
        if rebuild:
            debug.logger & debug.flagSearcher and debug.logger(
                'pretend %s is very old' % mibname)
            return

        mibname = decode(mibname)
        pyfile = os.path.join(self._path, mibname)

        for pySfx in BYTECODE_SUFFIXES:
            f = pyfile + pySfx

            if not os.path.exists(f) or not os.path.isfile(f):
                debug.logger & debug.flagSearcher and debug.logger(
                    '%s not present or not a file' % f)
                continue

            try:
                fp = open(f, 'rb')
                pyData = fp.read(8)
                fp.close()

            except IOError:
                raise error.PySmiSearcherError(
                    'failure opening compiled file %s: %s' %
                    (f, sys.exc_info()[1]),
                    searcher=self)
            if pyData[:4] == PY_MAGIC_NUMBER:
                pyData = pyData[4:]
                pyTime = struct.unpack('<L', pyData[:4])[0]
                debug.logger & debug.flagSearcher and debug.logger(
                    'found %s, mtime %s' %
                    (f,
                     time.strftime("%a, %d %b %Y %H:%M:%S GMT",
                                   time.gmtime(pyTime))))
                if pyTime >= mtime:
                    raise error.PySmiFileNotModifiedError()

                else:
                    raise error.PySmiFileNotFoundError('older file %s exists' %
                                                       mibname,
                                                       searcher=self)

            else:
                debug.logger & debug.flagSearcher and debug.logger(
                    'bad magic in %s' % f)
                continue

        for pySfx in SOURCE_SUFFIXES:
            f = pyfile + pySfx

            if not os.path.exists(f) or not os.path.isfile(f):
                debug.logger & debug.flagSearcher and debug.logger(
                    '%s not present or not a file' % f)
                continue

            try:
                pyTime = os.stat(f)[8]

            except OSError:
                raise error.PySmiSearcherError(
                    'failure opening compiled file %s: %s' %
                    (f, sys.exc_info()[1]),
                    searcher=self)

            debug.logger & debug.flagSearcher and debug.logger(
                'found %s, mtime %s' %
                (f,
                 time.strftime("%a, %d %b %Y %H:%M:%S GMT",
                               time.gmtime(pyTime))))

            if pyTime >= mtime:
                raise error.PySmiFileNotModifiedError()

        raise error.PySmiFileNotFoundError('no compiled file %s found' %
                                           mibname,
                                           searcher=self)
Example #39
0
 def __init__(self, path):
     self._path = decode(os.path.normpath(path))
Example #40
0
class PyFileWriter(AbstractWriter):
    """Stores transformed MIB modules as Python files at specified location.

       User is expected to pass *PyFileWriter* class instance to
       *MibCompiler* on instantiation. The rest is internal to *MibCompiler*.
    """
    pyCompile = True
    pyOptimizationLevel = -1

    suffixes = {}

    for sfx, mode, typ in imp.get_suffixes():
        if typ not in suffixes:
            suffixes[typ] = []

        suffixes[typ].append((decode(sfx), mode))

    def __init__(self, path):
        """Creates an instance of *PyFileWriter* class.

           Args:
               path: writable directory to store Python modules
        """
        self._path = decode(os.path.normpath(path))

    def __str__(self):
        return '%s{"%s"}' % (self.__class__.__name__, self._path)

    def putData(self, mibname, data, comments=(), dryRun=False):
        if dryRun:
            debug.logger & debug.flagWriter and debug.logger('dry run mode')
            return

        if not os.path.exists(self._path):
            try:
                os.makedirs(self._path)

            except OSError:
                raise error.PySmiWriterError(
                    'failure creating destination directory %s: %s' %
                    (self._path, sys.exc_info()[1]),
                    writer=self)

        if comments:
            data = '#\n' + ''.join(['# %s\n' % x
                                    for x in comments]) + '#\n' + data

        pyfile = os.path.join(
            self._path, decode(mibname)) + self.suffixes[imp.PY_SOURCE][0][0]

        tfile = None

        try:
            fd, tfile = tempfile.mkstemp(dir=self._path)
            os.write(fd, encode(data))
            os.close(fd)
            os.rename(tfile, pyfile)

        except (OSError, IOError, UnicodeEncodeError):
            exc = sys.exc_info()
            if tfile:
                try:
                    os.unlink(tfile)

                except OSError:
                    pass

            raise error.PySmiWriterError('failure writing file %s: %s' %
                                         (pyfile, exc[1]),
                                         file=pyfile,
                                         writer=self)

        debug.logger & debug.flagWriter and debug.logger(
            'created file %s' % pyfile)

        if self.pyCompile:
            try:
                if sys.version_info[0:2] > (3, 1):
                    # noinspection PyArgumentList
                    py_compile.compile(pyfile,
                                       doraise=True,
                                       optimize=self.pyOptimizationLevel)

                else:
                    py_compile.compile(pyfile, doraise=True)

            except (SyntaxError, py_compile.PyCompileError):
                pass  # XXX

            except:
                try:
                    os.unlink(pyfile)
                except Exception:
                    pass

                raise error.PySmiWriterError('failure compiling %s: %s' %
                                             (pyfile, sys.exc_info()[1]),
                                             file=mibname,
                                             writer=self)

        debug.logger & debug.flagWriter and debug.logger('%s stored' % mibname)

    def getData(self, filename):
        return ''
Example #41
0
    def fileExists(self, mibname, mtime, rebuild=False):
        if rebuild:
            debug.logger & debug.flagSearcher and debug.logger('pretend %s is very old' % mibname)
            return

        mibname = decode(mibname)

        try:
            p = __import__(self._package, globals(), locals(), ['__init__'])

            if hasattr(p, '__loader__') and hasattr(p.__loader__, '_files'):
                self.__loader = p.__loader__
                self._package = self._package.replace('.', os.sep)
                debug.logger & debug.flagSearcher and debug.logger(
                    '%s is an importable egg at %s' % (self._package, os.path.split(p.__file__)[0]))

            elif hasattr(p, '__file__'):
                debug.logger & debug.flagSearcher and debug.logger(
                    '%s is not an egg, trying it as a package directory' % self._package)
                return PyFileSearcher(os.path.split(p.__file__)[0]).fileExists(mibname, mtime, rebuild=rebuild)

            else:
                raise error.PySmiFileNotFoundError('%s is neither importable nor a file' % self._package, searcher=self)

        except ImportError:
            raise error.PySmiFileNotFoundError('%s is not importable, trying as a path' % self._package, searcher=self)

        for fmt in imp.PY_COMPILED, imp.PY_SOURCE:
            for pySfx, pyMode in self.suffixes[fmt]:
                f = os.path.join(self._package, mibname.upper()) + pySfx

                if f not in self.__loader._files:
                    debug.logger & debug.flagSearcher and debug.logger('%s is not in %s' % (f, self._package))
                    continue

                if fmt == imp.PY_COMPILED:
                    pyData = self.__loader.get_data(f)
                    if pyData[:4] == imp.get_magic():
                        pyData = pyData[4:]
                        pyTime = struct.unpack('<L', pyData[:4])[0]
                        debug.logger & debug.flagSearcher and debug.logger(
                            'found %s, mtime %s' % (f, time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(pyTime))))
                        if pyTime >= mtime:
                            raise error.PySmiFileNotModifiedError()
                        else:
                            raise error.PySmiFileNotFoundError('older file %s exists' % mibname, searcher=self)

                    else:
                        debug.logger & debug.flagSearcher and debug.logger('bad magic in %s' % f)
                        continue

                else:
                    pyTime = self._parseDosTime(
                        self.__loader._files[f][6],
                        self.__loader._files[f][5]
                    )

                    debug.logger & debug.flagSearcher and debug.logger(
                        'found %s, mtime %s' % (f, time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(pyTime))))
                    if pyTime >= mtime:
                        raise error.PySmiFileNotModifiedError()
                    else:
                        raise error.PySmiFileNotFoundError('older file %s exists' % mibname, searcher=self)

        raise error.PySmiFileNotFoundError('no file %s found' % mibname, searcher=self)
Example #42
0
    def getData(self, mibname):
        if self._ssl:
            conn = ftplib.FTP_TLS()
        else:
            conn = ftplib.FTP()

        try:
            conn.connect(self._host, self._port, self._timeout)

        except ftplib.all_errors:
            raise error.PySmiReaderFileNotFoundError(
                'failed to connect to FTP server %s:%s: %s' %
                (self._host, self._port, sys.exc_info()[1]),
                reader=self)

        try:
            conn.login(self._user, self._password)

        except ftplib.all_errors:
            conn.close()
            raise error.PySmiReaderFileNotFoundError(
                'failed to log in to FTP server %s:%s as %s/%s: %s' %
                (self._host, self._port, self._user, self._password,
                 sys.exc_info()[1]),
                reader=self)

        mibname = decode(mibname)

        debug.logger & debug.flagReader and debug.logger(
            'looking for MIB %s' % mibname)

        for mibalias, mibfile in self.getMibVariants(mibname):
            location = self._locationTemplate.replace('@mib@', mibfile)

            mtime = time.time()

            debug.logger & debug.flagReader and debug.logger(
                'trying to fetch MIB %s from %s:%s' %
                (location, self._host, self._port))

            data = []

            try:
                try:
                    response = conn.sendcmd('MDTM %s' % location)

                except ftplib.all_errors:
                    debug.logger & debug.flagReader and debug.logger(
                        'server %s:%s does not support MDTM command, fetching file %s'
                        % (self._host, self._port, location))

                else:
                    debug.logger & debug.flagReader and debug.logger(
                        'server %s:%s MDTM response is %s' %
                        (self._host, self._port, response))

                    if response[:3] == 213:
                        mtime = time.mktime(
                            time.strptime(response[4:], "%Y%m%d%H%M%S"))

                debug.logger & debug.flagReader and debug.logger(
                    'fetching source MIB %s, mtime %s' %
                    (location,
                     time.strftime("%a, %d %b %Y %H:%M:%S GMT",
                                   time.gmtime(mtime))))

                conn.retrlines('RETR %s' % location,
                               lambda x, y=data: y.append(x))

            except ftplib.all_errors:
                debug.logger & debug.flagReader and debug.logger(
                    'failed to fetch MIB %s from %s:%s: %s' %
                    (location, self._host, self._port, sys.exc_info()[1]))
                continue

            data = decode('\n'.join(data))

            debug.logger & debug.flagReader and debug.logger(
                'fetched %s bytes in %s' % (len(data), location))

            conn.close()

            return MibInfo(path='ftp://%s%s' % (self._host, location),
                           file=mibfile,
                           name=mibalias,
                           mtime=mtime), data

        conn.close()

        raise error.PySmiReaderFileNotFoundError('source MIB %s not found' %
                                                 mibname,
                                                 reader=self)