API.md 29 KB

System Packaging Library API

Include syspkg.h, and link with -lsyspkg.

The functions are clearly named and have straightforward arguments. They return an integer error code which is defined the same as errno in libc. Complex structures and variable length arrays are returned in the context's fields.

[[TOC]]

Context

Create Package Manager Instance

syspkg_ctx_t *syspkg_new(syspkg_progressbar_t progressbar, syspkg_conf_t conf);

Creates a new package manager instance. Progressbar callback can be NULL. If none of your package meta info files have neither "eula" nor "postinst.env" fields, then conf callback can be safely NULL too. For callback prototypes, see below.


Free Package Manager Instance

int syspkg_free(syspkg_ctx_t *ctx);

Frees a package manager instance.


Callbacks

typedef void (*syspkg_progressbar_t)(int step, int numstep, int64_t curr, int64_t total, int msg);

An optional progress bar callback. If numstep is greater than zero, then you should display the text "Step step of numstep" too. If curr is smaller than total, you should display a percentage and/or a progressbar box. When curr equals to total and they are non-zero, you should display "Done" or "OK". Finally when total is negative, you should indicate an error. For the msg parameter, take a look at the SYSPKG_MSG_* defines, and you should display a corresponding textual message translated to the user's language.

Define Description
SYSPKG_MSG_GENKEYS Generating keys
SYSPKG_MSG_GENCERT Generating certificate
SYSPKG_MSG_GENPAYLOAD Generating payloads
SYSPKG_MSG_CHKPAYLOAD Checking payloads integrity
SYSPKG_MSG_DLDPAYLOAD Downloading payloads
SYSPKG_MSG_GETREPO Downloading package list
SYSPKG_MSG_GETMETA Updating package info
SYSPKG_MSG_CLNMETA Cleaning up package info
SYSPKG_MSG_GENHTML Generating html catalog
SYSPKG_MSG_DELPKG Removing packages
SYSPKG_MSG_UNPPKG Unpacking packages
SYSPKG_MSG_CFGPKG Configuring packages

If you do not wish to display progress feedback for the user, this callback can be safely NULL.


typedef int (*syspkg_conf_t)(char *id, char *name, char *terms, int len, syspkg_input_t *input);

Accept terms of use and package configuration form callback. If terms is not NULL, should display it (might contain newline \n characters) for package name (translated, the untraslated package unix name is in id). It is very important that displaying the terms must contain a clear question "Accept terms of use?" and clear "Yes" and "No" answer options (don't ask, this is a lawyer's thing). If the users answers "No", the function must return 0. Otherwise if user accepted it must return 1, but first if input is not NULL, it should get user input for the form and return 1. There are len elements in the input array, each with an input[].name label and input[].desc popup description (both translated), and an input[].value string pointer that the callback must fill in. Note that strings and decimal numbers must be passed back in malloced buffers. For checkbox and selectbox, value is a pointer to one of their options. The type of the field depends on input[].type, which also defines the further input[].spec type specification fields.

Type Description
SYSPKG_FORM_STR string, input[].spec.str contains the default string value
SYSPKG_FORM_NUM decimal number, input[].spec.num.def is the default, num.min and num.max the limits
SYSPKG_FORM_CHK checkbox, input[].spec.chk.enabled and chk.disabled are the string values
SYSPKG_FORM_SEL select box, input[].spec.sel.opts[] are the option strings, sel.len the number of options

Certificates

In all the certificate related functions, EFAULT means cryptographic error: either the underlying library reported an error, or the public key does not match the private key, or the certificate's pubkey does not match your private key.

Generate Certificate

int syspkg_cert(syspkg_ctx_t *ctx, char *name, char *countrycode, int isrepo);

Generates key pair and certificate. It is going to be a maintainer certificate if isrepo is zero, and a repository CA certificate otherwise. If isrepo is 0 and countrycode is NULL and name is a filename, then it tries to import a signed maintainer certificate.

Return code Description
0 (SUCCESS) zero terminated pem certificate string in ctx->cert
EINVAL bad input parameters
ENOMEM memory allocation error
EPERM permission denied on writing files
EFAULT cryptographic library related fault

Sign Certificates

