openwrt / rpcd

[MIRROR] OpenWrt ubus RPC daemon
https://git.openwrt.org/?p=project/rpcd.git;
7 stars 5 forks source link

rpc-sys packagelist lists 'not-installed' packages #6

Open efahl opened 1 month ago

efahl commented 1 month ago

@jck112 @dangowrt

Running x86/64 SNAPSHOT r26829.

Expecting to get libustream-mbedtls only, but get the openssl version:

$ ubus call rpc-sys packagelist '{"all":false}' | grep libustream
                "libustream-openssl": "2024.04.19~524a76e5-r1",

$ ubus call rpc-sys packagelist '{"all":true}' | grep libustream
                "libustream-openssl": "2024.04.19~524a76e5-r1",
                "libustream-mbedtls": "2024.04.19~524a76e5-r1",

Looking in the package status we see both packages, but openssl version is not-installed and mbedtls version is installed. (I have no idea how this came to be in this state, I install/remove packages on this test machine constantly.)

$ grep 'Package: libustream' /usr/lib/opkg/status -A7
Package: libustream-openssl20201210
ABIVersion: 20201210
Version: 2024.04.19~524a76e5-r1
Depends: libc, libubox20240329, libopenssl3
Provides: libustream-openssl
Status: install user not-installed    <<<<<<<<<<<<<<<<<<<<<<<<<<< here
Architecture: x86_64

--
Package: libustream-mbedtls20201210
ABIVersion: 20201210
Version: 2024.04.19~524a76e5-r1
Depends: libc, libubox20240329, libmbedtls21
Provides: libustream-mbedtls
Conflicts: libustream-openssl, libustream-wolfssl
Status: install ok installed    <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< here
Architecture: x86_64
Installed-Time: 1719864281
Auto-Installed: yes

Seems like something is not right around https://github.com/openwrt/rpcd/blob/master/sys.c#L241. installed seems like it should be false for the ssl package...

The opkg status file is well-formed; if I manually edit out the whole not-installed package entry, then everything works as expected.

efahl commented 1 month ago

Aha, sscanf doesn't match on the tail.

#include <stdio.h>

void check(char *line)
{
    char tmp[128];
    int result = sscanf(line, "Status: install %63s installed", tmp);
    printf("%d >%s< %s\n", result, tmp, line);
}

int main()
{
    check("Hello");
    check("Status: install ok installed\n");
    check("Status: install ok installed");
    check("Status: install user not-installed\n");
    check("Status: install user not-installed");
    check("Status: install any old junk");
}

gives

0 >< Hello
1 >ok< Status: install ok installed

1 >ok< Status: install ok installed
1 >user< Status: install user not-installed

1 >user< Status: install user not-installed
1 >any< Status: install any old junk
jck112 commented 1 month ago

Good catch on the sscanf behavior.

The wanted state is install because an install was requested for libustream-openssl20201210, but it has the current state not-installed because of the conflict with libustream-mbedtls20201210.

We can change the sscanf line to parse the current state into a variable then compare that to "installed".

efahl commented 1 month ago

I didn't read through opkg source, which is probably the "specification", but digging through a bunch of status files makes me think that a simple one-liner would work.

    installed = strstr(line, " installed") != NULL;  // Note: leading blank is significant.