def _probe_snmp(self):
        # Run the CUPS SNMP backend, pointing it at the host.
        try:
            debugprint("snmp: trying")
            p = subprocess.Popen(
                args=["/usr/lib/cups/backend/snmp", self.hostname],
                close_fds=True,
                stdin=subprocess.DEVNULL,
                stdout=subprocess.PIPE,
                stderr=subprocess.DEVNULL)
        except OSError as e:
            debugprint("snmp: no good")
            if e.errno == errno.ENOENT:
                return

            raise

        (stdout, stderr) = p.communicate()
        if p.returncode != 0:
            debugprint("snmp: no good (return code %d)" % p.returncode)
            return

        if self.quit:
            debugprint("snmp: no good")
            return

        for line in stdout.decode().split('\n'):
            words = wordsep(line)
            n = len(words)
            if n == 6:
                (device_class, uri, make_and_model, info, device_id,
                 device_location) = words
            elif n == 5:
                (device_class, uri, make_and_model, info, device_id) = words
            elif n == 4:
                (device_class, uri, make_and_model, info) = words
            else:
                continue

            device_dict = {
                'device-class': device_class,
                'device-make-and-model': make_and_model,
                'device-info': info
            }
            if n == 5:
                debugprint("snmp: Device ID found:\n%s" % device_id)
                device_dict['device-id'] = device_id
            if n == 6:
                device_dict['device-location'] = device_location

            device = cupshelpers.Device(uri, **device_dict)
            debugprint("Device found: %s" % uri)
            self.callback_fn(device)

            # Cache the make and model for use by other search methods
            # that are not able to determine it.
            self._cached_attributes['device-make-and-model'] = make_and_model
            self._cached_attributes['device_id'] = device_id

        debugprint("snmp: done")
 def _new_device(self, uri, info, location=None):
     device_dict = {'device-class': 'network', 'device-info': "%s" % info}
     if location:
         device_dict['device-location'] = location
     device_dict.update(self._cached_attributes)
     new_device = cupshelpers.Device(uri, **device_dict)
     debugprint("Device found: %s" % uri)
     self.callback_fn(new_device)
    def __init__(self, devices, reply_handler, error_handler):
        self.devices = devices
        self.reply_handler = reply_handler
        self.error_handler = error_handler
        debugprint("+%s" % self)

        try:
            g_killtimer.add_hold()
            need_resolving = {}
            self.deviceobjs = {}
            for device_uri, device_dict in self.devices.items():
                deviceobj = cupshelpers.Device(device_uri, **device_dict)
                self.deviceobjs[device_uri] = deviceobj
                if device_uri.startswith("dnssd://"):
                    need_resolving[device_uri] = deviceobj

            if len(need_resolving) > 0:
                resolver = dnssdresolve.DNSSDHostNamesResolver(need_resolving)
                resolver.resolve(reply_handler=self._group)
            else:
                self._group()
        except Exception as e:
            g_killtimer.remove_hold()
            self.error_handler(e)