kubada
kubada

Reputation: 99

Using gio.lookup_by_address

Most of the code is borrowed, JS is not my way, but an extension needs to be created.

Can you tell me how to use g_resolver_lookup_by_name() to return IP within the given code?

g-resolver-lookup-by-name

const Main = imports.ui.main;
const St = imports.gi.St;
const GObject = imports.gi.GObject;
const Gio = imports.gi.Gio;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Me = imports.misc.extensionUtils.getCurrentExtension();

let myPopup;

const MyPopup = GObject.registerClass(
class MyPopup extends PanelMenu.Button {

  _init () {
    super._init(0);
 ...
    this.menu.addMenuItem(
      new PopupMenu.PopupMenuItem(
        "Some : ", // IP is required to be returned
        {reactive : false},
      )
    );    
  }
});
...

Gio.Resolver.lookup_by_name('google.com') - TypeError: Gio.Resolver.lookup_by_name is not a function

Upvotes: 0

Views: 144

Answers (2)

maweil
maweil

Reputation: 91

Just to add to the above answer: You do not actually need to implement a promise wrapper anymore. GJS has a builtin function to make the async methods return a promise.

Inside your extention, you can determine the addresses that match a hostname like this:

  1. Make the lookup_by_name_async method return a Promise
Gio._promisify(Gio.Resolver.prototype, 'lookup_by_name_async', 'lookup_by_name_finish');
  1. Initialize a resolver in your extention (probably somewhere during the enable() function).
const resolver = Gio.Resolver.get_default();
  1. Define an async function to lookup the addresses matching the hostname and return them as an array of strings
async function lookupHostName(resolver, hostname, cancellable=null){
    let inetAddressList = await resolver.lookup_by_name_async(hostname, null);
    let addressesAsStrings = inetAddressList.map(address => address.to_string());
    return addressesAsStrings;
}
  1. Call your function where you need it and work with the addresses
lookupHostName(resolver, "localhost").then(ipAddresses => {
        log(JSON.stringify(ipAddresses));
    });

In your log you should then see something like the following:

["::1","127.0.0.1"]

Upvotes: 1

andy.holmes
andy.holmes

Reputation: 3696

You're trying to call a method as though it is static, but you first need to get the default resolver:

const Gio = imports.gi.Gio;

// The default resolver
const resolver = Gio.Resolver.get_default();

Looking up a name will certainly do blocking I/O so using the async variant will be necessary in a Shell extension. A promise wrapper is probably best:

function lookupName(host, cancellable = null) {
    return new Promise((resolve, reject) => {
        resolver.lookup_by_name_async(host, cancellable, (obj, res) => {
            try {
                resolve(resolver.lookup_by_name_finish(res));
            } catch (e) {
                reject(e);
            }
        });
    });
}

Of course, as the documentation says this will return a list of Gio.InetAddress objects, which you will have to call to_string() on to get a readable address.

Upvotes: 1

Related Questions