#include <sys/types.h>
#include <time.h>
-// libarchive
#include <archive_entry.h>
+#include <gelf.h>
+
#include <pakfire/ctx.h>
#include <pakfire/constants.h>
#include <pakfire/digest.h>
Classification
*/
+static int setup_libelf(struct pakfire_ctx* ctx) {
+ // Initialize libelf
+ if (elf_version(EV_CURRENT) == EV_NONE) {
+ ERROR(ctx, "Could not initialize libelf: %s\n", elf_errmsg(-1));
+
+ return 1;
+ }
+
+ return 0;
+}
+
static int pakfire_file_classify_mode(struct pakfire_file* file) {
const mode_t mode = pakfire_file_get_mode(file);
return 0;
}
+static int pakfire_file_classify_elf(struct pakfire_file* file) {
+ FILE* f = NULL;
+ Elf* elf = NULL;
+ int r;
+
+ // Don't run this if we already know that file is an ELF file
+ if (file->class & PAKFIRE_FILE_ELF)
+ return 0;
+
+ // Setup libelf
+ r = setup_libelf(file->ctx);
+ if (r)
+ return r;
+
+ // Open the file
+ f = pakfire_file_open(file);
+ if (!f) {
+ ERROR(file->ctx, "Could not open %s: %m\n", pakfire_file_get_path(file));
+ return 1;
+ }
+
+ // Try to open the ELF file
+ elf = elf_begin(fileno(f), ELF_C_READ, NULL);
+ if (!elf) {
+ // We fail silently here, because this file might be in a different format
+ goto ERROR;
+ }
+
+ switch (elf_kind(elf)) {
+ // Mark this file as an ELF file
+ case ELF_K_ELF:
+ file->class |= PAKFIRE_FILE_ELF;
+ break;
+
+ // Ignore everything else
+ default:
+ break;
+ }
+
+ERROR:
+ if (elf)
+ elf_end(elf);
+ if (f)
+ fclose(f);
+
+ return 0;
+}
+
int pakfire_file_classify(struct pakfire_file* file) {
int r;
r = pakfire_file_classify_magic(file);
if (r)
goto ERROR;
+
+ // Check if the file is an ELF file
+ r = pakfire_file_classify_elf(file);
+ if (r)
+ goto ERROR;
}
}