diff options
Diffstat (limited to 'src/librc-daemon.c')
| -rw-r--r-- | src/librc-daemon.c | 974 | 
1 files changed, 462 insertions, 512 deletions
diff --git a/src/librc-daemon.c b/src/librc-daemon.c index 3add7e4c..240ca6ed 100644 --- a/src/librc-daemon.c +++ b/src/librc-daemon.c @@ -9,7 +9,7 @@  #include <sys/stat.h>  #if defined(__DragonFly__) || defined(__FreeBSD__) || \ - defined(__NetBSD__) || defined (__OpenBSD__) +	defined(__NetBSD__) || defined (__OpenBSD__)  #include <sys/param.h>  #include <sys/user.h>  #include <sys/sysctl.h> @@ -37,150 +37,143 @@  #if defined(__linux__)  static bool pid_is_cmd (pid_t pid, const char *cmd)  { -  char buffer[32]; -  FILE *fp; -  int c; +	char buffer[32]; +	FILE *fp; +	int c; -  snprintf(buffer, sizeof (buffer), "/proc/%d/stat", pid); -  if ((fp = fopen (buffer, "r")) == NULL) -    return (false); +	snprintf(buffer, sizeof (buffer), "/proc/%d/stat", pid); +	if ((fp = fopen (buffer, "r")) == NULL) +		return (false); -  while ((c = getc (fp)) != EOF && c != '(') -    ; +	while ((c = getc (fp)) != EOF && c != '(') +		; -  if (c != '(') -    { -      fclose(fp); -      return (false); -    } +	if (c != '(') { +		fclose(fp); +		return (false); +	} -  while ((c = getc (fp)) != EOF && c == *cmd) -    cmd++; +	while ((c = getc (fp)) != EOF && c == *cmd) +		cmd++; -  fclose (fp); +	fclose (fp); -  return ((c == ')' && *cmd == '\0') ? true : false); +	return ((c == ')' && *cmd == '\0') ? true : false);  }  static bool pid_is_exec (pid_t pid, const char *exec)  { -  char cmdline[32]; -  char buffer[PATH_MAX]; -  char *p; -  int fd = -1; -  int r; - -  snprintf (cmdline, sizeof (cmdline), "/proc/%u/exe", pid); -  memset (buffer, 0, sizeof (buffer)); -  if (readlink (cmdline, buffer, sizeof (buffer)) != -1) -    { -      if (strcmp (exec, buffer) == 0) -        return (true); - -      /* We should cater for deleted binaries too */ -      if (strlen (buffer) > 10) -        { -          p = buffer + (strlen (buffer) - 10); -          if (strcmp (p, " (deleted)") == 0) -            { -              *p = 0; -              if (strcmp (buffer, exec) == 0) -                return (true); -            } -        } -    } - -  snprintf (cmdline, sizeof (cmdline), "/proc/%u/cmdline", pid); -  if ((fd = open (cmdline, O_RDONLY)) < 0) -    return (false); - -  r = read(fd, buffer, sizeof (buffer)); -  close (fd); - -  if (r == -1) -    return 0; - -  buffer[r] = 0; -  return (strcmp (exec, buffer) == 0 ? true : false); +	char cmdline[32]; +	char buffer[PATH_MAX]; +	char *p; +	int fd = -1; +	int r; + +	snprintf (cmdline, sizeof (cmdline), "/proc/%u/exe", pid); +	memset (buffer, 0, sizeof (buffer)); +	if (readlink (cmdline, buffer, sizeof (buffer)) != -1) { +		if (strcmp (exec, buffer) == 0) +			return (true); + +		/* We should cater for deleted binaries too */ +		if (strlen (buffer) > 10) { +			p = buffer + (strlen (buffer) - 10); +			if (strcmp (p, " (deleted)") == 0) { +				*p = 0; +				if (strcmp (buffer, exec) == 0) +					return (true); +			} +		} +	} + +	snprintf (cmdline, sizeof (cmdline), "/proc/%u/cmdline", pid); +	if ((fd = open (cmdline, O_RDONLY)) < 0) +		return (false); + +	r = read(fd, buffer, sizeof (buffer)); +	close (fd); + +	if (r == -1) +		return 0; + +	buffer[r] = 0; +	return (strcmp (exec, buffer) == 0 ? true : false);  }  pid_t *rc_find_pids (const char *exec, const char *cmd, -                     uid_t uid, pid_t pid) +					 uid_t uid, pid_t pid)  { -  DIR *procdir; -  struct dirent *entry; -  int npids = 0; -  int foundany = false; -  pid_t p; -  pid_t *pids = NULL; -  char buffer[PATH_MAX]; -  struct stat sb; -  pid_t runscript_pid = 0; -  char *pp; - -  if ((procdir = opendir ("/proc")) == NULL) -    eerrorx ("opendir `/proc': %s", strerror (errno)); - -  /* -     We never match RC_RUNSCRIPT_PID if present so we avoid the below -     scenario - -     /etc/init.d/ntpd stop does -     start-stop-daemon --stop --name ntpd -     catching /etc/init.d/ntpd stop - -     nasty -     */ - -  if ((pp = getenv ("RC_RUNSCRIPT_PID"))) -    { -      if (sscanf (pp, "%d", &runscript_pid) != 1) -        runscript_pid = 0; -    } - -  while ((entry = readdir (procdir)) != NULL) -    { -      if (sscanf (entry->d_name, "%d", &p) != 1) -        continue; -      foundany = true; - -      if (runscript_pid != 0 && runscript_pid == p) -        continue; - -      if (pid != 0 && pid != p) -        continue; - -      if (uid) -        { -          snprintf (buffer, sizeof (buffer), "/proc/%d", pid); -          if (stat (buffer, &sb) != 0 || sb.st_uid != uid) -            continue; -        } - -      if (cmd && ! pid_is_cmd (p, cmd)) -        continue; - -      if (exec && ! cmd && ! pid_is_exec (p, exec)) -        continue; - -      pids = realloc (pids, sizeof (pid_t) * (npids + 2)); -      if (! pids) -        eerrorx ("memory exhausted"); - -      pids[npids] = p; -      pids[npids + 1] = 0; -      npids++; -    } -  closedir (procdir); - -  if (! foundany) -    eerrorx ("nothing in /proc"); - -  return (pids); +	DIR *procdir; +	struct dirent *entry; +	int npids = 0; +	int foundany = false; +	pid_t p; +	pid_t *pids = NULL; +	char buffer[PATH_MAX]; +	struct stat sb; +	pid_t runscript_pid = 0; +	char *pp; + +	if ((procdir = opendir ("/proc")) == NULL) +		eerrorx ("opendir `/proc': %s", strerror (errno)); + +	/* +	   We never match RC_RUNSCRIPT_PID if present so we avoid the below +	   scenario + +	   /etc/init.d/ntpd stop does +	   start-stop-daemon --stop --name ntpd +	   catching /etc/init.d/ntpd stop + +	   nasty +	   */ + +	if ((pp = getenv ("RC_RUNSCRIPT_PID"))) { +		if (sscanf (pp, "%d", &runscript_pid) != 1) +			runscript_pid = 0; +	} + +	while ((entry = readdir (procdir)) != NULL) { +		if (sscanf (entry->d_name, "%d", &p) != 1) +			continue; +		foundany = true; + +		if (runscript_pid != 0 && runscript_pid == p) +			continue; + +		if (pid != 0 && pid != p) +			continue; + +		if (uid) { +			snprintf (buffer, sizeof (buffer), "/proc/%d", pid); +			if (stat (buffer, &sb) != 0 || sb.st_uid != uid) +				continue; +		} + +		if (cmd && ! pid_is_cmd (p, cmd)) +			continue; + +		if (exec && ! cmd && ! pid_is_exec (p, exec)) +			continue; + +		pids = realloc (pids, sizeof (pid_t) * (npids + 2)); +		if (! pids) +			eerrorx ("memory exhausted"); + +		pids[npids] = p; +		pids[npids + 1] = 0; +		npids++; +	} +	closedir (procdir); + +	if (! foundany) +		eerrorx ("nothing in /proc"); + +	return (pids);  }  #elif defined(__DragonFly__) || defined(__FreeBSD__) || \ - defined(__NetBSD__) || defined(__OpenBSD__) +	defined(__NetBSD__) || defined(__OpenBSD__)  # if defined(__DragonFly__) || defined(__FreeBSD__)  #  ifndef KERN_PROC_PROC @@ -200,63 +193,60 @@ pid_t *rc_find_pids (const char *exec, const char *cmd,  # endif  pid_t *rc_find_pids (const char *exec, const char *cmd, -                     uid_t uid, pid_t pid) +					 uid_t uid, pid_t pid)  { -  static kvm_t *kd = NULL; -  char errbuf[_POSIX2_LINE_MAX]; -  struct _KINFO_PROC *kp; -  int i; -  int processes = 0; -  int argc = 0; -  char **argv; -  pid_t *pids = NULL; -  int npids = 0; - -  if ((kd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, errbuf)) == NULL) -    eerrorx ("kvm_open: %s", errbuf); +	static kvm_t *kd = NULL; +	char errbuf[_POSIX2_LINE_MAX]; +	struct _KINFO_PROC *kp; +	int i; +	int processes = 0; +	int argc = 0; +	char **argv; +	pid_t *pids = NULL; +	int npids = 0; + +	if ((kd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, errbuf)) == NULL) +		eerrorx ("kvm_open: %s", errbuf);  #if defined(__DragonFly__) || defined( __FreeBSD__) -  kp = kvm_getprocs (kd, KERN_PROC_PROC, 0, &processes); +	kp = kvm_getprocs (kd, KERN_PROC_PROC, 0, &processes);  #else -  kp = kvm_getproc2 (kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), -                     &processes); +	kp = kvm_getproc2 (kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), +					   &processes);  #endif -  for (i = 0; i < processes; i++) -    { -      pid_t p = _GET_KINFO_PID (kp[i]); -      if (pid != 0 && pid != p) -        continue; - -      if (uid != 0 && uid != _GET_KINFO_UID (kp[i])) -        continue; - -      if (cmd) -        { -          if (! _GET_KINFO_COMM (kp[i]) || -              strcmp (cmd, _GET_KINFO_COMM (kp[i])) != 0) -            continue; -        } - -      if (exec && ! cmd) -        { -          if ((argv = _KVM_GETARGV (kd, &kp[i], argc)) == NULL || ! *argv) -            continue; - -          if (strcmp (*argv, exec) != 0)  -            continue; -        } - -      pids = realloc (pids, sizeof (pid_t) * (npids + 2)); -      if (! pids) -        eerrorx ("memory exhausted"); - -      pids[npids] = p; -      pids[npids + 1] = 0; -      npids++; -    } -  kvm_close(kd); - -  return (pids); +	for (i = 0; i < processes; i++) { +		pid_t p = _GET_KINFO_PID (kp[i]); +		if (pid != 0 && pid != p) +			continue; + +		if (uid != 0 && uid != _GET_KINFO_UID (kp[i])) +			continue; + +		if (cmd) { +			if (! _GET_KINFO_COMM (kp[i]) || +				strcmp (cmd, _GET_KINFO_COMM (kp[i])) != 0) +				continue; +		} + +		if (exec && ! cmd) { +			if ((argv = _KVM_GETARGV (kd, &kp[i], argc)) == NULL || ! *argv) +				continue; + +			if (strcmp (*argv, exec) != 0)  +				continue; +		} + +		pids = realloc (pids, sizeof (pid_t) * (npids + 2)); +		if (! pids) +			eerrorx ("memory exhausted"); + +		pids[npids] = p; +		pids[npids + 1] = 0; +		npids++; +	} +	kvm_close(kd); + +	return (pids);  }  #else @@ -264,349 +254,309 @@ pid_t *rc_find_pids (const char *exec, const char *cmd,  #endif  static bool _match_daemon (const char *path, const char *file, -                           const char *mexec, const char *mname, -                           const char *mpidfile) +						   const char *mexec, const char *mname, +						   const char *mpidfile)  { -  char buffer[RC_LINEBUFFER]; -  char *ffile = rc_strcatpaths (path, file, (char *) NULL); -  FILE *fp; -  int lc = 0; -  int m = 0; - -  if (! rc_exists (ffile)) -    { -      free (ffile); -      return (false); -    } - -  if ((fp = fopen (ffile, "r")) == NULL) -    { -      eerror ("fopen `%s': %s", ffile, strerror (errno)); -      free (ffile); -      return (false); -    } - -  if (! mname) -    m += 10; -  if (! mpidfile) -    m += 100; - -  memset (buffer, 0, sizeof (buffer)); -  while ((fgets (buffer, RC_LINEBUFFER, fp))) -    { -      int lb = strlen (buffer) - 1; -      if (buffer[lb] == '\n') -        buffer[lb] = 0; - -      if (strcmp (buffer, mexec) == 0) -        m += 1; -      else if (mname && strcmp (buffer, mname) == 0) -        m += 10; -      else if (mpidfile && strcmp (buffer, mpidfile) == 0) -        m += 100; - -      if (m == 111) -        break; - -      lc++; -      if (lc > 5) -        break; -    } -  fclose (fp); -  free (ffile); - -  return (m == 111 ? true : false); +	char buffer[RC_LINEBUFFER]; +	char *ffile = rc_strcatpaths (path, file, (char *) NULL); +	FILE *fp; +	int lc = 0; +	int m = 0; + +	if (! rc_exists (ffile)) { +		free (ffile); +		return (false); +	} + +	if ((fp = fopen (ffile, "r")) == NULL) { +		eerror ("fopen `%s': %s", ffile, strerror (errno)); +		free (ffile); +		return (false); +	} + +	if (! mname) +		m += 10; +	if (! mpidfile) +		m += 100; + +	memset (buffer, 0, sizeof (buffer)); +	while ((fgets (buffer, RC_LINEBUFFER, fp))) { +		int lb = strlen (buffer) - 1; +		if (buffer[lb] == '\n') +			buffer[lb] = 0; + +		if (strcmp (buffer, mexec) == 0) +			m += 1; +		else if (mname && strcmp (buffer, mname) == 0) +			m += 10; +		else if (mpidfile && strcmp (buffer, mpidfile) == 0) +			m += 100; + +		if (m == 111) +			break; + +		lc++; +		if (lc > 5) +			break; +	} +	fclose (fp); +	free (ffile); + +	return (m == 111 ? true : false);  }  void rc_set_service_daemon (const char *service, const char *exec, -                            const char *name, const char *pidfile, -                            bool started) +							const char *name, const char *pidfile, +							bool started)  { -  char *dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename (service), -                                  (char *) NULL); -  char **files = NULL; -  char *file; -  char *ffile = NULL; -  int i; -  char *mexec; -  char *mname; -  char *mpidfile; -  int nfiles = 0; - -  if (! exec && ! name && ! pidfile) -    return; - -  if (exec) -    { -      i = strlen (exec) + 6; -      mexec = rc_xmalloc (sizeof (char *) * i); -      snprintf (mexec, i, "exec=%s", exec); -    } -  else -    mexec = strdup ("exec="); - -  if (name) -    { -      i = strlen (name) + 6; -      mname = rc_xmalloc (sizeof (char *) * i); -      snprintf (mname, i, "name=%s", name); -    } -  else -    mname = strdup ("name="); - -  if (pidfile) -    { -      i = strlen (pidfile) + 9; -      mpidfile = rc_xmalloc (sizeof (char *) * i); -      snprintf (mpidfile, i, "pidfile=%s", pidfile); -    } -  else -    mpidfile = strdup ("pidfile="); - -  /* Regardless, erase any existing daemon info */ -  if (rc_is_dir (dirpath)) -    { -      char *oldfile = NULL; -      files = rc_ls_dir (NULL, dirpath, 0); -      STRLIST_FOREACH (files, file, i) -        { -          ffile = rc_strcatpaths (dirpath, file, (char *) NULL); -          nfiles++; - -          if (! oldfile) -            { -              if (_match_daemon (dirpath, file, mexec, mname, mpidfile)) -                { -                  unlink (ffile); -                  oldfile = ffile; -                  nfiles--; -                } -            } -          else -            { -              rename (ffile, oldfile); -              free (oldfile); -              oldfile = ffile; -            } -        } -      if (ffile) -        free (ffile);  -      free (files); -    } - -  /* Now store our daemon info */ -  if (started) -    { -      char buffer[10]; -      FILE *fp; - -      if (! rc_is_dir (dirpath)) -        if (mkdir (dirpath, 0755) != 0) -          eerror ("mkdir `%s': %s", dirpath, strerror (errno)); - -      snprintf (buffer, sizeof (buffer), "%03d", nfiles + 1); -      file = rc_strcatpaths (dirpath, buffer, (char *) NULL); -      if ((fp = fopen (file, "w")) == NULL) -        eerror ("fopen `%s': %s", file, strerror (errno)); -      else -        { -          fprintf (fp, "%s\n%s\n%s\n", mexec, mname, mpidfile); -          fclose (fp); -        } -      free (file); -    } - -  free (mexec); -  free (mname); -  free (mpidfile); -  free (dirpath); +	char *dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename (service), +									(char *) NULL); +	char **files = NULL; +	char *file; +	char *ffile = NULL; +	int i; +	char *mexec; +	char *mname; +	char *mpidfile; +	int nfiles = 0; + +	if (! exec && ! name && ! pidfile) +		return; + +	if (exec) { +		i = strlen (exec) + 6; +		mexec = rc_xmalloc (sizeof (char *) * i); +		snprintf (mexec, i, "exec=%s", exec); +	} else +		mexec = strdup ("exec="); + +	if (name) { +		i = strlen (name) + 6; +		mname = rc_xmalloc (sizeof (char *) * i); +		snprintf (mname, i, "name=%s", name); +	} else +		mname = strdup ("name="); + +	if (pidfile) { +		i = strlen (pidfile) + 9; +		mpidfile = rc_xmalloc (sizeof (char *) * i); +		snprintf (mpidfile, i, "pidfile=%s", pidfile); +	} else +		mpidfile = strdup ("pidfile="); + +	/* Regardless, erase any existing daemon info */ +	if (rc_is_dir (dirpath)) { +		char *oldfile = NULL; +		files = rc_ls_dir (NULL, dirpath, 0); +		STRLIST_FOREACH (files, file, i) { +			ffile = rc_strcatpaths (dirpath, file, (char *) NULL); +			nfiles++; + +			if (! oldfile) { +				if (_match_daemon (dirpath, file, mexec, mname, mpidfile)) { +					unlink (ffile); +					oldfile = ffile; +					nfiles--; +				} +			} else { +				rename (ffile, oldfile); +				free (oldfile); +				oldfile = ffile; +			} +		} +		if (ffile) +			free (ffile);  +		free (files); +	} + +	/* Now store our daemon info */ +	if (started) { +		char buffer[10]; +		FILE *fp; + +		if (! rc_is_dir (dirpath)) +			if (mkdir (dirpath, 0755) != 0) +				eerror ("mkdir `%s': %s", dirpath, strerror (errno)); + +		snprintf (buffer, sizeof (buffer), "%03d", nfiles + 1); +		file = rc_strcatpaths (dirpath, buffer, (char *) NULL); +		if ((fp = fopen (file, "w")) == NULL) +			eerror ("fopen `%s': %s", file, strerror (errno)); +		else { +			fprintf (fp, "%s\n%s\n%s\n", mexec, mname, mpidfile); +			fclose (fp); +		} +		free (file); +	} + +	free (mexec); +	free (mname); +	free (mpidfile); +	free (dirpath);  }  bool rc_service_started_daemon (const char *service, const char *exec, -                                int indx) +								int indx)  { -  char *dirpath; -  char *file; -  int i; -  char *mexec; -  bool retval = false; - -  if (! service || ! exec) -    return (false); - -  dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename (service), -                            (char *) NULL); -  if (! rc_is_dir (dirpath)) -    { -      free (dirpath); -      return (false); -    } - -  i = strlen (exec) + 6; -  mexec = rc_xmalloc (sizeof (char *) * i); -  snprintf (mexec, i, "exec=%s", exec); - -  if (indx > 0) -    { -      int len = sizeof (char *) * 10; -      file = rc_xmalloc (len); -      snprintf (file, len, "%03d", indx); -      retval = _match_daemon (dirpath, file, mexec, NULL, NULL); -      free (file); -    } -  else -    { -      char **files = rc_ls_dir (NULL, dirpath, 0); -      STRLIST_FOREACH (files, file, i) -        { -          retval = _match_daemon (dirpath, file, mexec, NULL, NULL); -          if (retval) -            break; -        } -      free (files); -    } - -  free (mexec); -  return (retval); +	char *dirpath; +	char *file; +	int i; +	char *mexec; +	bool retval = false; + +	if (! service || ! exec) +		return (false); + +	dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename (service), +							  (char *) NULL); +	if (! rc_is_dir (dirpath)) { +		free (dirpath); +		return (false); +	} + +	i = strlen (exec) + 6; +	mexec = rc_xmalloc (sizeof (char *) * i); +	snprintf (mexec, i, "exec=%s", exec); + +	if (indx > 0) { +		int len = sizeof (char *) * 10; +		file = rc_xmalloc (len); +		snprintf (file, len, "%03d", indx); +		retval = _match_daemon (dirpath, file, mexec, NULL, NULL); +		free (file); +	} else { +		char **files = rc_ls_dir (NULL, dirpath, 0); +		STRLIST_FOREACH (files, file, i) { +			retval = _match_daemon (dirpath, file, mexec, NULL, NULL); +			if (retval) +				break; +		} +		free (files); +	} + +	free (mexec); +	return (retval);  }  bool rc_service_daemons_crashed (const char *service)  { -  char *dirpath; -  char **files; -  char *file; -  char *path; -  int i; -  FILE *fp; -  char buffer[RC_LINEBUFFER]; -  char *exec = NULL; -  char *name = NULL; -  char *pidfile = NULL; -  pid_t pid = 0; -  pid_t *pids = NULL; -  char *p; -  char *token; -  bool retval = false; - -  if (! service) -    return (false); - -  dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename (service), -                            (char *) NULL); -  if (! rc_is_dir (dirpath)) -    { -      free (dirpath); -      return (false); -    } - -  memset (buffer, 0, sizeof (buffer)); -  files = rc_ls_dir (NULL, dirpath, 0); -  STRLIST_FOREACH (files, file, i) -    { -      path = rc_strcatpaths (dirpath, file, (char *) NULL); -      fp = fopen (path, "r"); -      free (path); -      if (! fp) -        { -          eerror ("fopen `%s': %s", file, strerror (errno)); -          continue; -        } - -      while ((fgets (buffer, RC_LINEBUFFER, fp))) -        { -          int lb = strlen (buffer) - 1; -          if (buffer[lb] == '\n') -            buffer[lb] = 0; - -          p = buffer; -          if ((token = strsep (&p, "=")) == NULL || ! p) -            continue; - -          if (strlen (p) == 0) -            continue; - -          if (strcmp (token, "exec") == 0) -            { -              if (exec) -                free (exec); -              exec = strdup (p); -            } -          else if (strcmp (token, "name") == 0) -            { -              if (name) -                free (name); -              name = strdup (p); -            } -          else if (strcmp (token, "pidfile") == 0) -            { -              if (pidfile) -                free (pidfile); -              pidfile = strdup (p); -            } -        } -      fclose (fp); - -      pid = 0; -      if (pidfile) -        { -          if (! rc_exists (pidfile)) -            { -              retval = true; -              break; -            } - -          if ((fp = fopen (pidfile, "r")) == NULL) -            { -              eerror ("fopen `%s': %s", pidfile, strerror (errno)); -              retval = true; -              break; -            } - -          if (fscanf (fp, "%d", &pid) != 1) -            { -              eerror ("no pid found in `%s'", pidfile); -              fclose (fp); -              retval = true; -              break; -            } - -          fclose (fp); -          free (pidfile); -          pidfile = NULL; -        } - -      if ((pids = rc_find_pids (exec, name, 0, pid)) == NULL) -        { -          retval = true; -          break; -        } -      free (pids); - -      if (exec) -        { -          free (exec); -          exec = NULL; -        } -      if (name) -        { -          free (name); -          name = NULL; -        } -    } - -  if (exec) -    { -      free (exec); -      exec = NULL; -    } -  if (name) -    { -      free (name); -      name = NULL; -    } - -  free (dirpath); -  rc_strlist_free (files); - -  return (retval); +	char *dirpath; +	char **files; +	char *file; +	char *path; +	int i; +	FILE *fp; +	char buffer[RC_LINEBUFFER]; +	char *exec = NULL; +	char *name = NULL; +	char *pidfile = NULL; +	pid_t pid = 0; +	pid_t *pids = NULL; +	char *p; +	char *token; +	bool retval = false; + +	if (! service) +		return (false); + +	dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename (service), +							  (char *) NULL); +	if (! rc_is_dir (dirpath)) { +		free (dirpath); +		return (false); +	} + +	memset (buffer, 0, sizeof (buffer)); +	files = rc_ls_dir (NULL, dirpath, 0); +	STRLIST_FOREACH (files, file, i) { +		path = rc_strcatpaths (dirpath, file, (char *) NULL); +		fp = fopen (path, "r"); +		free (path); +		if (! fp) { +			eerror ("fopen `%s': %s", file, strerror (errno)); +			continue; +		} + +		while ((fgets (buffer, RC_LINEBUFFER, fp))) { +			int lb = strlen (buffer) - 1; +			if (buffer[lb] == '\n') +				buffer[lb] = 0; + +			p = buffer; +			if ((token = strsep (&p, "=")) == NULL || ! p) +				continue; + +			if (strlen (p) == 0) +				continue; + +			if (strcmp (token, "exec") == 0) { +				if (exec) +					free (exec); +				exec = strdup (p); +			} else if (strcmp (token, "name") == 0) { +				if (name) +					free (name); +				name = strdup (p); +			} else if (strcmp (token, "pidfile") == 0) { +				if (pidfile) +					free (pidfile); +				pidfile = strdup (p); +			} +		} +		fclose (fp); + +		pid = 0; +		if (pidfile) { +			if (! rc_exists (pidfile)) { +				retval = true; +				break; +			} + +			if ((fp = fopen (pidfile, "r")) == NULL) { +				eerror ("fopen `%s': %s", pidfile, strerror (errno)); +				retval = true; +				break; +			} + +			if (fscanf (fp, "%d", &pid) != 1) { +				eerror ("no pid found in `%s'", pidfile); +				fclose (fp); +				retval = true; +				break; +			} + +			fclose (fp); +			free (pidfile); +			pidfile = NULL; +		} + +		if ((pids = rc_find_pids (exec, name, 0, pid)) == NULL) { +			retval = true; +			break; +		} +		free (pids); + +		if (exec) { +			free (exec); +			exec = NULL; +		} +		if (name) { +			free (name); +			name = NULL; +		} +	} + +	if (exec) { +		free (exec); +		exec = NULL; +	} +	if (name) { +		free (name); +		name = NULL; +	} + +	free (dirpath); +	rc_strlist_free (files); + +	return (retval);  }  | 