int syspkg_sign(syspkg_ctx_t *ctx, char *crtfile);

Signs a maintainer certificate with your repository certificate.

Return code Description
0 (SUCCESS) zero terminated pem certificate string in ctx->cert
EINVAL bad input parameters
EBADF the given cert is not a valid maintainer cert
ENOMEM memory allocation error
EFAULT cryptographic library related fault

EINVAL could also mean that you don't have a repository certificate.


Revoke Certificates

int syspkg_revoke(syspkg_ctx_t *ctx, char *crtfile);

Revoke trust from a signed maintainer certificate.

Return code Description
0 (SUCCESS) zero terminated pem certificate string in ctx->cert
EINVAL bad input parameters
EBADF the given cert is not valid or not signed by you
ENOMEM memory allocation error
EFAULT cryptographic library related fault

EINVAL could also mean that you don't have a repository certificate.


Add Certificate to Trusted DB

int syspkg_trust(char *crtfile);

Add a certificate to the trusted list. The input in crtfile can be in pem format, a signed package metajson file or a https URL to a pem certificate.

Return code Description
0 (SUCCESS) certificate added to trusted database
EINVAL bad input parameters
EACCES you must be admin to trust a certificate
ENOMEM memory allocation error
EPERM permission denied on writing files

Remove Certificate from Trusted DB

int syspkg_untrust(char *cn);

Remove the certificate with the given canonical name from the trusted list. The high level API for removing trusted certificates is syspkg_remove().

Return code Description
0 (SUCCESS) everything went well
EINVAL bad input parameters
EACCES you must be admin to remove a certificate
ENOENT specified certificate not found
ENOMEM memory allocation error
EPERM permission denied on writing files

Package Metainfo and Payload

Build Metainfo and Payloads

int syspkg_build(syspkg_ctx_t *ctx, char *jsonfile, int numpl, char **plspec);

Generates payloads from playload specifications, updates and signes the package metainfo file. Payload specifications are plain strings, each look like (arch)=(dir|zipfile|url). If instead of a jsonfile a package URL list is given, then that's signed too.

Return code Description
0 (SUCCESS) everything went well
ENOENT unable to load json file
EBADF unable to parse json ((fieldindex << 16) + EBADF)
EINVAL bad input parameter ((payloadindex << 16) + EINVAL)
EACCES unable to download ((payloadindex << 16) + EACCES)
ENOMEM memory allocation error
EPERM permission denied on writing files
EFAULT unable to sign json
EIO unable to generate payloads

Fieldindex: missing or bad field 0 = id, 1 = description, 2 = version, 3 = url, 4 = category, 5 = payloads, 6 = signature.


Validating Metainfo and Payloads

int syspkg_check(syspkg_ctx_t *ctx, char *url);

Checks the integrity and validity of a metajson or payload.

Return code Description
0 (SUCCESS) everything went well
ENOENT unable to load file
EACCES unrecognized file format
EINVAL bad file format
EBADF unable to parse json ((fieldindex << 16) + EBADF)
ENOMEM memory allocation error

Fieldindex is the same as with build. The ctx->cert string contains detailed messages.

Package Management

Update Package List

int syspkg_update(syspkg_ctx_t *ctx);

Update the local packages database.

Return code Description
0 (SUCCESS) everything went well
EINVAL bad input parameters
EEXIST another instance is locked the package database
EACCES you must be admin to update the package database
ENOMEM memory allocation error

If SUCCESS returned, then ctx->numpackages contains the number of all available packages, and the number of currently installed packages is in ctx->numinst.


Remove Certificates, Repositories or Select Packages for Removal

int syspkg_remove(syspkg_ctx_t *ctx, char **name, int nodeps);

Removes a package, a certificate or a repository. The argument can be a list of package id, an url to a metajson, a repository url, a repository canonical name, an url to a trusted certificate, or a certificate canonical name. If a metajason url is given, then both the package and its signer certificate will be removed.

As for packages, they are not actually removed, just marked for removal. You'll need to call syspkg_commit() afterwards if ctx->removes is not empty, to actually remove the package(s). The others don't need commit.

