Commit 1f288990 authored by aTc's avatar aTc

Merge branch 'master' of https://github.com/slaeshjag/dbp into upstream

parents c02e0ff6 ea8129c5
......@@ -12,3 +12,4 @@
*.remote
build/
install/
documentation/
......@@ -40,9 +40,11 @@ all:
+@make -C dbp-cmd/
@echo " [ CD ] dbp-desktopd/"
+@make -C dbp-desktopd/
@echo " [ CD ] dbp-validate-extracted/"
+@make -C dbp-validate-extracted/
@echo " [POT ] po/dbp-run.pot"
@xgettext --package-name="DragonBox-Package-system" --package-version="$(VERSION)" -L C -k_ -d dbp-run -s -o po/dbp-run.pot dbp-run/*.vala dbp-run/common/*.vala dbp-cfg/*.c dbp-meta/*.c dbp-cmd/*.c dbp-thumbnailer/*.c
@xgettext --package-name="DragonBox-Package-system" --package-version="$(VERSION)" -L C -k_ -d dbp-run -s -o po/dbp-run.pot dbp-run/*.vala dbp-run/common/*.vala dbp-cfg/*.c dbp-meta/*.c dbp-cmd/*.c dbp-thumbnailer/*.c dbp-validate-extracted/*.c libdbpmgr/*.c
@echo " [ CD ] po/"
+@make -C po/
......@@ -70,40 +72,43 @@ clean:
+@make -C dbp-cmd/ clean
@echo " [ CD ] dbp-desktopd/"
+@make -C dbp-desktopd/ clean
@echo " [ CD ] dbp-validate-extracted/"
+@make -C dbp-validate-extracted/ clean
@echo
@echo "Source tree cleaned."
@echo
install:
install -d "$(PREFIX)/etc/dbp"
install -m 644 -t "$(PREFIX)/etc/dbp" "$(TOPDIR)/conf/dbp_config.ini"
install -m 644 -t "$(PREFIX)/etc/dbp" "$(TOPDIR)/conf/dbpd-introspection.xml"
install -m 644 -t "$(PREFIX)/etc/dbp" "$(TOPDIR)/scripts/dbp_exec"
install -m 755 -t "$(PREFIX)/etc/dbp" "$(TOPDIR)/scripts/run_script"
install -d "$(PREFIX)/lib/systemd/system/"
install -m 644 -t "$(PREFIX)/lib/systemd/system" "$(TOPDIR)/conf/dbpd.service"
install -d "$(PREFIX)/etc/dbus-1/system.d"
install -m 644 -t "$(PREFIX)/etc/dbus-1/system.d" "$(TOPDIR)/conf/de.dragonbox.PackageDaemon.conf"
install -d "$(PREFIX)/etc/xdg/autostart"
install -m 644 -t "$(PREFIX)/etc/xdg/autostart" "$(TOPDIR)/conf/dbp-desktopd-autostart.desktop"
install -d "$(PREFIX)/usr/share/binfmts/"
install -m 644 -t "$(PREFIX)/usr/share/binfmts" "$(TOPDIR)/conf/binfmts/dbp.binfmt"
install -d "$(PREFIX)/usr/share/applications"
install -m 644 -t "$(PREFIX)/usr/share/applications" "$(TOPDIR)/conf/dbp-run-path.desktop"
install -d "$(PREFIX)/usr/share/mime"
install -m 644 -t "$(PREFIX)/usr/share/mime" "$(TOPDIR)/conf/mime/x-dbp.xml"
install -d "$(PREFIX)/usr/bin"
install -m 755 $(STRIP_FLAG) -t "$(PREFIX)/usr/bin/" "$(TOPDIR)/build/bin/dbp-cfg"
install -m 755 $(STRIP_FLAG) -t "$(PREFIX)/usr/bin/" "$(TOPDIR)/build/bin/dbp-cmd"
install -m 755 $(STRIP_FLAG) -t "$(PREFIX)/usr/bin/" "$(TOPDIR)/build/bin/dbpd"
install -m 755 $(STRIP_FLAG) -t "$(PREFIX)/usr/bin/" "$(TOPDIR)/build/bin/dbp-desktopd"
install -m 755 $(STRIP_FLAG) -t "$(PREFIX)/usr/bin/" "$(TOPDIR)/build/bin/dbp-meta"
install -m 755 $(STRIP_FLAG) -t "$(PREFIX)/usr/bin/" "$(TOPDIR)/build/bin/dbp-run"
install -m 755 $(STRIP_FLAG) -t "$(PREFIX)/usr/bin/" "$(TOPDIR)/build/bin/dbp-run-path"
install -d "$(PREFIX)/usr/lib"
install -m 644 $(STRIP_FLAG) -t "$(PREFIX)/usr/lib/" "$(TOPDIR)/build/lib/libdbpmgr.so"
install -m 644 $(STRIP_FLAG) -t "$(PREFIX)/usr/lib/" "$(TOPDIR)/build/lib/libdbpbase.so"
install -d "$(PREFIX)/usr/include/dbpmgr"
install -m 644 -t "$(PREFIX)/usr/include/dbpmgr" $(TOPDIR)/build/include/dbpmgr/*.h
install -d "$(PREFIX)/usr/include/dbpbase"
install -m 644 -t "$(PREFIX)/usr/include/dbpbase" $(TOPDIR)/build/include/dbpbase/*.h
install -d "$(DESTDIR)/etc/dbp"
install -m 644 -t "$(DESTDIR)/etc/dbp" "$(TOPDIR)/conf/dbp_config.ini"
install -m 644 -t "$(DESTDIR)/etc/dbp" "$(TOPDIR)/conf/dbpd-introspection.xml"
install -m 644 -t "$(DESTDIR)/etc/dbp" "$(TOPDIR)/scripts/dbp_exec"
install -m 755 -t "$(DESTDIR)/etc/dbp" "$(TOPDIR)/scripts/run_script"
install -d "$(DESTDIR)/lib/systemd/system/"
install -m 644 -t "$(DESTDIR)/lib/systemd/system" "$(TOPDIR)/conf/dbpd.service"
install -d "$(DESTDIR)/etc/dbus-1/system.d"
install -m 644 -t "$(DESTDIR)/etc/dbus-1/system.d" "$(TOPDIR)/conf/de.dragonbox.PackageDaemon.conf"
install -d "$(DESTDIR)/etc/xdg/autostart"
install -m 644 -t "$(DESTDIR)/etc/xdg/autostart" "$(TOPDIR)/conf/dbp-desktopd-autostart.desktop"
install -d "$(DESTDIR)/usr/share/binfmts/"
install -m 644 -t "$(DESTDIR)/usr/share/binfmts" "$(TOPDIR)/conf/binfmts/dbp.binfmt"
install -d "$(DESTDIR)/usr/share/applications"
install -m 644 -t "$(DESTDIR)/usr/share/applications" "$(TOPDIR)/conf/dbp-run-path.desktop"
install -d "$(DESTDIR)/usr/share/mime"
install -m 644 -t "$(DESTDIR)/usr/share/mime" "$(TOPDIR)/conf/mime/x-dbp.xml"
install -d "$(DESTDIR)/usr/bin"
install -m 755 $(STRIP_FLAG) -t "$(DESTDIR)/usr/bin/" "$(TOPDIR)/build/bin/dbp-cfg"
install -m 755 $(STRIP_FLAG) -t "$(DESTDIR)/usr/bin/" "$(TOPDIR)/build/bin/dbp-cmd"
install -m 755 $(STRIP_FLAG) -t "$(DESTDIR)/usr/bin/" "$(TOPDIR)/build/bin/dbpd"
install -m 755 $(STRIP_FLAG) -t "$(DESTDIR)/usr/bin/" "$(TOPDIR)/build/bin/dbp-desktopd"
install -m 755 $(STRIP_FLAG) -t "$(DESTDIR)/usr/bin/" "$(TOPDIR)/build/bin/dbp-meta"
install -m 755 $(STRIP_FLAG) -t "$(DESTDIR)/usr/bin/" "$(TOPDIR)/build/bin/dbp-run"
install -m 755 $(STRIP_FLAG) -t "$(DESTDIR)/usr/bin/" "$(TOPDIR)/build/bin/dbp-run-path"
install -m 755 $(STRIP_FLAG) -t "$(DESTDIR)/usr/bin/" "$(TOPDIR)/build/bin/dbp-validate-extracted"
install -d "$(DESTDIR)/usr/lib"
install -m 644 $(STRIP_FLAG) -t "$(DESTDIR)/usr/lib/" "$(TOPDIR)/build/lib/libdbpmgr.so"
install -m 644 $(STRIP_FLAG) -t "$(DESTDIR)/usr/lib/" "$(TOPDIR)/build/lib/libdbpbase.so"
install -d "$(DESTDIR)/usr/include/dbpmgr"
install -m 644 -t "$(DESTDIR)/usr/include/dbpmgr" $(TOPDIR)/build/include/dbpmgr/*.h
install -d "$(DESTDIR)/usr/include/dbpbase"
install -m 644 -t "$(DESTDIR)/usr/include/dbpbase" $(TOPDIR)/build/include/dbpbase/*.h
......@@ -2,6 +2,13 @@
+ Feature added
- Feature removed
* Bug fixed
[0.6.12.1] 2016-05-10
+ meta-data validation tool will now chekck package icon and
% check for unused icons
[0.6.12] 2016-05-10
+ Added a crude meta-data validation utility
% Most probably quite buggy and incomplete
[0.6.11] 2015-11-05
+ New dependency checking system
......
......@@ -16,6 +16,7 @@ METABIN = "$(TOPDIR)/build/bin/$(NAME)-meta"
CMDBIN = "$(TOPDIR)/build/bin/$(NAME)-cmd"
DESKTOPBIN = "$(TOPDIR)/build/bin/$(NAME)-desktopd"
THUMBBIN = "$(TOPDIR)/build/bin/$(NAME)-thumbnailer"
VALIDBIN = "$(TOPDIR)/build/bin/$(NAME)-validate-extracted"
LIB = "$(TOPDIR)/dbp-common/dbp-common.a"
LIBINC = "-I$(TOPDIR)/libdbpbase" "-I$(TOPDIR)/build/include"
......@@ -28,7 +29,8 @@ RM = rm -fR
MKDIR = mkdir -p
CP = cp
MV = mv
PREFIX ?= /
DESTDIR ?= /
PREFIX ?= $(DESTDIR)
ifneq ($(wildcard /etc/debian_version),)
#Debian packaging
......
......@@ -99,13 +99,13 @@ public class DepListDialog {
dialog.get_content_area().pack_start(dbpex, true, true, 0);
install = new Gtk.Button.with_label(_("Install missing dependencies"));
install.always_show_image = true;
install.set_always_show_image(true);
install.set_image(new Gtk.Image.from_icon_name("gtk-floppy", Gtk.IconSize.BUTTON));
launch = new Gtk.Button.with_label(_("Launch anyway"));
launch.always_show_image = true;
launch.set_always_show_image(true);
launch.set_image(new Gtk.Image.from_icon_name("gtk-yes", Gtk.IconSize.BUTTON));
abort = new Gtk.Button.with_label(_("Abort launch"));
abort.always_show_image = true;
abort.set_always_show_image(true);
abort.set_image(new Gtk.Image.from_icon_name("gtk-no", Gtk.IconSize.BUTTON));
this.dialog.add_action_widget(install, Result.INSTALL);
this.dialog.add_action_widget(abort, Result.ABORT);
......
# Project: pyra-hspkg
include $(TOPDIR)/config.mk
SRCFILES = $(wildcard *.c)
OBJFILES = $(SRCFILES:.c=.o)
.PHONY: all clean
all: $(OBJFILES) $(DEPENDS)
@echo " [ LD ] $(VALIDBIN)"
@$(CC) -o $(VALIDBIN) $(OBJFILES) $(LIBBASE) $(LDFLAGS)
@echo "Done."
@echo
clean:
@echo
@echo " [ RM ] $(OBJFILES)"
@$(RM) $(OBJFILES)
@echo "Done."
@echo
%.o: %.c %.h
@echo " [ CC ] dbp-validate-extracted/$<"
@$(CC) $(LIBINC) $(CFLAGS) -c -o $@ $<
#ifndef __CATEGORIES_H__
#define __CATEGORIES_H__
#include <stdlib.h>
#include <stdbool.h>
struct CategoryEntry {
char *name;
char *parents[4];
bool requires_parent;
};
struct CategoryEntry freedesktop_cat[] = {
{ "AudioVideo", { NULL }, false },
{ "Audio", { "AudioVideo", NULL }, true },
{ "Video", { "AudioVideo", NULL }, true },
{ "Development", { NULL }, false },
{ "Education", { NULL }, false },
{ "Game", { NULL }, false },
{ "Graphics", { NULL }, false },
{ "Network", { NULL }, false },
{ "Office", { NULL }, false },
{ "Science", { NULL }, false },
{ "Settings", { NULL }, false },
{ "System", { NULL }, false },
{ "Utility", { NULL }, false },
{ "Building", { "Development", NULL }, true },
{ "Debugger", { "Development", NULL }, true },
{ "IDE", { "Development", NULL }, true },
{ "GUIDesigner", { "Development", NULL }, true },
{ "Profiling", { "Development", NULL }, true },
{ "RevisionControl", { "Development", NULL }, true },
{ "Translation", { "Development", NULL }, true },
{ "Calendar", { "Office", NULL }, true },
{ "ContactManagement", { "Office", NULL }, true },
{ "Database", { "Office", "Development", "AudioVideo", NULL }, true },
{ "Dictionary", { "Office", "TextTools", NULL }, true },
{ "Chart", { "Office", NULL }, true },
{ "Email", { "Office", "Network", NULL }, true },
{ "Finance", { "Office", NULL }, true },
{ "FlowChart", { "Office", NULL }, true },
{ "PDA", { "Office", NULL }, true },
{ "ProjectManagement", { "Office", "Development", NULL }, true },
{ "Presentation", { "Office", NULL }, true },
{ "Spreadsheet", { "Office", NULL }, true },
{ "WordProcessor", { "Office", NULL }, true },
{ "2DGraphics", { "Graphics", NULL }, true },
{ "VectorGraphics", { "2DGraphics", NULL }, true },
{ "RasterGraphics", { "2DGraphics", NULL }, true },
{ "3DGraphics", { "Graphics", NULL }, true },
{ "Scanning", { "Graphics", NULL }, true },
{ "OCR", { "Scanning", NULL }, true },
{ "Photography", { "Graphics", "Office", NULL }, true },
{ "Publishing", { "Graphics", "Office", NULL }, true },
{ "Viewer", { "Graphics", "Office", NULL }, true },
{ "TextTools", { "Utility", NULL }, true },
{ "DesktopSettings", { "Settings", NULL }, true },
{ "HardwareSettings", { "Settings", NULL }, true },
{ "Printing", { "HardwareSettings", NULL }, true },
{ "PackageManager", { "Settings", NULL }, true },
{ "Dialup", { "Network", NULL }, true },
{ "InstantMessaging", { "Network", NULL }, true },
{ "Chat", { "Network", NULL }, true },
{ "IRCClient", { "Network", NULL }, true },
{ "Feed", { "Network", NULL }, true },
{ "FileTransfer", { "Network", NULL }, true },
{ "HamRadio", { "Network", "Audio", NULL }, true },
{ "News", { "Network", NULL }, true },
{ "P2P", { "Network", NULL }, true },
{ "RemoteAccess", { "Network", NULL }, true },
{ "Telephony", { "Network", NULL }, true },
{ "TelephonyTools", { "Utility", NULL }, true },
{ "VideoConferance", { "Network", NULL }, true },
{ "WebBrowser", { "Network", NULL }, true },
{ "WebDevelopment", { "Network", "Development", NULL }, true },
{ "Midi", { "AudioVideo", "Audio", NULL }, true },
{ "Mixer", { "AudioVideo", "Audio", NULL }, true },
{ "Tuner", { "AudioVideo", "Audio", NULL }, true },
{ "TV", { "AudioVideo", "Video", NULL }, true },
{ "AudioVideoEditing", { "AudioVideo", "Audio", "Video", NULL }, true },
{ "Player", { "Audio", "Video", "AudioVideo", NULL }, true },
{ "Recorder", { "Audio", "Video", "AudioVideo", NULL }, true },
{ "DiscBurning", { "AudioVideo", NULL }, true },
{ "ActionGame", { "Game", NULL }, true },
{ "AdventureGame", { "Game", NULL }, true },
{ "ArcadeGame", { "Game", NULL }, true },
{ "BoardGame", { "Game", NULL }, true },
{ "BlocksGame", { "Game", NULL }, true },
{ "CardGame", { "Game", NULL }, true },
{ "KidsGame", { "Game", NULL }, true },
{ "LogicGame", { "Game", NULL }, true },
{ "RolePlaying", { "Game", NULL }, true },
{ "Shooter", { "Game", NULL }, true },
{ "Simulation", { "Game", NULL }, true },
{ "SportsGame", { "Game", NULL }, true },
{ "StrategyGame", { "Game", NULL }, true },
{ "Art", { "Education", "Science", NULL }, true },
{ "Construction", { "Education", "Science", NULL }, true },
{ "Music", { "AudioVideo", "Education", NULL}, true },
{ "Languages", { "Education", "Science", NULL }, true },
{ "ArtificialIntelligence", { "Education", "Science", NULL }, true },
{ "Astronomy", { "Education", "Science", NULL }, true },
{ "Biology", { "Education", "Science", NULL }, true },
{ "Chemistry", { "Education", "Science", NULL }, true },
{ "ComputerScience", { "Education", "Science", NULL }, true },
{ "DataVisualization", { "Education", "Science", NULL }, true },
{ "Economy", { "Education", "Science", NULL }, true },
{ "Electricity", { "Education", "Science", NULL }, true },
{ "Geography", { "Education", "Science", NULL }, true },
{ "Geology", { "Education", "Science", NULL }, true },
{ "Geoscience", { "Education", "Science", NULL }, true },
{ "History", { "Education", "Science", NULL }, true },
{ "Humanities", { "Education", "Science", NULL }, true },
{ "ImageProcessing", { "Education", "Science", NULL }, true },
{ "Literature", { "Education", "Science", NULL }, true },
{ "Maps", { "Education", "Science", "Utility", NULL }, true },
{ "Math", { "Education", "Science", NULL }, true },
{ "NumericalAnalysis", { "Math", NULL }, true },
{ "MedicalSoftware", { "Education", "Science", NULL }, true },
{ "Physics", { "Education", "Science", NULL }, true },
{ "Robotics", { "Education", "Science", NULL }, true },
{ "Spirituality", { "Education", "Utility", NULL }, true },
{ "Sports", { "Education", "Science", NULL }, true },
{ "ParallelComputing", { "ComputerScience", NULL }, true },
{ "Amusement", { NULL }, true },
{ "Archiving", { "Utility", NULL }, true },
{ "Compression", { "Archiving", NULL }, true },
{ "Electronics", { NULL }, false },
{ "Emulator", { "System", "Game", NULL }, true },
{ "Engineering", { NULL }, false },
{ "FileTools", { "Utility", "System", NULL }, true },
{ "FileManager", { "FileTools", NULL }, true },
{ "TerminalEmulator", { "System", NULL }, true },
{ "Filesystem", { "System", NULL }, true },
{ "Monitor", { "System", "Network", NULL }, true },
{ "Security", { "Settings", "System", NULL }, true },
{ "Accessibility", { "Settings", "Utility", NULL }, true },
{ "Calculator", { "Utility", NULL }, true },
{ "Clock", { "Utility", NULL }, true },
{ "TextEditor", { "Utility", NULL }, true },
{ "Documentation", { NULL }, false },
{ "Adult", { NULL }, true },
{ "Core", { NULL }, true },
/* TODO: Determine if the desktop specific ones should go here */
};
#endif
#define _GNU_SOURCE
#include <libintl.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <string.h>
#include <dirent.h>
#include <ctype.h>
#include <sys/types.h>
#include <dbpbase/dbpbase.h>
#include <dbpbase/desktop.h>
#include "validate.h"
#include "categories.h"
#define _(STRING) gettext(STRING)
#define LOG_FREE(msg, dest) free(add_string_message(&(dest), (msg)))
#define LOG(msg, dest) add_string_message(&(dest), (msg))
struct StringBuffer {
char *str;
struct StringBuffer *next;
};
struct StringBufferContainer {
struct StringBuffer *first;
struct StringBuffer *last;
int count;
};
struct CheckList {
char *name;
char *full_name;
bool check;
struct CheckList *next;
};
struct StringBufferContainer notice, warning, error;
struct CheckList *icons_avail, *icons_used, *launchers_to_skip, *execs_used, *desktop_files_to_scan;
char *rootfs_path = NULL, *meta_path = NULL;
bool directorylist_to_checklist(char *name, struct CheckList **list, char *prefix, char *suffix);
void checklist_add(char *str, char *name, struct CheckList **list) {
struct CheckList *new;
new = malloc(sizeof(*new));
new->check = false;
new->name = strdup(name);
new->full_name = strdup(str);
new->next = *list;
*list = new;
return;
}
struct CheckList *checklist_find(char *str, struct CheckList *list) {
if (!list)
return NULL;
if (!strcmp(list->name, str))
return list;
return checklist_find(str, list->next);
}
char *add_string_message(struct StringBufferContainer *cont, char *string) {
struct StringBuffer *new = malloc(sizeof(*new));
new->next = NULL;
if (cont->last) {
cont->last->next = new;
cont->last = new;
} else {
cont->first = new;
cont->last = new;
}
cont->count++;
new->str = strdup(string);
return string;
}
void usage() {
fprintf(stdout, _("Validates ingoing files before a DBP is created\n"));
fprintf(stdout, _("By Steven Arnow, 2015-2016, version %s\n"), dbp_config_version_get());
fprintf(stdout, "\n");
fprintf(stdout, _("Usage:\n"));
fprintf(stdout, _("dbp-validate-extracted <path to meta directory> [path to rootfs directory]\n"));
}
void print_messages() {
struct StringBuffer *next;
for (next = error.first; next; next = next->next)
fprintf(stdout, "ERROR: %s\n", next->str);
for (next = warning.first; next; next = next->next)
fprintf(stdout, "WARNING: %s\n", next->str);
for (next = notice.first; next; next = next->next)
fprintf(stdout, "NOTICE: %s\n", next->str);
if (error.count || warning.count || notice.count)
fprintf(stdout, "%i errors, %i warnings, %i notices\n", error.count, warning.count, notice.count);
}
static struct DBPDefaultMetaKey *__lookup_metakey(char *meta) {
int i;
for (i = 0; default_mk[i].name; i++)
if (!strcmp(meta, default_mk[i].name))
return &default_mk[i];
return NULL;
}
bool _conforms_strict_name_type(char *str) {
if (*str == '.' || *str == 0)
return false;
for (; *str; str++)
if (!isascii(*str) || !(isalnum(*str) || *str == '.' || *str == '_' || *str == '-'))
return false;
return true;
}
bool _contains_uppercase(const char *str) {
for (; *str; str++)
if (isupper(*str))
return true;
return false;
}
struct CategoryEntry *_find_category(const char *cat) {
int i;
for (i = 0; freedesktop_cat[i].name; i++)
if (!strcmp(freedesktop_cat[i].name, cat))
return &freedesktop_cat[i];
return NULL;
}
bool _valid_parent_category(struct CategoryEntry *ce, const char *prev) {
int i;
if (!ce->requires_parent)
return true;
if (!prev)
return false;
for (i = 0; ce->parents[i]; i++)
if (!strcmp(ce->parents[i], prev))
return true;
return false;
}
bool _valid_category(const char *prev, const char *cat) {
int i, j;
for (i = 0; freedesktop_cat[i].name; i++) {
if (strcmp(freedesktop_cat[i].name, cat))
continue;
if (!freedesktop_cat[i].requires_parent)
return true;
if (!prev)
return false;
for (j = 0; freedesktop_cat[i].parents[j]; j++)
if (!strcmp(freedesktop_cat[i].parents[j], prev))
return true;
return false;
}
return false;
}
void _find_unused_icons() {
struct CheckList *next;
char *tmp;
for (next = icons_avail; next; next = next->next)
if (!checklist_find(next->name, icons_used))
LOG_FREE((asprintf(&tmp, "Icon file %s is present but not used", next->name), tmp), warning);
}
bool validate_desktop_file(const char *path) {
int section;
struct DBPDesktopFile *df;
char *tmp;
bool valid = true;
if (!(df = dbp_desktop_parse_file(path)))
return LOG_FREE((asprintf(&tmp, "Desktop file %s could not be opened", path), tmp), warning), false;
if ((section = dbp_desktop_lookup_section(df, "Desktop Entry")) < 0)
return LOG_FREE((asprintf(&tmp, "Desktop file %s does not have a desktop entry", path), tmp), warning), false;
if (!(tmp = dbp_desktop_lookup(df, "Type", NULL, "Desktop Entry")))
return LOG_FREE((asprintf(&tmp, "Desktop file %s does not specify a type in its desktop entry", path), tmp), error), false;
if (!strcmp(tmp, "Application")) {
if (!dbp_desktop_lookup(df, "Exec", NULL, "Desktop Entry") && !dbp_desktop_lookup(df, "TryExec", NULL, "Desktop Entry"))
LOG_FREE((asprintf(&tmp, "Desktop file %s does not provide a Exec or TryExec entry, which is mandatory for applications", path), tmp), error), valid = false;
} else if (!strcmp(tmp, "Link")) {
if (!(tmp = dbp_desktop_lookup(df, "URL", NULL, "Desktop Entry")) || !strlen(tmp))
LOG_FREE((asprintf(&tmp, "Desktop file %s does not provide a URL entry, which is mandatory for links", path), tmp), error), valid = false;
} else if (!strcmp(tmp, "Directory")) {
} else
LOG_FREE((asprintf(&tmp, "Desktop file %s have an invalid type '%s' in its desktop entry", path, tmp), tmp), error), valid = false;
/* TODO: Check that all present keys are known */
if (!(tmp = dbp_desktop_lookup(df, "Name", NULL, "Desktop Entry")) || !strlen(tmp))
LOG_FREE((asprintf(&tmp, "Desktop file %s does not have a name set in its desktop entry", path), tmp), error), valid = false;
if (!(tmp = dbp_desktop_lookup(df, "Comment", NULL, "Desktop Entry")) || !strlen(tmp))
LOG_FREE((asprintf(&tmp, "Desktop file %s is missing a comment in its desktop entry", path), tmp), warning);
if (!(tmp = dbp_desktop_lookup(df, "Icon", NULL, "Desktop Entry")) || !strlen(tmp))
LOG_FREE((asprintf(&tmp, "Desktop file %s is missing an icon in its desktop entry", path), tmp), warning);
else {
checklist_add(tmp, tmp, &icons_used);
if (!checklist_find(tmp, icons_avail))
LOG_FREE((asprintf(&tmp, "Desktop file %s uses the icon %s, which is missing", path, tmp), tmp), error), valid = false;
}
/* Check categories */ {
char *category = NULL, **catlist = NULL, *last;
int categories = 0, i;
if (!(category = dbp_desktop_lookup(df, "Categories", NULL, "Desktop Entry")))
return LOG_FREE((asprintf(&tmp, "Desktop file %s does not have any categories set in its desktop entry", path), tmp), error), false;
category = strdup(category);
if (category[strlen(category) - 1] != ';')
LOG_FREE((asprintf(&tmp, "Desktop file %s has categories, but the list isn't terminated with a ';'", path), tmp), error);
else
category[strlen(category) - 1] = 0;
dbp_config_expand_token(&catlist, &categories, category);
for (i = 0, last = NULL; i < categories; i++) {
struct CategoryEntry *ce;
if (!(ce = _find_category(catlist[i])))
LOG_FREE((asprintf(&tmp, "Desktop file %s uses invalid category '%s'", path, catlist[i]), tmp), error), valid = false;
else if (!_valid_parent_category(ce, last)) {
if (!ce->parents[0])
LOG_FREE((asprintf(&tmp, "Desktop file %s uses the subcategory '%s', but a main category must preceed it", path, catlist[i]), tmp), error), valid = false;
else if (!ce->parents[1])
LOG_FREE((asprintf(&tmp, "Desktop file %s uses the subcategory '%s', but the category '%s' must preceed it", path, catlist[i], ce->parents[0]), tmp), error), valid = false;
else if (!ce->parents[2])
LOG_FREE((asprintf(&tmp, "Desktop file %s uses the subcategory '%s', but the category '%s' or '%s' must preceed it", path, catlist[i], ce->parents[0], ce->parents[1]), tmp), error), valid = false;
else
LOG_FREE((asprintf(&tmp, "Desktop file %s uses the subcategory '%s', but the category '%s', '%s' or '%s' must preceed it", path, catlist[i], ce->parents[0], ce->parents[1], ce->parents[2]), tmp), error), valid = false;
}
last = catlist[i];
}
}
return valid;
}