You are not logged in.

#1 2021-09-17 07:45:04

apoorv569
Member
Registered: 2020-05-26
Posts: 19

Looking for some help regarding libalpm.

I am trying to make a GUI frontend for pacman using libalpm, but I can't find much information or example code except the man pages in the terminal. They are not bad, but they don't provide much information or example code, or help with debugging errors, so its mostly DIY kind of thing. So I am having some issues with it, also have a couple of questions.

So far I am able to query the database, but not very well. I am using wxWIdgets for the GUI toolkit BTW.

Here is a snippet of code that I am having problem with,

void cMainFrame::OnClickButton(wxCommandEvent &event)
{
    alpm_errno_t err;
    m_Handle = alpm_initialize("/", "/var/lib/pacman", &err);

    std::cout << "ERROR: " << alpm_strerror(err) << std::endl;

    alpm_db_t* localdb = alpm_get_localdb(m_Handle);
    alpm_list_t* syncdb = alpm_get_syncdbs(m_Handle);

    alpm_db_t* core_repo = alpm_register_syncdb(m_Handle, "core", ALPM_DB_USAGE_ALL);
    alpm_db_t* community_repo = alpm_register_syncdb(m_Handle, "community", ALPM_DB_USAGE_ALL);
    alpm_db_t* extra_repo = alpm_register_syncdb(m_Handle, "extra", ALPM_DB_USAGE_ALL);
    alpm_db_t* multilib_repo = alpm_register_syncdb(m_Handle, "multilib", ALPM_DB_USAGE_ALL);

    alpm_list_t* needle;
    alpm_list_t** found = nullptr;

    wxString pkgname = m_TextCtrl->GetValue();

    alpm_pkg_t* pkg = alpm_db_get_pkg(localdb, pkgname);
    alpm_list_t* pkgcache = alpm_db_get_pkgcache(core_repo);

    size_t pkgcount = alpm_list_count(pkgcache);

    alpm_pkg_t* pkgdata;

    for (size_t i = 0; i < pkgcount; i++)
    {
        pkgdata = (alpm_pkg_t*)pkgcache->data;

        const char* base = alpm_pkg_get_base(pkgdata);
        const char* name = alpm_pkg_get_name(pkgdata);
        const char* filename = alpm_pkg_get_filename(pkgdata);
        const char* desc = alpm_pkg_get_desc(pkgdata);
        const char* author = alpm_pkg_get_packager(pkgdata);
        const char* version = alpm_pkg_get_version(pkgdata);
        const char* arch = alpm_pkg_get_arch(pkgdata);
        const char* url = alpm_pkg_get_url(pkgdata);
        int size = alpm_pkg_get_size(pkgdata) / (2 * 1000);
        int isize = alpm_pkg_get_isize(pkgdata) / (2 * 1000);

        m_ListBox->InsertItem(i, name, 0);
        // m_ListBox->SetItem(i, 1, desc, 0);
        // m_ListBox->SetItem(i, 2, author, 0);
        // m_ListBox->SetItem(i, 3, version, 0);
        // m_ListBox->SetItem(i, 4, arch, 0);
        // m_ListBox->SetItem(i, 5, url, 0);
        // m_ListBox->SetItem(i, 6, wxString::Format(wxT("%i Mb"), size), 0);
        // m_ListBox->SetItem(i, 7, wxString::Format(wxT("%i Mb"), isize), 0);

        pkgcache = pkgcache->next;
    }

    int ret;

    ret = alpm_db_search(core_repo, needle, found);

    if (ret < 0)
    {
        std::cout << "failed to search all databases " << alpm_strerror(alpm_errno(m_Handle)) << std::endl;
    }

    ret = alpm_db_update(m_Handle, pkgcache, 1);

    if (ret < 0)
    {
        std::cout << "failed to synchronize all databases " << alpm_strerror(alpm_errno(m_Handle)) << std::endl;
    }
}

This is all the code I have so far, rest is just designing the GUI and all.

I am able to get the package cache, and all the packages inside that repository. But I can't seem call alpm_db_search() and alpm_db_update(). They always throw error,

ERROR: unexpected error
failed to search all databases wrong or NULL argument passed
failed to synchronize all databases unexpected error

I'm not really sure what they expect as the arguments. If someone can help me it would be great. Or if there is a good source of documentation other then the man pages please point me to that source.

Offline

#2 2021-09-17 10:49:10

Raynman
Member
Registered: 2011-10-22
Posts: 1,312

Re: Looking for some help regarding libalpm.

Disclaimer: never used libalpm, just looking at the man page(s) now. And since you didn't provide a self-contained/compilable example, I didn't test.

