void *data,
void *userdata) {
- bool *b = data;
+ bool *b = ASSERT_PTR(data);
assert(filename);
assert(lvalue);
assert(rvalue);
- assert(data);
if (streq(rvalue, "true"))
*b = true;
void *userdata) {
_cleanup_free_ char *res = NULL;
- char **out = data;
+ char **out = ASSERT_PTR(data);
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
- assert(data);
/* XDG does not allow duplicate definitions. */
if (*out) {
const char *filename,
unsigned line,
char ***sv,
- size_t *n_allocated,
size_t *n,
const char *start,
const char *end) {
if (r < 0)
return r;
- if (!greedy_realloc((void**) sv, n_allocated, *n + 2, sizeof(char*))) /* One extra for NULL */
+ if (!GREEDY_REALLOC(*sv, *n + 2)) /* One extra for NULL */
return log_oom();
(*sv)[*n] = TAKE_PTR(copy);
void *data,
void *userdata) {
- char ***ret_sv = data;
+ char ***ret_sv = ASSERT_PTR(data);
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
- assert(data);
/* XDG does not allow duplicate definitions. */
if (*ret_sv) {
return 0;
}
- size_t n = 0, n_allocated = 0;
+ size_t n = 0;
_cleanup_strv_free_ char **sv = NULL;
- if (!GREEDY_REALLOC0(sv, n_allocated, 1))
+ if (!GREEDY_REALLOC0(sv, 1))
return log_oom();
/* We cannot use strv_split because it does not handle escaping correctly. */
if (*end == ';') {
r = strv_strndup_unescape_and_push(unit, filename, line,
- &sv, &n_allocated, &n,
+ &sv, &n,
start, end);
if (r < 0)
return r;
/* Handle the trailing entry after the last separator */
r = strv_strndup_unescape_and_push(unit, filename, line,
- &sv, &n_allocated, &n,
+ &sv, &n,
start, end);
if (r < 0)
return r;
const void *table,
const char *section,
const char *lvalue,
- ConfigParserCallback *func,
- int *ltype,
- void **data,
+ ConfigParserCallback *ret_func,
+ int *ret_ltype,
+ void **ret_data,
void *userdata) {
assert(lvalue);
/* Ignore any keys with [] as those are translations. */
if (strchr(lvalue, '[')) {
- *func = NULL;
- *ltype = 0;
- *data = NULL;
+ *ret_func = NULL;
+ *ret_ltype = 0;
+ *ret_data = NULL;
return 1;
}
- return config_item_table_lookup(table, section, lvalue, func, ltype, data, userdata);
+ return config_item_table_lookup(table, section, lvalue, ret_func, ret_ltype, ret_data, userdata);
}
XdgAutostartService *xdg_autostart_service_parse_desktop(const char *path) {
/* Common entries that we do not use currently. */
{ "Desktop Entry", "Categories", NULL, 0, NULL},
{ "Desktop Entry", "Comment", NULL, 0, NULL},
+ { "Desktop Entry", "DBusActivatable", NULL, 0, NULL},
{ "Desktop Entry", "Encoding", NULL, 0, NULL},
{ "Desktop Entry", "GenericName", NULL, 0, NULL},
{ "Desktop Entry", "Icon", NULL, 0, NULL},
first_arg = true;
for (i = n = 0; exec_split[i]; i++) {
- _cleanup_free_ char *c = NULL, *raw = NULL, *p = NULL, *escaped = NULL, *quoted = NULL;
+ _cleanup_free_ char *c = NULL, *raw = NULL, *percent = NULL;
+ ssize_t l;
- r = cunescape(exec_split[i], 0, &c);
- if (r < 0)
- return log_debug_errno(r, "Failed to unescape '%s': %m", exec_split[i]);
+ l = cunescape(exec_split[i], 0, &c);
+ if (l < 0)
+ return log_debug_errno(l, "Failed to unescape '%s': %m", exec_split[i]);
if (first_arg) {
_cleanup_free_ char *executable = NULL;
if (r < 0)
return log_info_errno(r, "Exec binary '%s' does not exist: %m", c);
- escaped = cescape(executable);
- if (!escaped)
- return log_oom();
-
- free(exec_split[n]);
- exec_split[n++] = TAKE_PTR(escaped);
+ free_and_replace(exec_split[n++], executable);
continue;
}
raw = strreplace(c, "%%", "%");
if (!raw)
return log_oom();
- p = strreplace(raw, "%", "%%");
- if (!p)
- return log_oom();
- escaped = cescape(p);
- if (!escaped)
- return log_oom();
-
- quoted = strjoin("\"", escaped, "\"");
- if (!quoted)
+ percent = strreplace(raw, "%", "%%");
+ if (!percent)
return log_oom();
- free(exec_split[n]);
- exec_split[n++] = TAKE_PTR(quoted);
+ free_and_replace(exec_split[n++], percent);
}
for (; exec_split[n]; n++)
exec_split[n] = mfree(exec_split[n]);
- res = strv_join(exec_split, " ");
+ res = quote_command_line(exec_split, SHELL_ESCAPE_EMPTY);
if (!res)
return log_oom();
}
static int xdg_autostart_generate_desktop_condition(
+ const XdgAutostartService *service,
FILE *f,
const char *test_binary,
const char *condition) {
r = find_executable(test_binary, &gnome_autostart_condition_path);
if (r < 0) {
log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
- "%s not found: %m", test_binary);
+ "%s: ExecCondition executable %s not found, unit will not be started automatically: %m",
+ service->path, test_binary);
fprintf(f, "# ExecCondition using %s skipped due to missing binary.\n", test_binary);
- return r;
+ return 0;
}
e_autostart_condition = cescape(condition);
if (!e_autostart_condition)
return log_oom();
+ log_debug("%s: ExecCondition converted to %s --condition \"%s\"%s",
+ service->path, gnome_autostart_condition_path, e_autostart_condition,
+ special_glyph(SPECIAL_GLYPH_ELLIPSIS));
+
fprintf(f,
"ExecCondition=%s --condition \"%s\"\n",
gnome_autostart_condition_path,
}
int xdg_autostart_service_generate_unit(
- XdgAutostartService *service,
+ const XdgAutostartService *service,
const char *dest) {
_cleanup_free_ char *path_escaped = NULL, *exec_start = NULL, *unit = NULL;
/* Nothing to do for hidden services. */
if (service->hidden) {
- log_debug("Not generating service for XDG autostart %s, it is hidden.", service->name);
+ log_debug("%s: not generating unit, entry is hidden.", service->path);
return 0;
}
if (service->systemd_skip) {
- log_debug("Not generating service for XDG autostart %s, should be skipped by generator.", service->name);
+ log_debug("%s: not generating unit, marked as skipped by generator.", service->path);
return 0;
}
/* Nothing to do if type is not Application. */
if (!streq_ptr(service->type, "Application")) {
- log_debug("Not generating service for XDG autostart %s, only Type=Application is supported.", service->name);
+ log_debug("%s: not generating unit, Type=%s is not supported.", service->path, service->type);
return 0;
}
if (!service->exec_string) {
- log_warning("Not generating service for XDG autostart %s, it is has no Exec= line.", service->name);
+ log_warning("%s: not generating unit, no Exec= line.", service->path);
return 0;
}
r = find_executable(service->try_exec, NULL);
if (r < 0) {
log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
- "Not generating service for XDG autostart %s, could not find TryExec= binary %s: %m",
- service->name, service->try_exec);
+ "%s: not generating unit, could not find TryExec= binary %s: %m",
+ service->path, service->try_exec);
return 0;
}
}
r = xdg_autostart_format_exec_start(service->exec_string, &exec_start);
if (r < 0) {
- log_warning_errno(r,
- "Not generating service for XDG autostart %s, error parsing Exec= line: %m",
- service->name);
+ log_warning_errno(r, "%s: not generating unit, error parsing Exec= line: %m", service->path);
return 0;
}
if (service->gnome_autostart_phase) {
/* There is no explicit value for the "Application" phase. */
- log_debug("Not generating service for XDG autostart %s, startup phases are not supported.",
- service->name);
+ log_debug("%s: not generating unit, startup phases are not supported.", service->path);
return 0;
}
f = fopen(unit, "wxe");
if (!f)
- return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
+ return log_error_errno(errno, "%s: failed to create unit file %s: %m", service->path, unit);
fprintf(f,
"# Automatically generated by systemd-xdg-autostart-generator\n\n"
fprintf(f,
"\n[Service]\n"
"Type=exec\n"
+ "ExitType=cgroup\n"
"ExecStart=:%s\n"
"Restart=no\n"
"TimeoutSec=5s\n"
e_not_show_in);
}
- r = xdg_autostart_generate_desktop_condition(f,
+ r = xdg_autostart_generate_desktop_condition(service, f,
"gnome-systemd-autostart-condition",
service->autostart_condition);
if (r < 0)
return r;
- r = xdg_autostart_generate_desktop_condition(f,
+ r = xdg_autostart_generate_desktop_condition(service, f,
"kde-systemd-start-condition",
service->kde_autostart_condition);
if (r < 0)
return r;
- (void) generator_add_symlink(dest, "xdg-desktop-autostart.target", "wants", service->name);
-
- return 0;
+ log_debug("%s: symlinking %s in xdg-desktop-autostart.target/.wants%s",
+ service->path, service->name, special_glyph(SPECIAL_GLYPH_ELLIPSIS));
+ return generator_add_symlink(dest, "xdg-desktop-autostart.target", "wants", service->name);
}