Return code Description
0 (SUCCESS) everything went well
EINVAL bad input parameters
EACCES you must be admin to remove
EEXIST another instance is already running
ENOENT package/metajson/certificate/repo not found
EBADF package found, but not installed
ENOMEM memory allocation error

Select Packages for (Re)install

int syspkg_install(syspkg_ctx_t *ctx, char **name, int nodeps);

Marks package(s) to install or upgrade and collects the dependencies. Name can be a package id or an url to a metajson file, and points to a NULL terminated list.

To actually install or upgrade the package(s), you'll have to call syspkg_commit() afterwards.

Return code Description
0 (SUCCESS) everything went well
EINVAL bad input parameters
EACCES you must be admin to install packages
EEXIST another instance is already running
ENOENT package not found, in conflict or missing deps
ENOMEM memory allocation error

Reconfigure Packages

int syspkg_reconf(syspkg_ctx_t *ctx, char **name);

Reconfigure package(s) by executing the configuration form hook and postinstallation commands again.

Return code Description
0 (SUCCESS) everything went well
EINVAL bad input parameters
EACCES you must be admin to reconfigure packages
EEXIST another instance is already running
ENOENT package not found, in conflict or missing deps
ENOMEM memory allocation error

Select Packages with Newer Versions Available

int syspkg_upgrade(syspkg_ctx_t *ctx);

Mark all packages for reinstall which have newer versions available.

To actually upgrade the package(s), you'll have to call syspkg_commit() afterwards.

Return code Description
0 (SUCCESS) everything went well
EINVAL bad input parameters
EACCES you must be admin to install packages
EEXIST another instance is already running
ENOMEM memory allocation error

Perform Operation on Selected Packages

int syspkg_commit(syspkg_ctx_t *ctx);

Execute the operations on previously marked packages, selected by syspkg_install(), syspkg_remove(), or syspkg_upgrade().

Return code Description
0 (SUCCESS) everything went well
EINVAL bad input parameters
EACCES you must be admin to install or remove packages
EEXIST another instance is already running
ENOMEM memory allocation error
ENOSPC not enough space on device
ENOENT one of the payloads was not found
EBADF one of the payloads had bad format or checksum error
EPERM one of the payloads couldn't be extracted / removed

With package errors, the faulting package in ctx->packages[i]->err has a negative error code:

Error code Description
-1 download error
-2 file format or checksum error
-3 permission denied

Search For Packages in Name and Description

int syspkg_search(syspkg_ctx_t *ctx, int installed, char *search, char *depends, int *ids);

Returns a list of packages that match certain criteria. Either their package id, name or description contains the string in search, or they depend on depends or their numerical id listed in the ids array (terminated with -1U). If more filters given, then they're matched with a logical AND relation.

Return code Description
0 (SUCCESS) list of packages in ctx->packages
EINVAL bad input parameters
ENOENT no package found
ENOMEM memory allocation error
ctx->packages Description
id package id (package unix name)
name package name in the current locale
desc package description in the current locale
category package's category, not translated, see VALIDCATS
license license identifier ("MIT", "BSD", "GPL", etc.)
url download url
homepage software's webpage url
bugtracker issues page url
depends list of mandatory dependencies
suggests list of optional dependencies
conflicts list of blocking packages
maintainer developer's or package maintainer's canonical name
release available version (string)
irelease installed version (or NULL)
version available canonical, numerical version
iversion installed canonical, numerical version (or 0)
afirst first screenshot's attachment id (or -1)
alast last screenshot's attachment id (or -1)

Search For Files in Packages

int syspkg_which(syspkg_ctx_t *ctx, char *search);

Returns a list of packages which provide files with filenames containing search.

Return code Description
0 (SUCCESS) list of packages in ctx->packages
EINVAL bad input parameters
ENOENT no package found
ENOMEM memory allocation error

Returns in the same format as syspkg_search().


Search For Dependent Packages

Use syspkg_search with the depends parameter.


Return Decoded Package Logo / Screenshot

unsigned int *syspkg_loadattachment(unsigned int aidx, int size);

