pacutils-mtree(3)
π pacutils-mtree π
okay so bestie, welcome to the pacutils-mtree(3) page β that's the manual section 3, library-call vibes, and yes it's from pacutils, the whole thing is dated 2025-12-04 and we'll get to that at the very end, promise π«Ά
β¨ NAME β¨
pacutils-mtree β read mtree data for installed packages πΈ
Literally what it says: you want the mtree info for stuff that's already installed on your system, this is the girl for the job.
π SYNOPSIS π
First, the include, because you gotta:
#include <pacutils/mtree.h>
Then the entry struct, and listen, this is the main character struct, memorize her:
typedef struct pu_mtree_t {
char *path;
char *type;
uid_t uid;
gid_t gid;
mode_t mode;
off_t size;
char *md5digest;
char *sha256digest;
} pu_mtree_t;
Then the reader struct (she's the one doing the actual reading):
typedef struct {
FILE *stream;
int eof;
pu_mtree_t defaults;
} pu_mtree_reader_t;
And the functions, all five plus the deprecated one π
pu_mtree_reader_t *pu_mtree_reader_open_stream(FILE *stream);
pu_mtree_reader_t *pu_mtree_reader_open_package(alpm_handle_t *h, alpm_pkg_t *p);
pu_mtree_t *pu_mtree_reader_next(pu_mtree_reader_t *reader, pu_mtree_t *dest);
void pu_mtree_reader_free(pu_mtree_reader_t *reader);
void pu_mtree_free(pu_mtree_t *mtree);
/* deprecated */
alpm_list_t *pu_mtree_load_pkg_mtree(alpm_handle_t *handle, alpm_pkg_t *pkg);
π¦ DESCRIPTION π¦
okay so the whole point of these package mtree reading functions is that they fill gaps in libarchive's mtree reader β most notably "md5digest" and "sha256digest", which libarchive is currently not reading at all. not me pointing fingers but π
β οΈ real talk: support here is incomplete β this is only meant to supplement libalpm's native mtree reader, not replace it. do not treat this like a full reimplementation, bestie, it is not.
Now the functions one by one:
pu_mtree_reader_t *pu_mtree_reader_open_stream(FILE *stream);β opens a file stream for parsing. that's it, that's the whole job. πpu_mtree_reader_t *pu_mtree_reader_open_package(alpm_handle_t *h, alpm_pkg_t *p);β opens an installed package's mtree file for parsing. heads up though: results are undefined if"p"is not a locally installed package. so like, don't do that. lowkey important. πpu_mtree_t *pu_mtree_reader_next(pu_mtree_reader_t *reader, pu_mtree_t *dest);β reads and returns the next entry in the mtree file. here's the cute part: if"dest"is"NULL", a brand new"pu_mtree_t"object gets allocated and you (the caller) are responsible for freeing it. otherwise"dest"gets filled with the parsed data. internally allocated memory is automatically freed as needed, so you don't have to stress about that part. π«Άvoid pu_mtree_free(pu_mtree_t *mtree);β frees a"pu_mtree_t"struct. scrub the entry, she's done. β¨void pu_mtree_reader_free(pu_mtree_reader_t *reader);β frees a"pu_mtree_reader_t"object. bye reader bestie πalpm_list_t *pu_mtree_load_pkg_mtree(alpm_handle_t *handle, alpm_pkg_t *pkg);β returns a list of mtree entries for"pkg". DEPRECATED: use"pu_mtree_reader_open_package"instead. she's iconic but she's retired, periodt π
π EXAMPLES π
the classic demo: print file md5sums for a package. here's the whole thing verbatim so you can just copy-paste and slay:
pu_mtree_t *m;
pu_mtree_reader_t *r;
if((r = pu_mtree_reader_open_package(handle, pkg)) == NULL) {
fprintf(stderr, "error: unable to load mtree data for '%s'\n",
alpm_pkg_get_name(pkg));
return;
}
while((m = pu_mtree_reader_next(r, NULL))) {
const char *md5 = m->md5digest;
printf("%s: %s\n", m->path,
md5 && md5[0] != '\0' ? md5 : "(no md5sum provided)");
pu_mtree_free(m);
}
if(!reader->eof) {
fprintf(stderr, "error: unable to read mtree data for '%s'\n",
alpm_pkg_get_name(pkg));
}
pu_mtree_reader_free(r);
a few things worth noticing, since we're here:
- the
NULLpassed asdestinpu_mtree_reader_next(r, NULL)β that's the allocate-a-new-one path, which is exactly why every loop iteration also callspu_mtree_free(m). no leaks, we're responsible queens π - the ternary on md5 checks
md5 && md5[0] != '\0'before printing, and falls back to"(no md5sum provided)"β so an empty digest doesn't get printed as a mystery blank. - after the loop,
if(!reader->eof)is the vibe check on whether reading actually finished cleanly β if not, it yells at stderr and you know something went wrong. π
and finally pu_mtree_reader_free(r) to clean up the reader itself.
π SEE ALSO π
go read these next, iykyk:
alpm_pkg_mtree_open(3)alpm_pkg_mtree_next(3)alpm_pkg_mtree_close(3)mtree(5)β this one is literally the description of"pu_mtree_t"members, so if you were confused about a field, that's your girl π
okay that's the whole page, you ate that π
one last thing: this was pacutils-mtree(3), section 3 of the manual, from pacutils, version-dated 2025-12-04 β go forth and read those mtree files, bestie, you've got this πβ¨π«Ά
π¦ where this page comes from
- arch rolling: pacutils 0.15.0-2 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms