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]]
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.
int syspkg_free(syspkg_ctx_t *ctx);
Frees a package manager instance.
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 |
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.
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 |
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.
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.
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 |
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 |
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.
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.
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
.
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 |
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 |
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 |
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 |
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 |
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) |
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()
.
Use syspkg_search
with the depends
parameter.
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.
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 |
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 |
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 |
Normally not accessible, but might be useful and good to know.
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 |
int syspkg_unlock();
Releases exclusive access for package management.
Return code | Description |
---|---|
0 (SUCCESS) | everything went well |
EPERM | unable to remove the lock file |
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 |
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 |
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 |
int syspkg_isadmin();
Returns 1 if the user running the executable has admin privileges.