+static void service_notify_message(Unit *u, pid_t pid, char **tags) {
+ Service *s = SERVICE(u);
+ const char *e;
+
+ assert(u);
+
+ if (s->notify_access == NOTIFY_NONE) {
+ log_warning("%s: Got notification message from PID %lu, but reception is disabled.",
+ u->meta.id, (unsigned long) pid);
+ return;
+ }
+
+ if (s->notify_access == NOTIFY_MAIN && pid != s->main_pid) {
+ log_warning("%s: Got notification message from PID %lu, but reception only permitted for PID %lu",
+ u->meta.id, (unsigned long) pid, (unsigned long) s->main_pid);
+ return;
+ }
+
+ log_debug("%s: Got message", u->meta.id);
+
+ /* Interpret MAINPID= */
+ if ((e = strv_find_prefix(tags, "MAINPID=")) &&
+ (s->state == SERVICE_START ||
+ s->state == SERVICE_START_POST ||
+ s->state == SERVICE_RUNNING ||
+ s->state == SERVICE_RELOAD)) {
+
+ if (parse_pid(e + 8, &pid) < 0)
+ log_warning("Failed to parse notification message %s", e);
+ else {
+ log_debug("%s: got %s", u->meta.id, e);
+ service_set_main_pid(s, pid);
+ }
+ }
+
+ /* Interpret READY= */
+ if (s->type == SERVICE_NOTIFY &&
+ s->state == SERVICE_START &&
+ strv_find(tags, "READY=1")) {
+ log_debug("%s: got READY=1", u->meta.id);
+
+ service_enter_start_post(s);
+ }
+
+ /* Interpret STATUS= */
+ if ((e = strv_find_prefix(tags, "STATUS="))) {
+ char *t;
+
+ if (e[7]) {
+ if (!(t = strdup(e+7))) {
+ log_error("Failed to allocate string.");
+ return;
+ }
+
+ log_debug("%s: got %s", u->meta.id, e);
+
+ free(s->status_text);
+ s->status_text = t;
+ } else {
+ free(s->status_text);
+ s->status_text = NULL;
+ }
+
+ }
+
+ /* Notify clients about changed status or main pid */
+ unit_add_to_dbus_queue(u);
+}
+
+#ifdef HAVE_SYSV_COMPAT
+
+#ifdef TARGET_SUSE
+static void sysv_facility_in_insserv_conf(Manager *mgr) {
+ FILE *f=NULL;
+ int r;
+
+ if (!(f = fopen("/etc/insserv.conf", "re"))) {
+ r = errno == ENOENT ? 0 : -errno;
+ goto finish;
+ }
+
+ while (!feof(f)) {
+ char l[LINE_MAX], *t;
+ char **parsed = NULL;
+
+ if (!fgets(l, sizeof(l), f)) {
+ if (feof(f))
+ break;
+
+ r = -errno;
+ log_error("Failed to read configuration file '/etc/insserv.conf': %s", strerror(-r));
+ goto finish;
+ }
+
+ t = strstrip(l);
+ if (*t != '$' && *t != '<')
+ continue;
+
+ parsed = strv_split(t,WHITESPACE);
+ /* we ignore <interactive>, not used, equivalent to X-Interactive */
+ if (parsed && !startswith_no_case (parsed[0], "<interactive>")) {
+ char *facility;
+ Unit *u;
+ if (sysv_translate_facility(parsed[0], NULL, &facility) < 0)
+ continue;
+ if ((u = manager_get_unit(mgr, facility)) && (u->meta.type == UNIT_TARGET)) {
+ UnitDependency e;
+ char *dep = NULL, *name, **j;
+
+ STRV_FOREACH (j, parsed+1) {
+ if (*j[0]=='+') {
+ e = UNIT_WANTS;
+ name = *j+1;
+ }
+ else {
+ e = UNIT_REQUIRES;
+ name = *j;
+ }
+ if (sysv_translate_facility(name, NULL, &dep) < 0)
+ continue;
+
+ r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, e, dep, NULL, true);
+ free(dep);
+ }
+ }
+ free(facility);
+ }
+ strv_free(parsed);
+ }
+finish:
+ if (f)
+ fclose(f);
+
+}
+#endif
+