Returns a package attachment (logo or screenshot). The attachment index is returned in the ctx->packages elements' afirst and alast fields, all indeces in between (inclusive) belong to that package. If size is 0, then the image is returned in its original size, otherwise it is scaled and resampled to fit into size x size pixels keeping its aspect ratio (max 255 x 255). With aidx being -1, returns the no attachment icon. The returned array's first element is the image width, second is the height, and the rest are ARGB pixels, width times height elements. Blue component is in the least significant byte, alpha channel is in the most. If size is negative, then ABGR pixels will be returned (red component in the least significant byte). It is the caller's responsibility to free the returned array.

Repository Handling

Add a Repository

int syspkg_addrepo(syspkg_ctx_t *ctx, char *url);

Downloads and checks validity of a package list, and if passes, adds the url to the repository list.

Return code Description
0 (SUCCESS) everything went well
EINVAL bad input parameters
EEXIST the url is already in the list
EACCES you must be admin to add a repository url
ENOENT unable to (down)load repository list or certificate
ENOMEM memory allocation error
EPERM unable to save configuration file

Delete a Repository

int syspkg_delrepo(syspkg_ctx_t *ctx, char *name);

Removes a repository from list. The parameter can be an url or a canonical name. The high level API for removing repositories is syspkg_remove.

Return code Description
0 (SUCCESS) everything went well
EINVAL bad input parameters
EACCES you must be admin to add a repository url
ENOENT specified repository not found
ENOMEM memory allocation error
EPERM unable to save configuration file

Return List of Configured Repositories

int syspkg_listrepo(syspkg_ctx_t *ctx);

Returns the list of configured repositories. It also validates the package lists. The returned struct has several fields, url being NULL terminates the list. If all the other fields are NULL, that means the repository could not be reached or its certificate is invalid.

Return code Description
0 (SUCCESS) list of repositories in ctx->repos
EINVAL bad input parameters
ENOENT no repository found
ENOMEM memory allocation error
ctx->repos Description
url repository url (or NULL for the last item)
cn canonical name of the repository
num the number of packages in this repository

Private Functions

Normally not accessible, but might be useful and good to know.

Lock Package DB

int syspkg_lock(int acquire);

Checks or acquires exclusive access for package management.

Return code Description
0 (SUCCESS) everything went well
EEXIST another instance is already running
EPERM unable to write the lock file

Unlock Package DB

int syspkg_unlock();

Releases exclusive access for package management.

Return code Description
0 (SUCCESS) everything went well
EPERM unable to remove the lock file

Generate Metainfo Signature

int syspkg_gensig(syspkg_ctx_t *ctx, char *buffer);

Generates signature to a zero terminated package metajson string passed in buffer.

Return code Description
0 (SUCCESS) zero terminated pem signature string in ctx->cert
EINVAL bad input parameters
ENOMEM memory allocation error
EFAULT cryptographic library related fault

Check Metainfo Signature

int syspkg_chksig(mbedtls_x509_crt *repocrt, mbedtls_x509_buf *repocrl, char *buffer);

Checks the validity of the signature of a zero terminated package metajson string passed in buffer. The signature certificate is accepted if matches the metajson's hash, issued by the repository's owner but not listed in the certificate revokation list or if the certificate is in the trusted certificates list. The CRL is not standard, it is a list of binary public key sha hashes. First, standard CRL does not allow revokation of keys, it only lists serial numbers. Second, the underlying cryptographic engine can't generate those.

Return code Description
0 (SUCCESS) the signature is valid
EINVAL bad input parameters
ENOMEM memory allocation error
EFAULT cryptographic library related fault
EPERM the metainfo hash and the signature hash do not match
EACCESS bad certificate used for signing
ENOENT signed by a maintainer cert not in trusted list

Read Entire File from Disk or Remote Server into Memory

int syspkg_readfileall(char *url, unsigned char **buf, size_t *len);

Downloads a small file from a server via https or loads from a local file.

Return code Description
0 (SUCCESS) content in buffer
EINVAL bad input parameters
ENOMEM memory allocation error
EFAULT SSL hanshake fault
EACCESS connection error
EIO SSL read or write error
ENOENT http 404, file not found or too many redirects

Check Administrator Privileges

int syspkg_isadmin();

Returns 1 if the user running the executable has admin privileges.