Commit 5d851174 authored by aTc's avatar aTc

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

parents d8a3d3b4 cf35dbac
......@@ -7,4 +7,7 @@
*.swo
*.bin
*.pot
*.orig
*.local
*.remote
build/
......@@ -19,15 +19,17 @@ all:
+@make -C dbp-common/
@echo " [ CD ] dbpd/"
+@make -C dbpd/
@echo " [ CD ] dbp-run-vala/"
+@make -C dbp-run-vala/
@echo " [ CD ] dbp-thumbnailer/"
+@make -C dbp-thumbnailer/
@echo " [ CD ] dbp-run/"
+@make -C dbp-run/
@echo " [ CD ] dbp-cfg/"
+@make -C dbp-cfg/
@echo " [ CD ] dbp-meta/"
+@make -C dbp-meta/
@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/*.vala dbp-run-vala/common/*.vala dbp-cfg/*.c dbp-meta/*.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
@echo " [ CD ] po/"
@make -C po/
......@@ -41,8 +43,10 @@ clean:
+@make -C dbp-common/ clean
@echo " [ CD ] dbpd/"
+@make -C dbpd/ clean
@echo " [ CD ] dbp-run-vala/"
+@make -C dbp-run-vala/ clean
@echo " [ CD ] dbp-thumbnailer/"
+@make -C dbp-thumbnailer/ clean
@echo " [ CD ] dbp-run/"
+@make -C dbp-run/ clean
@echo " [ CD ] dbp-cfg/"
+@make -C dbp-cfg/ clean
@echo " [ CD ] dbp-meta/"
......
......@@ -29,3 +29,5 @@ dbpout_prefix=dbprun
dbpout_suffix=.log
;; When dbpd is restarted, state about launched programs is written to this file
state_file=/var/lib/dbp/dbp.state
;; If not commented out, launch executables via an extra wrapper allowing user pre-run/post-run scrips
run_script=/etc/dbp/run_script
......@@ -23,9 +23,17 @@ desktop_directory=/usr/share/applications
exec_directory=/usr/local/games
image_mount_dir=/mnt/dbp/images
union_mount_dir=/mnt/dbp/union
overlayfs_tmp1=/mnt/dbp/tmp1
overlayfs_tmp2=/mnt/dbp/tmp2
overlayfs_datamerge=/mnt/dbp/data
;; Used to generate runtime logs from executables with enviroment override set
dbpout_directory=/tmp/dbpout
dbpout_prefix=dbprun
dbpout_suffix=.log
;; When dbpd is restarted, state about launched programs is written to this file
state_file=/var/lib/dbp/dbp.state
;; If not commented out, launch executables via an extra wrapper allowing user pre-run/post-run scrips
;; This can also be used to set up launch enviroments for different ABI/CPU-architectures
;; run_script without index is used when a dbp is lacking the Arch key, or if it's set to "any".
;;run_script=/etc/dbp/run_script
run_script[armhf]=/etc/dbp/run_script
......@@ -6,6 +6,9 @@ Type=forking
ExecStart=/usr/bin/dbpd -d
PIDFile=/var/run/dbpd.pid
Restart=on-abort
TimeoutStopSec=1
ExecStartPost=-/usr/sbin/update-binfmts --import dbp.binfmt
ExecStopPost=-/usr/sbin/update-binfmts --disable dbp.binfmt
[Install]
WantedBy=multi-user.target
......@@ -4,10 +4,13 @@
NAME = dbp
VERSION = 0.5
#Uncomment to build dbp-run without dpkg dependency checking
#BUILD_DPKG = NO
DAEMONBIN = "$(TOPDIR)/build/bin/$(NAME)d"
RUNNERBIN = "$(TOPDIR)/build/bin/$(NAME)-run-old"
CONFIGBIN = "$(TOPDIR)/build/bin/$(NAME)-cfg"
METABIN = "$(TOPDIR)/build/bin/$(NAME)-meta"
THUMBBIN = "$(TOPDIR)/build/bin/$(NAME)-thumbnailer"
LIB = "$(TOPDIR)/dbp-common/dbp-common.a"
LIBINC = "-I$(TOPDIR)/dbp-common"
PREFIX += /usr/local
......
......@@ -91,6 +91,11 @@ int config_init() {
c.per_user_appdata = config_get_bool(df, "per_user_appdata");
/* Optional key */
c.run_script = desktop_lookup(df, "run_script", "", "Package Daemon Config");
if (c.run_script)
c.run_script = strdup(c.run_script);
desktop_free(df);
config_struct = c;
return 1;
......
......@@ -30,6 +30,7 @@ struct config_s {
int create_rodata;
char *state_file;
char *run_script;
};
......
......@@ -8,11 +8,14 @@
#define DBP_DBUS_CLIENT_PREFIX "de.dragonbox.DBP.run"
#define DBP_DBUS_DAEMON_PREFIX "de.dragonbox.PackageDaemon"
#define DBP_DBUS_DAEMON_OBJECT "/de/dragonbox/PackageDaemon"
#define DBP_DBUS_THUMB_PREFIX "de.dragonbox.PackageThumbnail"
#define DBP_DBUS_THUMB_OBJECT "/de/dragonbox/PackageThumbnail"
#define DBP_FS_NAME "squashfs"
#define DBP_UNIONFS_NAME "aufs"
/* ERROR CODES */
#define DBP_ERROR_NO_REPLY -1000 /* dbp daemon did not reply */
......
......@@ -274,12 +274,12 @@ int loop_mount(const char *image, const char *id, const char *user, const char *
goto fail;
free(user_dir), user_dir = NULL;
free(img_dir), img_dir = NULL;
free(rodata_dir), rodata_dir = NULL;
if (mount("none", mount_path, DBP_UNIONFS_NAME, 0, mount_opt) < 0)
goto union_failed;
free(img_dir), img_dir = NULL;
free(mount_path), mount_path = NULL;
free(mount_opt);
return loop_n;
......@@ -298,6 +298,7 @@ illegal_dirname:
goto fail;
union_failed:
fprintf(dbp_error_log, "%s, %s\n", mount_opt, strerror(errno));
umount(img_dir);
ret = DBP_ERROR_UNION_FAILED;
fail:
free(img_dir);
......
......@@ -54,4 +54,3 @@ int meta_package_open(const char *path, struct meta_package_s *mp) {
return errid;
}
VALAC = valac
VALAPKG = --pkg=gio-2.0 --target-glib 2.32 --pkg glib-2.0 --pkg=posix --pkg=dbp
VALAFLAGS = --vapidir=./common -X -I../dbp-common -X -I./common --thread -X -DGETTEXT_PACKAGE=\"dbp-run\"
VALAPKG = --pkg=gio-2.0 --target-glib 2.32 --pkg glib-2.0 --pkg=gtk+-3.0 --pkg=posix --pkg=dbp
VALAFLAGS = --vapidir=./common -X -I../dbp-common --thread -X -DGETTEXT_PACKAGE=\"dbp-run\"
VALASTATICLIBS = -X ../dbp-common/dbp-common.a
LIBS = -X -larchive -X -ldpkg
DEPCHECKLIBS = -X -ldpkg
DEPCHECKSRC = -X -I./dep-check dep-check/*.vala -X dep-check/*.c
ifeq ($(BUILD_DPKG), NO)
DEPCHECKLIBS =
DEPCHECKSRC = -X -I./dep-check dep-check/*.vala -X dep-check/deb_dep_check.nodpkg.c
else
DEPCHECKLIBS = -X -ldpkg
DEPCHECKSRC = -X -I./dep-check dep-check/*.vala -X dep-check/deb_dep_check.c
endif
BINPATH = ../build/bin
all:
@echo " [VALA] dbp-run.vala"
@$(VALAC) -o $(BINPATH)/dbp-run $(VALAPKG) $(VALAFLAGS) dbp-run.vala common/*.vala -X common/*.c $(DEPCHECKSRC) $(VALASTATICLIBS) $(LIBS) $(DEPCHECKLIBS)
@echo " [VALA] dbp-run-path.vala"
......@@ -20,4 +25,4 @@ all:
@echo "Done."
clean:
@echo " Nothing needs to be done to clean dbp-run-vala/"
@echo " Nothing needs to be done to clean dbp-run/"
......@@ -35,7 +35,12 @@ namespace DBP {
NO_DEFAULTH,
SIGEXIT,
SIGSEGV,
MYSTKILL,
MYSTKILL;
public string error_string() {
//TODO: fix
return this.to_string();
}
}
[CCode (cheader_filename = "config.h")]
......@@ -68,6 +73,8 @@ namespace DBP {
bool per_user_appdata;
bool per_package_appdata;
bool create_rodata;
string? run_script;
}
[CCode (cname = "config_struct")]
......
using Gtk;
public class ErrorLog {
bool use_gui = false;
public string[] errormessage = new string[] {
_("The DBP System Daemon is not responding. Make sure it's running"),
_("An unknown internal error has occured. This is only supposed to be a placeholder. You should examine the DBP System daemon log-file for further information."),
_("The system has ran out of loopback device nodes. Try closing some applications and try again."),
_("The system has ran out of loopback device nodes. Try closing some applications and try again."),
_("The DBP System Daemon was unable to assign the package file to a device node. ioctl failed."),
_("The package file could not be opened. Make sure it's still accessable."),
_("Unable to allocate system resources. You're probably out of RAM. Close some programs and try again."),
_("You've attempted to launch a program from a package that could not be found in the local database. This is likely a bug."),
_("Unable to access the package filesystem. This DBP-file is likely corrupt."),
_("The meta-data in this package is malformed: Illegal character(s) was found in a generated mountpoint."),
_("Unable to set up AuFS union. This is likely a bug. This may temporarely be worked around by rebooting."),
_("Your user doesn't have the permissions needed to create the application data directory on the SD-card that this application is installed on."),
_("No default.desktop was found in the meta-data for this package."),
_("The package with this ID is already registered! This is not an error, and you shouldn't see this message."),
_("An unhandled error has occured. This is just a placehoder that you shouldn't see."),
_("Unable to read meta-data from package. The package file is likely corrupt. Try re-downloading it."),
_("This package lacks a default executable, and therefore cannot be executed directly."),
_("The program was killed by a signal"),
_("The program has crashed from a segmentation fault. This likely a bug in the program."),
_("The program exited abnormally for an unknown reason.")
};
public ErrorLog(ref unowned string[] args) {
use_gui = Gtk.init_check(ref args);
}
public void display_errno(int number) {
number = number*(-1) - 1000;
if(number < 0 || number >= errormessage.length)
return;
display(errormessage[number]);
}
public void display(string message) {
string error_msg, path, package_id;
if (Run.package_path == null)
path = _("Unknown");
else
path = Run.package_path;
if (Run.package_id == null)
package_id = _("Unknown");
else
package_id = Run.package_id;
error_msg = _("Error: ") + message + "\n\n" + _("Path: ") + path + "\n" + _("Package ID: ") + package_id;
if(use_gui) {
if (int.parse(message) < 0)
display_errno(int.parse(message));
else {
MessageDialog msgbox = new MessageDialog(null, DialogFlags.MODAL, MessageType.ERROR, ButtonsType.OK, error_msg, message);
msgbox.run();
}
} else {
stdout.printf(error_msg);
}
}
}
namespace Run {
const int appdata_mode = 0755;
string? package_path = null;
string? package_id = null;
class OutputLogger {
int fd;
......@@ -91,7 +94,7 @@ namespace Run {
mountpoint = bus.mount_point_get(pkg_id);
if(mountpoint == null || mountpoint == "" || mountpoint == "!")
throw new IOError.FAILED(_("Failed to find mountpoint"));
throw new IOError.FAILED(_("Failed to find the mountpoint that this package resides on"));
if(DBP.Config.config.per_user_appdata) {
appdata = DBP.Config.config.data_directory + "_" + Environment.get_user_name();
......@@ -102,17 +105,23 @@ namespace Run {
}
if (DBP.Config.config.per_package_appdata) {
DirUtils.create_with_parents(Path.build_filename(mountpoint, appdata, appdata_name), appdata_mode);
var dir = Path.build_filename(mountpoint, appdata, appdata_name);
DirUtils.create_with_parents(dir, appdata_mode);
if (!FileUtils.test(dir, FileTest.IS_DIR))
throw new IOError.FAILED(_("Unable to create appdata directory") + " " + dir + "\n" + _("Make sure you have the file system permissions to create this directory"));
if (DBP.Config.config.create_rodata)
DirUtils.create_with_parents(Path.build_filename(mountpoint, roappdata, appdata_name), appdata_mode);
} else {
DirUtils.create_with_parents(Path.build_filename(mountpoint, appdata), appdata_mode);
var dir = Path.build_filename(mountpoint, appdata);
DirUtils.create_with_parents(dir, appdata_mode);
if (!FileUtils.test(dir, FileTest.IS_DIR))
throw new IOError.FAILED(_("Unable to create appdata directory") + " " + dir + "\n" + _("Make sure you have the file system permissions to create this directory"));
if (DBP.Config.config.create_rodata)
DirUtils.create_with_parents(Path.build_filename(mountpoint, roappdata), appdata_mode);
}
}
public void run(string pkg_id, string exec, string[] args, bool log, bool chdir) throws IOError, SpawnError {
public void run(string pkg_id, string exec, string[] args, bool log, bool chdir) throws IOError, SpawnError, Error {
string mount_id;
string binary_path;
string ?cwd;
......@@ -127,12 +136,17 @@ namespace Run {
if (pkg_id == null)
return;
pkgpath = bus.path_from_id(pkg_id);
try {
pkgpath = bus.path_from_id(pkg_id);
} catch (Error e) {
throw new IOError.FAILED(_("Unable to connect to connect to dbpd, make sure dbpd is running\n\n" + e.message));
}
if (pkgpath == null || pkgpath == "" || pkgpath == "!")
throw new IOError.FAILED(_("pkgid is not in the database"));
Run.package_path = pkgpath;
DBP.Meta.package_open(pkgpath, out pkg);
if (!dependency_ok(pkg_id, pkg))
......@@ -150,6 +164,9 @@ namespace Run {
binary_path = Path.build_filename(DBP.Config.config.union_mount, pkg_id, exec);
cwd = chdir ? Path.build_filename(DBP.Config.config.union_mount, pkg_id) : null;
if (DBP.Config.config.run_script != null)
argv += DBP.Config.config.run_script;
argv += binary_path;
foreach(string s in args)
argv += s;
......@@ -171,7 +188,7 @@ namespace Run {
bus.u_mount(mount_id);
}
public void run_path(string path_in, string[] args) throws IOError, SpawnError {
public void run_path(string path_in, string[] args) throws IOError, SpawnError, Error {
string pkg_id;
string error_code;
string actual_path;
......@@ -184,11 +201,18 @@ namespace Run {
path = Path.build_filename(Environment.get_current_dir(), path_in, null);
else
path = path_in;
pkg_id = bus.register_path(path, out error_code);
try {
pkg_id = bus.register_path(path, out error_code);
} catch (Error e) {
throw new IOError.FAILED(_("Unable to connect to connect to dbpd, make sure dbpd is running\n\n" + e.message));
}
if(pkg_id == "!")
throw new IOError.FAILED(error_code);
Run.package_id = pkg_id;
actual_path = bus.path_from_id(pkg_id);
Run.package_path = actual_path;
DBP.Meta.package_open(actual_path, out meta);
exec_name = meta.desktop_file.lookup("Exec", "", "Desktop Entry");
if (exec_name == null)
......
......@@ -84,19 +84,25 @@ int main(string[] args) {
stdout.printf("%s\n", ret);
return 0;
case "register":
string path;
if (args.length == 2) {
stderr.printf(_("Error: A path to the package that is to be registered needs to be provided\n"));
return 1;
}
if (Path.is_absolute(args[2]))
ret2 = bus.register_path(args[2], out ret);
path = args[2];
else
ret2 = bus.register_path(Path.build_path(Environment.get_current_dir(), args[2], null), out ret);
path = Path.build_path(Environment.get_current_dir(), args[2], null);
ret2 = bus.register_path(path, out ret);
if (int.parse(ret) < 0) {
/* TODO: print error */
/* Should probably return something else if it already was registered */
return 1;
if (int.parse(ret) == -1013) /* Package already registered */
stderr.printf(_("Warning: Package with pkgid %s is already registered at %s\n"), ret2, bus.path_from_id(ret2));
else {
/* TODO: print error */
return 1;
}
}
stdout.printf("%s\n", ret2);
......
......@@ -15,8 +15,11 @@ int main(string[] args) {
Config config = Config() {
gui_errors = false
};
ErrorLog errorlog;
bus = null;
errorlog = new ErrorLog(ref args);
Intl.setlocale(LocaleCategory.MESSAGES, "");
Intl.textdomain(GETTEXT_PACKAGE);
Intl.bind_textdomain_codeset(GETTEXT_PACKAGE, "utf-8");
......@@ -25,7 +28,7 @@ int main(string[] args) {
try {
bus = Bus.get_proxy_sync(BusType.SYSTEM, DBP.DBus.DAEMON_PREFIX, DBP.DBus.DAEMON_OBJECT);
} catch(Error e) {
stderr.printf (_("Error: %s\n"), e.message);
errorlog.display(e.message);
return 1;
}
......@@ -56,11 +59,13 @@ int main(string[] args) {
usage();
return 1;
}
Run.package_path = argv[0];
try {
Run.run_path(argv[0], argv[1:argv.length]);
} catch(Error e) {
stderr.printf(_("Error: %s\n"), e.message);
errorlog.display(e.message);
return 1;
}
......
......@@ -20,20 +20,17 @@ int main(string[] args) {
log_output = false,
chdir = false
};
ErrorLog errorlog;
bus = null;
errorlog = new ErrorLog(ref args);
Intl.setlocale(LocaleCategory.MESSAGES, "");
Intl.textdomain(GETTEXT_PACKAGE);
Intl.bind_textdomain_codeset(GETTEXT_PACKAGE, "utf-8");
DBP.Config.init();
try {
bus = Bus.get_proxy_sync(BusType.SYSTEM, DBP.DBus.DAEMON_PREFIX, DBP.DBus.DAEMON_OBJECT);
} catch(Error e) {
stderr.printf (_("Error: %s\n"), e.message);
return 1;
}
parse_option = true;
foreach(string s in args[1:args.length]) {
if(s.length < 1 || s[0] != '-' || s[1] != '-')
......@@ -63,15 +60,25 @@ int main(string[] args) {
}
}
try {
bus = Bus.get_proxy_sync(BusType.SYSTEM, DBP.DBus.DAEMON_PREFIX, DBP.DBus.DAEMON_OBJECT);
} catch(Error e) {
errorlog.display(e.message);
return 1;
}
if(argv.length < 2) {
usage();
return 1;
}
Run.package_id = argv[0];
try {
Run.run(argv[0], argv[1], argv[2:argv.length], config.log_output, config.chdir);
} catch(Error e) {
stderr.printf(_("Error: %s\n"), e.message);
errorlog.display(e.message);
return 1;
}
......
/* deb_dep_check.c - Steven Arnow <s@rdw.se>, 2014 */
#include <stdlib.h>
#include <string.h>
void dbp_deb_dep_check_do_init() {
}
void dbp_deb_dep_check_do_free() {
}
int dbp_deb_dep_check_check_package(const char *pkgname) {
return 1;
}
# Project: pyra-hspkg
include $(TOPDIR)/config.mk
SRCFILES = $(wildcard *.c)
OBJFILES = $(SRCFILES:.c=.o)
CFLAGS += `pkg-config --cflags glib-2.0`
LDFLAGS += `pkg-config --libs glib-2.0` -lImlib2
.PHONY: all clean
all: $(OBJFILES) $(DEPENDS)
@echo " [ LD ] $(THUMBBIN)"
@$(CC) -o $(THUMBBIN) $(OBJFILES) $(LIB) $(LDFLAGS)
@echo "Done."
@echo
clean:
@echo
@echo " [ RM ] $(OBJFILES)"
@$(RM) $(OBJFILES)
@echo "Done."
@echo
%.o: %.c %.h
@echo " [ CC ] dbp-thumbnailer/$<"
@$(CC) $(LIBINC) $(CFLAGS) -c -o $@ $<
#include <dbus/dbus.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dbp.h"
#include "thumb_queue.h"
#include "util.h"
DBusConnection *dbus_conn_handle;
void comm_dbus_unregister(DBusConnection *dc, void *n) {
(void) n;
(void) dc;
fprintf(dbp_error_log, "Unregister handler called\n");
return;
}
DBusHandlerResult comm_dbus_msg_handler(DBusConnection *dc, DBusMessage *dm, void *n) {
DBusMessage *ndm;
DBusMessageIter iter;
const char *uri;
uint32_t ret;
if (!dbus_message_iter_init(dm, &iter)) {
fprintf(dbp_error_log, "Message has no arguments\n");
return DBUS_HANDLER_RESULT_HANDLED;
}
ndm = dbus_message_new_method_return(dm);
if (dbus_message_is_method_call(dm, DBP_DBUS_THUMB_PREFIX, "Queue")) {
dbus_message_iter_get_basic(&iter, &uri);
ret = thumb_queue(uri);
dbus_message_append_args(ndm, DBUS_TYPE_UINT32, &ret, DBUS_TYPE_INVALID);
} else if (dbus_message_is_method_call(dm, DBP_DBUS_THUMB_PREFIX, "Dequeue")) {
fprintf(stderr, "STUB: %s/Dequeue()\n", DBP_DBUS_THUMB_OBJECT);
} else {
fprintf(stderr, "Unhandled method call\n");
}
dbus_connection_send(dc, ndm, NULL);
dbus_connection_flush(dc);
dbus_message_unref(ndm);