alpm_db_search: you never initialize needle (or needles since it's a list). Similar issue with found, should be like:

alpm_list_t* found = nullptr;
// ...
ret = alpm_db_search(core_repo, needle, &found);

alpm_db_update: it expects a list of databases (the parameter 'dbs'; you have 'syncdb' for this, which should really be called 'syncdbs'), you pass it a list of packages (pkgcache). (A C++ wrapper for libalpm using the stronger type system would be useful here.)

It's not immediately clear to me if _get_syncdbs() automatically gets you the dbs available in /var/lib/pacman, but you can easily check whether the list is empty or not. If it contains the dbs already, you should probably use those and not register dbs yourself. If you do need to register the dbs yourself, calling _get_syncdbs() isn't very useful there.

Existing libalpm frontends should provide example code (more real world than toy examples, which can be either more useful or harder to get started with, I guess). Of course pacman itself, but I'm sure there are others.

Last edited by Raynman (2021-09-17 10:53:50)

Offline

#3 2021-09-17 12:27:19

Allan
Pacman
From: Brisbane, AU
Registered: 2007-06-09
Posts: 11,058
Website

Re: Looking for some help regarding libalpm.

Pacman is essentially the main documentation for libalpm.

Your call to alpm_get_syncdbs() does nothing as you have not registered and sync databases.  Normally you would parse a config file to get configured databases and add those to the handle.

Offline

#4 2021-09-17 12:36:26

apoorv569
Member
Registered: 2020-05-26
Posts: 19

Re: Looking for some help regarding libalpm.

Raynman wrote:

Disclaimer: never used libalpm, just looking at the man page(s) now. And since you didn't provide a self-contained/compilable example, I didn't test.

That is all the code related to alpm, this can be run as CLI application too, with slight modifications, I'm just showing the output in GUI rather than CLI. Rest of the code is just GUI. But I can share it here, is it possible to upload a compressed archive here? or should I share a link to something that you can download from?

Raynman wrote:

alpm_db_search: you never initialize needle (or needles since it's a list). Similar issue with found, should be like:

alpm_list_t* found = nullptr;
// ...
ret = alpm_db_search(core_repo, needle, &found);

alpm_db_update: it expects a list of databases (the parameter 'dbs'; you have 'syncdb' for this, which should really be called 'syncdbs'), you pass it a list of packages (pkgcache). (A C++ wrapper for libalpm using the stronger type system would be useful here.)

Ah! I forgot to initialize needles. It works now. I also changed the code a little bit,

    alpm_list_t* syncdbs = alpm_get_syncdbs(m_Handle);

    alpm_list_t* needle = nullptr;
    alpm_list_t* found = nullptr;

    int ret;

    ret = alpm_db_search(core_repo, needle, &found);

    switch (ret)
    {
        case 0:
            std::cout << "successfully searched all databases " << alpm_strerror(alpm_errno(m_Handle)) << std::endl;
            break;
        case -1:
            std::cout << "failed to search all databases " << alpm_strerror(alpm_errno(m_Handle)) << std::endl;
            break;
        default:
            break;
    }

    ret = alpm_db_update(m_Handle, syncdbs, 1);

    switch (ret)
    {
        case 0:
            std::cout << "successfully synchronized all databases " << alpm_strerror(alpm_errno(m_Handle)) << std::endl;
            break;
        case -1:
            std::cout << "failed to synchronize all databases " << alpm_strerror(alpm_errno(m_Handle)) << std::endl;
            break;
        case 1:
            std::cout << "all databases are up to date " << alpm_strerror(alpm_errno(m_Handle)) << std::endl;
            break;
        default:
            std::cout << "unknown error " << alpm_strerror(alpm_errno(m_Handle)) << std::endl;
            break;
    }

The alpm_db_update() doesn't still though, now I am getting a different error.

ERROR: unexpected error
successfully searched all databases unexpected error
failed to synchronize all databases unexpected error
Successfully released the handle.
Raynman wrote:

It's not immediately clear to me if _get_syncdbs() automatically gets you the dbs available in /var/lib/pacman, but you can easily check whether the list is empty or not. If it contains the dbs already, you should probably use those and not register dbs yourself. If you do need to register the dbs yourself, calling _get_syncdbs() isn't very useful there.

I see.

Raynman wrote:

Existing libalpm frontends should provide example code (more real world than toy examples, which can be either more useful or harder to get started with, I guess). Of course pacman itself, but I'm sure there are others.

Yea, I did take a look at pamac and octopi, pamac uses vala, and I can't find anything similar to what is in the man pages, also I don't know anything about vala, as far octopi goes, it is also kind of using its own wrapper and all stuff, and they use qt stuff which I am not very familiar with. Which they certainly can help, but I have no understanding of those languages..

Offline

#5 2021-09-18 08:37:35

apoorv569
Member
Registered: 2020-05-26
Posts: 19

Re: Looking for some help regarding libalpm.

Allan wrote:

Pacman is essentially the main documentation for libalpm.

Your call to alpm_get_syncdbs() does nothing as you have not registered and sync databases.  Normally you would parse a config file to get configured databases and add those to the handle.

Is there a function to set the pacman configuration file for the handle, or do I parse the file myself?

Offline

#6 2021-09-18 12:49:15

Allan
Pacman
From: Brisbane, AU
Registered: 2007-06-09
Posts: 11,058
Website

Re: Looking for some help regarding libalpm.

apoorv569 wrote:

Is there a function to set the pacman configuration file for the handle, or do I parse the file myself?

No - the pacman configuration file is for pacman.  libalpm does not know how to parse it.

Offline

#7 2021-09-20 13:53:34

apoorv569
Member
Registered: 2020-05-26
Posts: 19

Re: Looking for some help regarding libalpm.

Does anybody knows how does these other GUI front-ends for pacman fetches those screenshots and icon for the application and all that stuff? Do all package archives have that kind of stuff inside them?

Offline

#8 2021-09-20 14:35:03

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 25,723
Website

Re: Looking for some help regarding libalpm.

apoorv569 wrote:

Does anybody knows how does these other GUI front-ends for pacman ...

Which "other GUI front-ends" are you talking about?  If they're open-source, just go look at what they do.

apoorv569 wrote:

... screenshots and icon for the application and all that stuff? Do all package archives have that kind of stuff inside them?

No, the databases contain absolutely none of this and the package archives don't really either (but this wouldn't matter as you're not downloading all the package archives to display this info).  Package archives may contain icons - but that depends on the package ... and they'd not be icons for the package itself, but just what is used by any packaged programs.  Frankly you should know a bit more about what the databases and package archives are if you're writting a libalpm front end.

There's a chance that those "other GUI front ends" that you are referring to use packagekit not libalpm (or perhaps both ... but the former may be relevant to the question if icons / screenshots, the latter definitely isn't).

Last edited by Trilby (2021-09-20 14:36:43)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

Board footer

Powered by FluxBB