summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/Makefile2
-rw-r--r--man/einfo.34
-rw-r--r--man/rc_config.310
-rw-r--r--man/rc_deptree.325
-rw-r--r--man/rc_plugin_hook.34
-rw-r--r--man/rc_runlevel.313
-rw-r--r--man/rc_service.325
-rw-r--r--man/rc_strlist.3104
-rw-r--r--src/includes/rc-misc.h73
-rw-r--r--src/includes/strlist.h48
-rw-r--r--src/libeinfo/einfo.h74
-rw-r--r--src/libeinfo/libeinfo.c650
-rw-r--r--src/librc/.gitignore4
-rw-r--r--src/librc/Makefile2
-rw-r--r--src/librc/librc-daemon.c438
-rw-r--r--src/librc/librc-depend.c1012
-rw-r--r--src/librc/librc-depend.h61
-rw-r--r--src/librc/librc-misc.c123
-rw-r--r--src/librc/librc-strlist.c230
-rw-r--r--src/librc/librc.c843
-rw-r--r--src/librc/librc.h16
-rw-r--r--src/librc/rc.h200
-rw-r--r--src/librc/rc.map15
-rw-r--r--src/rc/.gitignore4
-rw-r--r--src/rc/Makefile9
-rw-r--r--src/rc/_usage.c33
-rw-r--r--src/rc/builtins.h2
-rw-r--r--src/rc/checkpath.c129
-rw-r--r--src/rc/fstabinfo.c211
-rw-r--r--src/rc/mountinfo.c351
-rw-r--r--src/rc/rc-applets.c453
-rw-r--r--src/rc/rc-depend.c166
-rw-r--r--src/rc/rc-logger.c255
-rw-r--r--src/rc/rc-misc.c380
-rw-r--r--src/rc/rc-plugin.c183
-rw-r--r--src/rc/rc-plugin.h10
-rw-r--r--src/rc/rc-status.c200
-rw-r--r--src/rc/rc-update.c153
-rw-r--r--src/rc/rc.c1230
-rw-r--r--src/rc/runscript.c1263
-rw-r--r--src/rc/start-stop-daemon.c973
41 files changed, 4667 insertions, 5314 deletions
diff --git a/man/Makefile b/man/Makefile
index f6ffd69..f8c8ded 100644
--- a/man/Makefile
+++ b/man/Makefile
@@ -1,6 +1,6 @@
MAN3= einfo.3 \
rc_config.3 rc_deptree.3 rc_find_pids.3 rc_plugin_hook.3 \
- rc_runlevel.3 rc_service.3 rc_strcatpaths.3 rc_strlist.3
+ rc_runlevel.3 rc_service.3 rc_strcatpaths.3 rc_stringlist.3
MAN8= rc-status.8 rc-update.8 rc.8 runscript.8 start-stop-daemon.8
# Handy macro to create symlinks
diff --git a/man/einfo.3 b/man/einfo.3
index 327ae35..5f1b96b 100644
--- a/man/einfo.3
+++ b/man/einfo.3
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd Feb 22, 2008
+.Dd Mar 16, 2008
.Dt EINFO 3 SMM
.Os OpenRC
.Sh NAME
@@ -62,7 +62,7 @@ Enhanced Informatation output library (libeinfo, -leinfo)
.Ft int Fn ewend "int retval" "const char * restrict format" ...
.Ft int Fn eendv "int retval" "const char * restrict format" ...
.Ft int Fn ewendv "int retval" "const char * restrict format" ...
-.Ft void Fn ebracket "int col" "einfo_color_t color" "const char * restrict msg"
+.Ft void Fn ebracket "int col" "ECOLOR color" "const char * restrict msg"
.Ft void Fn eindent void
.Ft void Fn eoutdent void
.Ft void Fn eindentv void
diff --git a/man/rc_config.3 b/man/rc_config.3
index 9a5bfcd..f420d43 100644
--- a/man/rc_config.3
+++ b/man/rc_config.3
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd Jan 08, 2008
+.Dd Mar 16, 2008
.Dt RC_CONFIG 3 SMM
.Os OpenRC
.Sh NAME
@@ -33,8 +33,8 @@ Run Command library (librc, -lrc)
.Sh SYNOPSIS
.In rc.h
.Ft "char *" Fn rc_getline "FILE *fp"
-.Ft "char **" Fn rc_config_list "const char *file"
-.Ft "char **" Fn rc_config_load "const char *file"
+.Ft "RC_STRINGLIST *" Fn rc_config_list "const char *file"
+.Ft "RC_STRINGLIST *" Fn rc_config_load "const char *file"
.Ft "char *" Fn rc_config_value "const char *const *list" "const char *entry"
.Ft bool Fn rc_yesno "const char *value"
.Sh DESCRIPTION
@@ -61,7 +61,7 @@ found in
.Fa list .
.Pp
Each list should be freed using
-.Fn rc_strlist_free
+.Fn rc_stringlist_free
when done.
.Pp
.Fn rc_yesno
@@ -76,7 +76,7 @@ is set to
.Va EINVAL .
.Sh SEE ALSO
.Xr malloc 3 ,
-.Xr rc_strlist_free 3 ,
+.Xr rc_stringlist_free 3 ,
.Xr sh 1
.Sh AUTHORS
.An "Roy Marples" Aq roy@marples.name
diff --git a/man/rc_deptree.3 b/man/rc_deptree.3
index 0ee1ad2..8ca2a7d 100644
--- a/man/rc_deptree.3
+++ b/man/rc_deptree.3
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd Feb 22, 2008
+.Dd Mar 16, 2008
.Dt RC_DEPTREE 3 SMM
.Os OpenRC
.Sh NAME
@@ -36,25 +36,25 @@ Run Command library (librc, -lrc)
.In rc.h
.Ft bool Fn rc_deptree_update void
.Ft bool Fn rc_deptree_update_needed void
-.Ft rc_depinfo_t Fn rc_deptree_load void
-.Ft "char **" Fo rc_deptree_depend
-.Fa "const rc_depinfo_t *deptree"
+.Ft RC_DEPTREE Fn rc_deptree_load void
+.Ft "RC_STRINGLIST *" Fo rc_deptree_depend
+.Fa "const RC_DEPTREE *deptree"
.Fa "const char *type"
.Fa "const char *service"
.Fc
.Ft bool Fo rc_deptree_depends
-.Fa "const rc_depinfo_t *deptree"
+.Fa "const RC_DEPTREE *deptree"
.Fa "const char *const *types"
.Fa "const char *const *services"
.Fa "const char *runlevel"
.Fa "int options"
.Fc
-.Ft "char **" Fo rc_deptree_order
-.Fa "const rc_depinfo_t *deptree"
+.Ft "RC_STRINGLIST *" Fo rc_deptree_order
+.Fa "const RC_DEPTREE *deptree"
.Fa "const char *runlevel"
.Fa "int options"
.Fc
-.Ft void Fn rc_deptree_free "rc_depinfo_t *deptree"
+.Ft void Fn rc_deptree_free "RC_DEPTREE *deptree"
.Sh DESCRIPTION
These functions provide a means of querying the dependencies of OpenRC
services.
@@ -100,15 +100,14 @@ only lists services actually needed or in the
.Va runlevel .
.Sh IMPLEMENTATION NOTES
Each function that returns
-.Fr "char **"
-returns a malloced NULL terminated array of malloced NULL terminated strings,
-all of which need to be freed using
-.Fn rc_strlist_free
+.Fr "RC_STRINGLIST *"
+should be freed by calling
+.Fn rc_stringlist_free
when done.
.Sh SEE ALSO
.Xr malloc 3 ,
.Xr free 3 ,
-.Xr rc_strlist_free 3 ,
+.Xr rc_stringlist_free 3 ,
.Xr runscript 8
.Sh AUTHORS
.An "Roy Marples" Aq roy@marples.name
diff --git a/man/rc_plugin_hook.3 b/man/rc_plugin_hook.3
index 7a6e890..f433a94 100644
--- a/man/rc_plugin_hook.3
+++ b/man/rc_plugin_hook.3
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd Feb 22, 2008
+.Dd Mar 16, 2008
.Dt RC_PLUGIN_HOOK 3 SMM
.Os OpenRC
.Sh NAME
@@ -32,7 +32,7 @@
Run Command library (librc, -lrc)
.Sh SYNOPSIS
.In rc.h
-.Ft int Fn rc_plugin_hook "rc_hook_t hook" "const char *name"
+.Ft int Fn rc_plugin_hook "RC_HOOK hook" "const char *name"
.Sh DESCRIPTION
.Fn rc_plugin_hook
is called for each shareable object found in
diff --git a/man/rc_runlevel.3 b/man/rc_runlevel.3
index 1a806c8..2ee7977 100644
--- a/man/rc_runlevel.3
+++ b/man/rc_runlevel.3
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd Feb 22, 2008
+.Dd Mar 16, 2008
.Dt RC_RUNLEVEL 3 SMM
.Os OpenRC
.Sh NAME
@@ -35,7 +35,7 @@ Run Command library (librc, -lrc)
.In rc.h
.Ft "char *" Fn rc_runlevel_get void
.Ft bool Fn rc_runlevel_exists
-.Ft "char **" Fn rc_runlevel_list void
+.Ft "RC_STRINGLIST *" Fn rc_runlevel_list void
.Ft bool Fn rc_runlevel_set "const char *runlevel"
.Ft bool Fn rc_runlevel_starting void
.Ft bool Fn rc_runlevel_stopping void
@@ -48,10 +48,9 @@ Each function that returns
returns a malloced NULL terminated string that should be freed when done.
.Pp
Each function that returns
-.Fr "char **"
-returns a malloced NULL terminated array of malloced NULL terminated strings,
-all of which need to be freed using
-.Fn rc_strlist_free
+.Fr "RC_STRINGLIST *"
+should by freed by calling
+.Fn rc_stringlist_free
when done.
.Sh FILES
.Pa /etc/init.d/functions.sh
@@ -62,6 +61,6 @@ Rinse and repeat for the other verbose functions.
.Sh SEE ALSO
.Xr malloc 3 ,
.Xr free 3
-.Xr rc_strlist_free 3
+.Xr rc_stringlist_free 3
.Sh AUTHORS
.An "Roy Marples" Aq roy@marples.name
diff --git a/man/rc_service.3 b/man/rc_service.3
index 9faecb6..a716857 100644
--- a/man/rc_service.3
+++ b/man/rc_service.3
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd Feb 22, 2008
+.Dd Mar 16, 2008
.Dt RC_SERVICE 3 SMM
.Os OpenRC
.Sh NAME
@@ -55,17 +55,17 @@ Run Command library (librc, -lrc)
.Fc
.Ft bool Fn rc_service_exists "const char *service"
.Ft bool Fn rc_service_in_runlevel "const char *service" "const char *runlevel"
-.Ft bool Fn rc_service_mark "const char *service" "rc_service_state_t state"
-.Ft "char **" Fn rc_service_extra_commands "const char *service"
+.Ft bool Fn rc_service_mark "const char *service" "RC_SERVICE state"
+.Ft "RC_STRINGLIST *" Fn rc_service_extra_commands "const char *service"
.Ft bool Fn rc_service_plugable "const char *service"
.Ft "char *" rc_service_resolve "const char *service"
.Ft bool Fo rc_service_schedule_start
.Fa "const char *service"
.Fa "const char *service_to_start"
.Fc
-.Ft "char **" Fn rc_services_scheduled_by "const char *service"
+.Ft "RC_STRINGLIST *" Fn rc_services_scheduled_by "const char *service"
.Ft bool Fn rc_service_schedule_clear "const char *service"
-.Ft rc_service_state_t Fn rc_service_state "const char *service"
+.Ft RC_SERVICE Fn rc_service_state "const char *service"
.Ft pid_t Fn rc_service_start "const char *service"
.Ft pid_t Fn rc_service_stop "const char *service"
.Ft bool Fo rc_service_started_daemon
@@ -79,9 +79,9 @@ Run Command library (librc, -lrc)
.Fa "const char *option"
.Fa "const char *value"
.Fc
-.Ft "char **" Fn rc_services_in_runlevel "const char *runlevel"
-.Ft "char **" Fn rc_services_in_state "rc_service_state_t state"
-.Ft "char **" Fn rc_services_scheduled "const char *service"
+.Ft "RC_STRINGLIST *" Fn rc_services_in_runlevel "const char *runlevel"
+.Ft "RC_STRINGLIST *" Fn rc_services_in_state "RC_SERVICE state"
+.Ft "RC_STRINGLIST *" Fn rc_services_scheduled "const char *service"
.Ft bool Fn rc_service_daemons_crashed "const char *service"
.Sh DESCRIPTION
These functions provide a means of querying OpenRC services to find out the
@@ -222,10 +222,9 @@ Each function that returns
returns a malloced NULL terminated string that should be freed when done.
.Pp
Each function that returns
-.Fr "char **"
-returns a malloced NULL terminated array of malloced NULL terminated strings,
-all of which need to be freed using
-.Fn rc_strlist_free
+.Fr "RC_STRINGLIST *"
+should be freed using
+.Fn rc_stringlist_free
when done.
.Pp
When a function fails it should either return false or NULL and set
@@ -238,7 +237,7 @@ normally holds the volatile state data for services on a RAM backed disk.
.Xr errno 3 ,
.Xr malloc 3 ,
.Xr free 3
-.Xr rc_strlist_free 3 ,
+.Xr rc_stringlist_free 3 ,
.Xr start-stop-daemon 8
.Sh AUTHORS
.An "Roy Marples" Aq roy@marples.name
diff --git a/man/rc_strlist.3 b/man/rc_strlist.3
deleted file mode 100644
index 9d082c5..0000000
--- a/man/rc_strlist.3
+++ /dev/null
@@ -1,104 +0,0 @@
-.\" Copyright 2007-2008 Roy Marples
-.\" All rights reserved
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.Dd Feb 22, 2008
-.Dt RC_STRLIST 3 SMM
-.Os OpenRC
-.Sh NAME
-.Nm rc_strlist_add , rc_strlist_addu , rc_strlist_addsort ,
-.Nm rc_strlist_addsortc , rc_strlist_addsortu , rc_strlist_delete ,
-.Nm rc_strlist_join , rc_strlist_reverse , rc_strlist_free
-.Nd RC string list functions
-.Sh LIBRARY
-Run Command library (librc, -lrc)
-.Sh SYNOPSIS
-.In rc.h
-.Ft "char *" Fn rc_strlist_add "char ***list" "const char *item"
-.Ft "char *" Fn rc_strlist_addu "char ***list" "const char *item"
-.Ft "char *" Fn rc_strlist_addsort "char ***list" "const char *item"
-.Ft "char *" Fn rc_strlist_addsortc "char ***list" "const char *item"
-.Ft "char *" Fn rc_strlist_addsortu "char ***list" "const char *item"
-.Ft bool Fn rc_strlist_delete "char ***list" "const char *item"
-.Ft "char *" Fn rc_strlist_join "char ***list1" "const char **list2"
-.Ft void Fn rc_strlist_reverse "char **list"
-.Ft void Fn rc_strlist_free "char **list"
-.Sh DESCRIPTION
-These functions provide an easy means of manipulating string lists without
-the need for custom structures or non standard macros.
-.Pp
-.Fn rc_strlist_add
-adds a malloced copy of
-.Fa item
-to
-.Fa list ,
-realloced to accomodate the new item. It returns a pointer to the new item on
-success, or NULL on failure and sets
-.Va errno
-accordingly.
-.Fn rc_strlist_addu
-and
-.Fn rc_strlist_addsortu
-only work if
-.Fa list
-does not already contain
-.Fa item .
-.Fn rc_strlist_addsort
-adds the item to the list in a lexically sorted position, using
-.Nm strcoll ,
-whereas
-.Fn rc_strlist_addsortc
-uses
-.Nm strcmp .
-.Pp
-.Fn rc_strlist_delete
-removes and frees
-.Fa item
-from
-.Fa list ,
-retuning true on success, otherwise false.
-.Pp
-.Fn rc_strlist_join
-appends
-.Fa list2
-to the end of
-.Fa list1
-and returns a pointer to the last item on the new list.
-.Pp
-.Fn rc_strlist_reverse
-reverses the items on
-.Fa list .
-.Pp
-.Fn rc_strlist_free
-frees each item on
-.Fa list
-and the
-.Fa list
-itself.
-.Sh SEE ALSO
-.Xr malloc 3 ,
-.Xr free 3 ,
-.Xr strcmp 3 ,
-.Xr strcoll 3
-.Sh AUTHORS
-.An "Roy Marples" Aq roy@marples.name
diff --git a/src/includes/rc-misc.h b/src/includes/rc-misc.h
index fafbc49..0b33c99 100644
--- a/src/includes/rc-misc.h
+++ b/src/includes/rc-misc.h
@@ -56,7 +56,7 @@
#define RC_LIBDIR RC_PREFIX "/" LIB "/rc"
#define RC_SVCDIR RC_LIBDIR "/init.d"
-#define RC_DEPTREE RC_SVCDIR "/deptree"
+#define RC_DEPTREE_CACHE RC_SVCDIR "/deptree"
#define RC_RUNLEVELDIR RC_PREFIX SYSCONFDIR "/runlevels"
#define RC_INITDIR RC_PREFIX SYSCONFDIR "/init.d"
#define RC_CONFDIR RC_PREFIX SYSCONFDIR "/conf.d"
@@ -98,9 +98,46 @@
# define _unused
#endif
+
+/* Some libc implemntations don't have these */
+#ifndef STAILQ_CONCAT
+#define STAILQ_CONCAT(head1, head2) do { \
+ if (!STAILQ_EMPTY((head2))) { \
+ *(head1)->stqh_last = (head2)->stqh_first; \
+ (head1)->stqh_last = (head2)->stqh_last; \
+ STAILQ_INIT((head2)); \
+ } \
+} while (0)
+#endif
+
+#ifndef TAILQ_CONCAT
+#define TAILQ_CONCAT(head1, head2) do { \
+ if (!TAILQ_EMPTY((head2))) { \
+ *(head1)->tqh_last = (head2)->tqh_first; \
+ (head1)->tqh_last = (head2)->tqh_last; \
+ TAILQ_INIT((head2)); \
+ } \
+} while (0)
+#endif
+
+#ifndef STAILQ_FOREACH_SAFE
+#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = STAILQ_FIRST((head)); \
+ (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
+ (var) = (tvar))
+#endif
+
+#ifndef TAILQ_FOREACH_SAFE
+#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = TAILQ_FIRST((head)); \
+ (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
+ (var) = (tvar))
+#endif
+
+
_unused static void *xmalloc (size_t size)
{
- void *value = malloc (size);
+ void *value = malloc(size);
if (value)
return (value);
@@ -109,9 +146,9 @@ _unused static void *xmalloc (size_t size)
/* NOTREACHED */
}
-_unused static void *xrealloc (void *ptr, size_t size)
+_unused static void *xrealloc(void *ptr, size_t size)
{
- void *value = realloc (ptr, size);
+ void *value = realloc(ptr, size);
if (value)
return (value);
@@ -120,14 +157,14 @@ _unused static void *xrealloc (void *ptr, size_t size)
/* NOTREACHED */
}
-_unused static char *xstrdup (const char *str)
+_unused static char *xstrdup(const char *str)
{
char *value;
if (! str)
return (NULL);
- value = strdup (str);
+ value = strdup(str);
if (value)
return (value);
@@ -138,32 +175,32 @@ _unused static char *xstrdup (const char *str)
#undef ERRX
-_unused static bool exists (const char *pathname)
+_unused static bool exists(const char *pathname)
{
struct stat buf;
- return (stat (pathname, &buf) == 0);
+ return (stat(pathname, &buf) == 0);
}
-_unused static bool existss (const char *pathname)
+_unused static bool existss(const char *pathname)
{
struct stat buf;
- return (stat (pathname, &buf) == 0 && buf.st_size != 0);
+ return (stat(pathname, &buf) == 0 && buf.st_size != 0);
}
-char *rc_conf_value (const char *var);
-bool rc_conf_yesno (const char *var);
-char **env_filter (void);
-char **env_config (void);
-bool service_plugable (const char *service);
-int signal_setup (int sig, void (*handler)(int));
+char *rc_conf_value(const char *var);
+bool rc_conf_yesno(const char *var);
+void env_filter(void);
+void env_config(void);
+bool service_plugable(const char *service);
+int signal_setup(int sig, void (*handler)(int));
/* basename_c never modifies the argument. As such, if there is a trailing
* slash then an empty string is returned. */
-_unused static const char *basename_c (const char *path)
+_unused static const char *basename_c(const char *path)
{
- const char *slash = strrchr (path, '/');
+ const char *slash = strrchr(path, '/');
if (slash)
return (++slash);
diff --git a/src/includes/strlist.h b/src/includes/strlist.h
deleted file mode 100644
index ff4c4ed..0000000
--- a/src/includes/strlist.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- strlist.h
- String list macros for making char ** arrays
- Based on a previous implementation by Martin Schlemmer
- */
-
-/*
- * Copyright 2007-2008 Roy Marples
- * All rights reserved
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef __STRLIST_H__
-#define __STRLIST_H__
-
-/* FIXME: We should replace the macro with an rc_strlist_foreach
- function, but I'm unsure how to go about this. */
-
-/* Step through each entry in the string list, setting '_pos' to the
- beginning of the entry. '_counter' is used by the macro as index,
- but should not be used by code as index (or if really needed, then
- it should usually by +1 from what you expect, and should only be
- used in the scope of the macro) */
-#define STRLIST_FOREACH(_list, _pos, _counter) \
- if ((_list) && _list[0] && ! (_counter = 0)) \
- while ((_pos = _list[_counter++]))
-
-#endif /* __STRLIST_H__ */
diff --git a/src/libeinfo/einfo.h b/src/libeinfo/einfo.h
index 06fd3aa..6d39c36 100644
--- a/src/libeinfo/einfo.h
+++ b/src/libeinfo/einfo.h
@@ -54,19 +54,19 @@
/*! @brief Color types to use */
typedef enum
{
- ECOLOR_NORMAL = 1,
- ECOLOR_GOOD = 2,
- ECOLOR_WARN = 3,
- ECOLOR_BAD = 4,
- ECOLOR_HILITE = 5,
- ECOLOR_BRACKET = 6
-} einfo_color_t;
+ ECOLOR_NORMAL = 1,
+ ECOLOR_GOOD = 2,
+ ECOLOR_WARN = 3,
+ ECOLOR_BAD = 4,
+ ECOLOR_HILITE = 5,
+ ECOLOR_BRACKET = 6
+} ECOLOR;
/*! @brief Returns the ASCII code for the color */
-const char *ecolor (einfo_color_t);
+const char *ecolor(ECOLOR);
/*! @brief Writes to syslog. */
-void elog (int __level, const char * __EINFO_RESTRICT __fmt, ...) __EEND_PRINTF;
+void elog(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF;
/*!
* @brief Display informational messages.
@@ -84,22 +84,22 @@ void elog (int __level, const char * __EINFO_RESTRICT __fmt, ...) __EEND_PRINTF;
* The v suffix means only print if EINFO_VERBOSE is yes.
*/
/*@{*/
-int einfon (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
-int ewarnn (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
-int eerrorn (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
-int einfo (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
-int ewarn (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
-void ewarnx (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_XPRINTF;
-int eerror (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
-void eerrorx (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_XPRINTF;
-
-int einfovn (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
-int ewarnvn (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
-int ebeginvn (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
-int eendvn (int __retval, const char * __EINFO_RESTRICT __fmt, ...) __EEND_PRINTF;
-int ewendvn (int __retval, const char * __EINFO_RESTRICT __fmt, ...) __EEND_PRINTF;
-int einfov (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
-int ewarnv (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
+int einfon(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
+int ewarnn(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
+int eerrorn(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
+int einfo(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
+int ewarn(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
+void ewarnx(const char * __EINFO_RESTRICT, ...) __EINFO_XPRINTF;
+int eerror(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
+void eerrorx(const char * __EINFO_RESTRICT, ...) __EINFO_XPRINTF;
+
+int einfovn(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
+int ewarnvn(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
+int ebeginvn(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
+int eendvn(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF;
+int ewendvn(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF;
+int einfov(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
+int ewarnv(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
/*@}*/
/*! @ingroup ebegin
@@ -107,8 +107,8 @@ int ewarnv (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
*
* Similar to einfo, but we add ... to the end of the message */
/*@{*/
-int ebeginv (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
-int ebegin (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
+int ebeginv(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
+int ebegin(const char * __EINFO_RESTRICT, ...) __EINFO_PRINTF;
/*@}*/
/*! @ingroup eend
@@ -120,12 +120,12 @@ int ebegin (const char * __EINFO_RESTRICT __fmt, ...) __EINFO_PRINTF;
*
* ebracket allows you to specifiy the position, color and message */
/*@{*/
-int eend (int __retval, const char * __EINFO_RESTRICT __fmt, ...) __EEND_PRINTF;
-int ewend (int __retval, const char * __EINFO_RESTRICT __fmt, ...) __EEND_PRINTF;
-void ebracket (int __col, einfo_color_t __color, const char * __EINFO_RESTRICT __msg);
+int eend(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF;
+int ewend(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF;
+void ebracket(int, ECOLOR, const char * __EINFO_RESTRICT);
-int eendv (int __retval, const char * __EINFO_RESTRICT __fmt, ...) __EEND_PRINTF;
-int ewendv (int __retval, const char * __EINFO_RESTRICT __fmt, ...) __EEND_PRINTF;
+int eendv(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF;
+int ewendv(int, const char * __EINFO_RESTRICT, ...) __EEND_PRINTF;
/*@}*/
/*! @ingroup eindent
@@ -133,12 +133,12 @@ int ewendv (int __retval, const char * __EINFO_RESTRICT __fmt, ...) __EEND_PRINT
*
* For each indent you should outdent when done */
/*@{*/
-void eindent (void);
-void eoutdent (void);
-void eindentv (void);
-void eoutdentv (void);
+void eindent(void);
+void eoutdent(void);
+void eindentv(void);
+void eoutdentv(void);
/*! @brief Prefix each einfo line with something */
-void eprefix (const char * __EINFO_RESTRICT __prefix);
+void eprefix(const char * __EINFO_RESTRICT);
#endif
diff --git a/src/libeinfo/libeinfo.c b/src/libeinfo/libeinfo.c
index ee5b8a6..4196996 100644
--- a/src/libeinfo/libeinfo.c
+++ b/src/libeinfo/libeinfo.c
@@ -34,6 +34,7 @@ const char libeinfo_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
+
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
@@ -52,6 +53,7 @@ const char libeinfo_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
#include "einfo.h"
#include "hidden-visibility.h"
+
hidden_proto(ecolor)
hidden_proto(ebegin)
hidden_proto(ebeginv)
@@ -107,10 +109,10 @@ hidden_proto(ewendv)
#define ME "\033[m"
#define UP "\033[A"
-#define _GET_CAP(_d, _c) strlcpy (_d, tgoto (_c, 0, 0), sizeof (_d));
+#define _GET_CAP(_d, _c) strlcpy(_d, tgoto(_c, 0, 0), sizeof(_d));
#define _ASSIGN_CAP(_v) { \
_v = p; \
- p += strlcpy (p, tmp, sizeof (ebuffer) - (p - ebuffer)) + 1; \
+ p += strlcpy(p, tmp, sizeof(ebuffer) - (p - ebuffer)) + 1; \
}
/* A pointer to a string to prefix to einfo/ewarn/eerror messages */
@@ -119,7 +121,7 @@ static const char *_eprefix = NULL;
/* Buffers and structures to hold the final colours */
static char ebuffer[100];
struct ecolor {
- einfo_color_t color;
+ ECOLOR color;
int def;
const char *name;
};
@@ -197,7 +199,7 @@ static const char *const color_terms[] = {
/* strlcat and strlcpy are nice, shame glibc does not define them */
#ifdef __GLIBC__
# if ! defined (__UCLIBC__) && ! defined (__dietlibc__)
-static size_t strlcat (char *dst, const char *src, size_t size)
+static size_t strlcat(char *dst, const char *src, size_t size)
{
char *d = dst;
const char *s = src;
@@ -210,7 +212,7 @@ static size_t strlcat (char *dst, const char *src, size_t size)
src_n = size - dst_n;
if (src_n == 0)
- return (dst_n + strlen (src));
+ return dst_n + strlen(src);
while (*s != '\0') {
if (src_n != 1) {
@@ -221,10 +223,10 @@ static size_t strlcat (char *dst, const char *src, size_t size)
}
*d = '\0';
- return (dst_n + (s - src));
+ return dst_n + (s - src);
}
-static size_t strlcpy (char *dst, const char *src, size_t size)
+static size_t strlcpy(char *dst, const char *src, size_t size)
{
const char *s = src;
size_t n = size;
@@ -241,72 +243,72 @@ static size_t strlcpy (char *dst, const char *src, size_t size)
while (*src++);
}
- return (src - s - 1);
+ return src - s - 1;
}
# endif
#endif
-static bool yesno (const char *value)
+static bool yesno(const char *value)
{
if (! value) {
errno = ENOENT;
- return (false);
+ return false;
}
- if (strcasecmp (value, "yes") == 0 ||
- strcasecmp (value, "y") == 0 ||
- strcasecmp (value, "true") == 0 ||
- strcasecmp (value, "on") == 0 ||
- strcasecmp (value, "1") == 0)
- return (true);
-
- if (strcasecmp (value, "no") != 0 &&
- strcasecmp (value, "n") != 0 &&
- strcasecmp (value, "false") != 0 &&
- strcasecmp (value, "off") != 0 &&
- strcasecmp (value, "0") != 0)
+ if (strcasecmp(value, "yes") == 0 ||
+ strcasecmp(value, "y") == 0 ||
+ strcasecmp(value, "true") == 0 ||
+ strcasecmp(value, "on") == 0 ||
+ strcasecmp(value, "1") == 0)
+ return true;
+
+ if (strcasecmp(value, "no") != 0 &&
+ strcasecmp(value, "n") != 0 &&
+ strcasecmp(value, "false") != 0 &&
+ strcasecmp(value, "off") != 0 &&
+ strcasecmp(value, "0") != 0)
errno = EINVAL;
- return (false);
+ return false;
}
-static bool noyes (const char *value)
+static bool noyes(const char *value)
{
int serrno = errno;
bool retval;
errno = 0;
- retval = yesno (value);
+ retval = yesno(value);
if (errno == 0) {
retval = ! retval;
errno = serrno;
}
- return (retval);
+ return retval;
}
-static bool is_quiet()
+static bool is_quiet(void)
{
- return (yesno (getenv ("EINFO_QUIET")));
+ return yesno(getenv("EINFO_QUIET"));
}
-static bool is_verbose()
+static bool is_verbose(void)
{
- return (yesno (getenv ("EINFO_VERBOSE")));
+ return yesno(getenv ("EINFO_VERBOSE"));
}
/* Fake tgoto call - very crapy, but works for our needs */
#ifndef HAVE_TERMCAP
-static char *tgoto (const char *cap, int a, int b)
+static char *tgoto(const char *cap, int a, int b)
{
static char buf[20];
- snprintf (buf, sizeof (buf), cap, b, a);
- return (buf);
+ snprintf(buf, sizeof(buf), cap, b, a);
+ return buf;
}
#endif
-static bool colour_terminal (FILE * __EINFO_RESTRICT f)
+static bool colour_terminal(FILE * __EINFO_RESTRICT f)
{
static int in_colour = -1;
char *e;
@@ -321,50 +323,50 @@ static bool colour_terminal (FILE * __EINFO_RESTRICT f)
char *p;
unsigned int i = 0;
- if (f && ! isatty (fileno (f)))
- return (false);
+ if (f && ! isatty(fileno(f)))
+ return false;
- if (noyes (getenv ("EINFO_COLOR")))
- return (false);
+ if (noyes(getenv("EINFO_COLOR")))
+ return false;
if (in_colour == 0)
- return (false);
+ return false;
if (in_colour == 1)
- return (true);
+ return true;
term_is_cons25 = false;
if (! term) {
- term = getenv ("TERM");
+ term = getenv("TERM");
if (! term)
- return (false);
+ return false;
}
- if (strcmp (term, "cons25") == 0)
+ if (strcmp(term, "cons25") == 0)
term_is_cons25 = true;
#ifdef HAVE_TERMCAP
/* Check termcap to see if we can do colour or not */
- if (tgetent (termcapbuf, term) == 1) {
+ if (tgetent(termcapbuf, term) == 1) {
char *bp = tcapbuf;
- _af = tgetstr ("AF", &bp);
- _ce = tgetstr ("ce", &bp);
- _ch = tgetstr ("ch", &bp);
+ _af = tgetstr("AF", &bp);
+ _ce = tgetstr("ce", &bp);
+ _ch = tgetstr("ch", &bp);
/* Our ch use also works with RI .... for now */
if (! _ch)
- _ch = tgetstr ("RI", &bp);
- _md = tgetstr ("md", &bp);
- _me = tgetstr ("me", &bp);
- _up = tgetstr ("up", &bp);
+ _ch = tgetstr("RI", &bp);
+ _md = tgetstr("md", &bp);
+ _me = tgetstr("me", &bp);
+ _up = tgetstr("up", &bp);
}
/* Cheat here as vanilla BSD has the whole termcap info in /usr
* which is not available to us when we boot */
- if (term_is_cons25 || strcmp (term, "wsvt25") == 0) {
+ if (term_is_cons25 || strcmp(term, "wsvt25") == 0) {
#else
while (color_terms[i]) {
- if (strcmp (color_terms[i], term) == 0) {
+ if (strcmp(color_terms[i], term) == 0) {
in_colour = 1;
}
i++;
@@ -372,7 +374,7 @@ static bool colour_terminal (FILE * __EINFO_RESTRICT f)
if (in_colour != 1) {
in_colour = 0;
- return (false);
+ return false;
}
#endif
if (! _af)
@@ -392,7 +394,7 @@ static bool colour_terminal (FILE * __EINFO_RESTRICT f)
if (! _af || ! _ce || ! _me || !_md || ! _up) {
in_colour = 0;
- return (false);
+ return false;
}
/* Many termcap databases don't have ch or RI even though they
@@ -403,7 +405,7 @@ static bool colour_terminal (FILE * __EINFO_RESTRICT f)
/* Now setup our colours */
p = ebuffer;
- for (i = 0; i < sizeof (ecolors) / sizeof (ecolors[0]); i++) {
+ for (i = 0; i < sizeof(ecolors) / sizeof(ecolors[0]); i++) {
tmp[0] = '\0';
if (ecolors[i].name) {
@@ -414,370 +416,370 @@ static bool colour_terminal (FILE * __EINFO_RESTRICT f)
* We use a :col;bold: format like 2;1: for bold green
* and 1;0: for a normal red */
if ((e = getenv("EINFO_COLOR"))) {
- char *ee = strstr (e, ecolors[i].name);
+ char *ee = strstr(e, ecolors[i].name);
if (ee)
- ee += strlen (ecolors[i].name);
+ ee += strlen(ecolors[i].name);
if (ee && *ee == '=') {
- char *d = strdup (ee + 1);
+ char *d = strdup(ee + 1);
if (d) {
- char *end = strchr (d, ':');
+ char *end = strchr(d, ':');
if (end)
*end = '\0';
c = atoi(d);
- end = strchr (d, ';');
+ end = strchr(d, ';');
if (end && *++end == '0')
bold = _me;
- free (d);
+ free(d);
}
}
}
- strlcpy (tmp, tgoto (bold, 0, 0), sizeof (tmp));
- strlcat (tmp, tgoto (_af, 0, c & 0x07), sizeof (tmp));
+ strlcpy(tmp, tgoto(bold, 0, 0), sizeof(tmp));
+ strlcat(tmp, tgoto(_af, 0, c & 0x07), sizeof(tmp));
} else
- _GET_CAP (tmp, _me);
+ _GET_CAP(tmp, _me);
if (tmp[0])
- _ASSIGN_CAP (ecolors_str[i])
+ _ASSIGN_CAP(ecolors_str[i])
else
ecolors_str[i] = &nullstr;
}
- _GET_CAP (tmp, _ce)
- _ASSIGN_CAP (flush)
- _GET_CAP (tmp, _up);
- _ASSIGN_CAP (up);
- strlcpy (tmp, _ch, sizeof (tmp));
- _ASSIGN_CAP (goto_column);
+ _GET_CAP(tmp, _ce);
+ _ASSIGN_CAP(flush);
+ _GET_CAP(tmp, _up);
+ _ASSIGN_CAP(up);
+ strlcpy(tmp, _ch, sizeof(tmp));
+ _ASSIGN_CAP(goto_column);
in_colour = 1;
- return (true);
+ return true;
}
-static int get_term_columns (FILE * __EINFO_RESTRICT stream)
+static int get_term_columns(FILE * __EINFO_RESTRICT stream)
{
struct winsize ws;
- char *env = getenv ("COLUMNS");
+ char *env = getenv("COLUMNS");
char *p;
int i;
if (env) {
- i = strtoimax (env, &p, 10);
+ i = strtoimax(env, &p, 10);
if (! *p)
- return (i);
+ return i;
}
- if (ioctl (fileno (stream), TIOCGWINSZ, &ws) == 0)
- return (ws.ws_col);
+ if (ioctl(fileno(stream), TIOCGWINSZ, &ws) == 0)
+ return ws.ws_col;
- return (DEFAULT_COLS);
+ return DEFAULT_COLS;
}
-void eprefix (const char *__EINFO_RESTRICT prefix)
+void eprefix(const char *__EINFO_RESTRICT prefix)
{
_eprefix = prefix;
}
hidden_def(eprefix)
-static void elogv (int level, const char *__EINFO_RESTRICT fmt, va_list ap)
+static void elogv(int level, const char *__EINFO_RESTRICT fmt, va_list ap)
{
- char *e = getenv ("EINFO_LOG");
+ char *e = getenv("EINFO_LOG");
va_list apc;
if (fmt && e) {
- closelog ();
- openlog (e, LOG_PID, LOG_DAEMON);
- va_copy (apc, ap);
- vsyslog (level, fmt, apc);
- va_end (apc);
- closelog ();
+ closelog();
+ openlog(e, LOG_PID, LOG_DAEMON);
+ va_copy(apc, ap);
+ vsyslog(level, fmt, apc);
+ va_end(apc);
+ closelog();
}
}
-void elog (int level, const char *__EINFO_RESTRICT fmt, ...)
+void elog(int level, const char *__EINFO_RESTRICT fmt, ...)
{
va_list ap;
- va_start (ap, fmt);
- elogv (level, fmt, ap);
- va_end (ap);
+ va_start(ap, fmt);
+ elogv(level, fmt, ap);
+ va_end(ap);
}
hidden_def(elog)
-static int _eindent (FILE * __EINFO_RESTRICT stream)
+static int _eindent(FILE * __EINFO_RESTRICT stream)
{
- char *env = getenv ("EINFO_INDENT");
+ char *env = getenv("EINFO_INDENT");
int amount = 0;
char indent[INDENT_MAX];
if (env) {
errno = 0;
- amount = strtoimax (env, NULL, 0);
+ amount = strtoimax(env, NULL, 0);
if (errno != 0 || amount < 0)
amount = 0;
else if (amount > INDENT_MAX)
amount = INDENT_MAX;
if (amount > 0)
- memset (indent, ' ', (size_t) amount);
+ memset(indent, ' ', (size_t) amount);
}
/* Terminate it */
- memset (indent + amount, 0, 1);
- return (fprintf (stream, "%s", indent));
+ memset(indent + amount, 0, 1);
+ return fprintf(stream, "%s", indent);
}
-static const char *_ecolor (FILE * __EINFO_RESTRICT f, einfo_color_t color)
+static const char *_ecolor(FILE * __EINFO_RESTRICT f, ECOLOR color)
{
unsigned int i;
- if (! colour_terminal (f))
- return ("");
+ if (! colour_terminal(f))
+ return "";
- for (i = 0; i < sizeof (ecolors) / sizeof (ecolors[0]); i++) {
+ for (i = 0; i < sizeof(ecolors) / sizeof(ecolors[0]); i++) {
if (ecolors[i].color == color)
- return (ecolors_str[i]);
+ return ecolors_str[i];
}
- return ("");
+ return "";
}
hidden_def(ecolor)
-const char *ecolor (einfo_color_t color)
+const char *ecolor(ECOLOR color)
{
FILE *f = stdout;
/* Try and guess a valid tty */
- if (! isatty (fileno (f))) {
+ if (! isatty(fileno(f))) {
f = stderr;
- if (! isatty (fileno (f))) {
+ if (! isatty(fileno(f))) {
f = stdin;
- if (! isatty (fileno (f)))
+ if (! isatty(fileno(f)))
f = NULL;
}
}
- return (_ecolor (f, color));
+ return _ecolor(f, color);
}
#define LASTCMD(_cmd) { \
- unsetenv ("EINFO_LASTCMD"); \
- setenv ("EINFO_LASTCMD", _cmd, 1); \
+ unsetenv("EINFO_LASTCMD"); \
+ setenv("EINFO_LASTCMD", _cmd, 1); \
}
#define EINFOVN(_file, _color) \
{ \
- char *_e = getenv ("EINFO_LASTCMD"); \
- if (_e && ! colour_terminal (_file) && strcmp (_e, "ewarn") != 0 && \
+ char *_e = getenv("EINFO_LASTCMD"); \
+ if (_e && ! colour_terminal(_file) && strcmp(_e, "ewarn") != 0 && \
_e[strlen (_e) - 1] == 'n') \
- fprintf (_file, "\n"); \
+ fprintf(_file, "\n"); \
if (_eprefix) \
- fprintf (_file, "%s%s%s|", _ecolor (_file, _color), _eprefix, _ecolor (_file, ECOLOR_NORMAL)); \
- fprintf (_file, " %s*%s ", _ecolor (_file, _color), _ecolor (_file, ECOLOR_NORMAL)); \
- retval += _eindent (_file); \
+ fprintf(_file, "%s%s%s|", _ecolor(_file, _color), _eprefix, _ecolor(_file, ECOLOR_NORMAL)); \
+ fprintf(_file, " %s*%s ", _ecolor(_file, _color), _ecolor(_file, ECOLOR_NORMAL)); \
+ retval += _eindent(_file); \
{ \
va_list _ap; \
- va_copy (_ap, ap); \
- retval += vfprintf (_file, fmt, _ap) + 3; \
- va_end (_ap); \
+ va_copy(_ap, ap); \
+ retval += vfprintf(_file, fmt, _ap) + 3; \
+ va_end(_ap); \
} \
- if (colour_terminal (_file)) \
- fprintf (_file, "%s", flush); \
+ if (colour_terminal(_file)) \
+ fprintf(_file, "%s", flush); \
}
-static int _einfovn (const char *__EINFO_RESTRICT fmt, va_list ap)
+static int _einfovn(const char *__EINFO_RESTRICT fmt, va_list ap)
{
int retval = 0;
- EINFOVN (stdout, ECOLOR_GOOD);
- return (retval);
+ EINFOVN(stdout, ECOLOR_GOOD);
+ return retval;
}
-static int _ewarnvn (const char *__EINFO_RESTRICT fmt, va_list ap)
+static int _ewarnvn(const char *__EINFO_RESTRICT fmt, va_list ap)
{
int retval = 0;
- EINFOVN (stderr, ECOLOR_WARN);
- return (retval);
+ EINFOVN(stderr, ECOLOR_WARN);
+ return retval;
}
-static int _eerrorvn (const char *__EINFO_RESTRICT fmt, va_list ap)
+static int _eerrorvn(const char *__EINFO_RESTRICT fmt, va_list ap)
{
int retval = 0;
- EINFOVN (stderr, ECOLOR_BAD);
- return (retval);
+ EINFOVN(stderr, ECOLOR_BAD);
+ return retval;
}
-int einfon (const char *__EINFO_RESTRICT fmt, ...)
+int einfon(const char *__EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
- if (! fmt || is_quiet ())
- return (0);
+ if (! fmt || is_quiet())
+ return 0;
- va_start (ap, fmt);
- retval = _einfovn (fmt, ap);
- va_end (ap);
+ va_start(ap, fmt);
+ retval = _einfovn(fmt, ap);
+ va_end(ap);
- LASTCMD ("einfon");
+ LASTCMD("einfon");
- return (retval);
+ return retval;
}
hidden_def(einfon)
-int ewarnn (const char *__EINFO_RESTRICT fmt, ...)
+int ewarnn(const char *__EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
- if (! fmt || is_quiet ())
- return (0);
+ if (! fmt || is_quiet())
+ return 0;
- va_start (ap, fmt);
- retval = _ewarnvn (fmt, ap);
- va_end (ap);
+ va_start(ap, fmt);
+ retval = _ewarnvn(fmt, ap);
+ va_end(ap);
- LASTCMD ("ewarnn");
+ LASTCMD("ewarnn");
- return (retval);
+ return retval;
}
hidden_def(ewarnn)
-int eerrorn (const char *__EINFO_RESTRICT fmt, ...)
+int eerrorn(const char *__EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
- va_start (ap, fmt);
- retval = _eerrorvn (fmt, ap);
- va_end (ap);
+ va_start(ap, fmt);
+ retval = _eerrorvn(fmt, ap);
+ va_end(ap);
- LASTCMD ("errorn");
+ LASTCMD("errorn");
- return (retval);
+ return retval;
}
hidden_def(eerrorn)
-int einfo (const char *__EINFO_RESTRICT fmt, ...)
+int einfo(const char *__EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
if (! fmt || is_quiet())
- return (0);
+ return 0;
- va_start (ap, fmt);
- retval = _einfovn (fmt, ap);
- retval += printf ("\n");
- va_end (ap);
+ va_start(ap, fmt);
+ retval = _einfovn(fmt, ap);
+ retval += printf("\n");
+ va_end(ap);
- LASTCMD ("einfo");
+ LASTCMD("einfo");
- return (retval);
+ return retval;
}
hidden_def(einfo)
-int ewarn (const char *__EINFO_RESTRICT fmt, ...)
+int ewarn(const char *__EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
- if (! fmt || is_quiet ())
- return (0);
+ if (! fmt || is_quiet())
+ return 0;
- va_start (ap, fmt);
- elogv (LOG_WARNING, fmt, ap);
- retval = _ewarnvn (fmt, ap);
- retval += fprintf (stderr, "\n");
- va_end (ap);
+ va_start(ap, fmt);
+ elogv(LOG_WARNING, fmt, ap);
+ retval = _ewarnvn(fmt, ap);
+ retval += fprintf(stderr, "\n");
+ va_end(ap);
- LASTCMD ("ewarn");
+ LASTCMD("ewarn");
- return (retval);
+ return retval;
}
hidden_def(ewarn)
-void ewarnx (const char *__EINFO_RESTRICT fmt, ...)
+void ewarnx(const char *__EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
- if (fmt && ! is_quiet ()) {
- va_start (ap, fmt);
- elogv (LOG_WARNING, fmt, ap);
- retval = _ewarnvn (fmt, ap);
- va_end (ap);
- retval += fprintf (stderr, "\n");
+ if (fmt && ! is_quiet()) {
+ va_start(ap, fmt);
+ elogv(LOG_WARNING, fmt, ap);
+ retval = _ewarnvn(fmt, ap);
+ va_end(ap);
+ retval += fprintf(stderr, "\n");
}
- exit (EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
hidden_def(ewarnx)
-int eerror (const char *__EINFO_RESTRICT fmt, ...)
+int eerror(const char *__EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
if (! fmt)
- return (0);
+ return 0;
- va_start (ap, fmt);
- elogv (LOG_ERR, fmt, ap);
- retval = _eerrorvn (fmt, ap);
- va_end (ap);
- retval += fprintf (stderr, "\n");
+ va_start(ap, fmt);
+ elogv(LOG_ERR, fmt, ap);
+ retval = _eerrorvn(fmt, ap);
+ va_end(ap);
+ retval += fprintf(stderr, "\n");
- LASTCMD ("eerror");
+ LASTCMD("eerror");
- return (retval);
+ return retval;
}
hidden_def(eerror)
-void eerrorx (const char *__EINFO_RESTRICT fmt, ...)
+void eerrorx(const char *__EINFO_RESTRICT fmt, ...)
{
va_list ap;
if (fmt) {
- va_start (ap, fmt);
- elogv (LOG_ERR, fmt, ap);
- _eerrorvn (fmt, ap);
- va_end (ap);
- fprintf (stderr, "\n");
+ va_start(ap, fmt);
+ elogv(LOG_ERR, fmt, ap);
+ _eerrorvn(fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
}
- exit (EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
hidden_def(eerrorx)
-int ebegin (const char *__EINFO_RESTRICT fmt, ...)
+int ebegin(const char *__EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
- if (! fmt || is_quiet ())
- return (0);
+ if (! fmt || is_quiet())
+ return 0;
- va_start (ap, fmt);
- retval = _einfovn (fmt, ap);
- va_end (ap);
- retval += printf (" ...");
- if (colour_terminal (stdout))
- retval += printf ("\n");
+ va_start(ap, fmt);
+ retval = _einfovn(fmt, ap);
+ va_end(ap);
+ retval += printf(" ...");
+ if (colour_terminal(stdout))
+ retval += printf("\n");
- LASTCMD ("ebegin");
+ LASTCMD("ebegin");
- return (retval);
+ return retval;
}
hidden_def(ebegin)
-static void _eend (FILE * __EINFO_RESTRICT fp, int col, einfo_color_t color,
- const char *msg)
+static void _eend(FILE * __EINFO_RESTRICT fp, int col, ECOLOR color,
+ const char *msg)
{
int i;
int cols;
@@ -785,13 +787,13 @@ static void _eend (FILE * __EINFO_RESTRICT fp, int col, einfo_color_t color,
if (! msg)
return;
- cols = get_term_columns (fp) - (strlen (msg) + 3);
+ cols = get_term_columns(fp) - (strlen(msg) + 3);
/* cons25 is special - we need to remove one char, otherwise things
* do not align properly at all. */
if (! term) {
- term = getenv ("TERM");
- if (term && strcmp (term, "cons25") == 0)
+ term = getenv("TERM");
+ if (term && strcmp(term, "cons25") == 0)
term_is_cons25 = true;
else
term_is_cons25 = false;
@@ -799,19 +801,19 @@ static void _eend (FILE * __EINFO_RESTRICT fp, int col, einfo_color_t color,
if (term_is_cons25)
cols--;
- if (cols > 0 && colour_terminal (fp)) {
- fprintf (fp, "%s%s %s[%s%s%s]%s\n", up, tgoto (goto_column, 0, cols),
- ecolor (ECOLOR_BRACKET), ecolor (color), msg,
- ecolor (ECOLOR_BRACKET), ecolor (ECOLOR_NORMAL));
+ if (cols > 0 && colour_terminal(fp)) {
+ fprintf(fp, "%s%s %s[%s%s%s]%s\n", up, tgoto(goto_column, 0, cols),
+ ecolor(ECOLOR_BRACKET), ecolor(color), msg,
+ ecolor(ECOLOR_BRACKET), ecolor(ECOLOR_NORMAL));
} else {
if (col > 0)
for (i = 0; i < cols - col; i++)
- fprintf (fp, " ");
- fprintf (fp, " [%s]\n", msg);
+ fprintf(fp, " ");
+ fprintf(fp, " [%s]\n", msg);
}
}
-static int _do_eend (const char *cmd, int retval, const char *__EINFO_RESTRICT fmt, va_list ap)
+static int _do_eend(const char *cmd, int retval, const char *__EINFO_RESTRICT fmt, va_list ap)
{
int col = 0;
FILE *fp = stdout;
@@ -819,70 +821,70 @@ static int _do_eend (const char *cmd, int retval, const char *__EINFO_RESTRICT f
if (fmt && *fmt != '\0' && retval != 0) {
fp = stderr;
- va_copy (apc, ap);
- if (strcmp (cmd, "ewend") == 0)
- col = _ewarnvn (fmt, apc);
+ va_copy(apc, ap);
+ if (strcmp(cmd, "ewend") == 0)
+ col = _ewarnvn(fmt, apc);
else
- col = _eerrorvn (fmt, apc);
- col += fprintf (fp, "\n");
- va_end (apc);
+ col = _eerrorvn(fmt, apc);
+ col += fprintf(fp, "\n");
+ va_end(apc);
}
- _eend (fp, col,
- retval == 0 ? ECOLOR_GOOD : ECOLOR_BAD,
- retval == 0 ? OK : NOT_OK);
- return (retval);
+ _eend(fp, col,
+ retval == 0 ? ECOLOR_GOOD : ECOLOR_BAD,
+ retval == 0 ? OK : NOT_OK);
+ return retval;
}
-int eend (int retval, const char *__EINFO_RESTRICT fmt, ...)
+int eend(int retval, const char *__EINFO_RESTRICT fmt, ...)
{
va_list ap;
- if (is_quiet ())
- return (retval);
+ if (is_quiet())
+ return retval;
- va_start (ap, fmt);
- _do_eend ("eend", retval, fmt, ap);
- va_end (ap);
+ va_start(ap, fmt);
+ _do_eend("eend", retval, fmt, ap);
+ va_end(ap);
- LASTCMD ("eend");
+ LASTCMD("eend");
- return (retval);
+ return retval;
}
hidden_def(eend)
-int ewend (int retval, const char *__EINFO_RESTRICT fmt, ...)
+int ewend(int retval, const char *__EINFO_RESTRICT fmt, ...)
{
va_list ap;
- if (is_quiet ())
- return (retval);
+ if (is_quiet())
+ return retval;
- va_start (ap, fmt);
- _do_eend ("ewend", retval, fmt, ap);
- va_end (ap);
+ va_start(ap, fmt);
+ _do_eend("ewend", retval, fmt, ap);
+ va_end(ap);
- LASTCMD ("ewend");
+ LASTCMD("ewend");
- return (retval);
+ return retval;
}
hidden_def(ewend)
-void ebracket (int col, einfo_color_t color, const char *msg)
+void ebracket(int col, ECOLOR color, const char *msg)
{
- _eend (stdout, col, color, msg);
+ _eend(stdout, col, color, msg);
}
hidden_def(ebracket)
-void eindent (void)
+void eindent(void)
{
- char *env = getenv ("EINFO_INDENT");
+ char *env = getenv("EINFO_INDENT");
int amount = 0;
char num[10];
if (env) {
errno = 0;
- amount = strtoimax (env, NULL, 0);
+ amount = strtoimax(env, NULL, 0);
if (errno != 0)
amount = 0;
}
@@ -891,14 +893,14 @@ void eindent (void)
if (amount > INDENT_MAX)
amount = INDENT_MAX;
- snprintf (num, 10, "%08d", amount);
- setenv ("EINFO_INDENT", num, 1);
+ snprintf(num, 10, "%08d", amount);
+ setenv("EINFO_INDENT", num, 1);
}
hidden_def(eindent)
-void eoutdent (void)
+void eoutdent(void)
{
- char *env = getenv ("EINFO_INDENT");
+ char *env = getenv("EINFO_INDENT");
int amount = 0;
char num[10];
int serrno = errno;
@@ -907,161 +909,161 @@ void eoutdent (void)
return;
errno = 0;
- amount = strtoimax (env, NULL, 0);
+ amount = strtoimax(env, NULL, 0);
if (errno != 0)
amount = 0;
else
amount -= INDENT_WIDTH;
if (amount <= 0)
- unsetenv ("EINFO_INDENT");
+ unsetenv("EINFO_INDENT");
else {
- snprintf (num, 10, "%08d", amount);
- setenv ("EINFO_INDENT", num, 1);
+ snprintf(num, 10, "%08d", amount);
+ setenv("EINFO_INDENT", num, 1);
}
errno = serrno;
}
hidden_def(eoutdent)
-int einfovn (const char *__EINFO_RESTRICT fmt, ...)
+int einfovn(const char *__EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
- if (! fmt || ! is_verbose ())
- return (0);
+ if (! fmt || ! is_verbose())
+ return 0;
- va_start (ap, fmt);
- retval = _einfovn (fmt, ap);
- va_end (ap);
+ va_start(ap, fmt);
+ retval = _einfovn(fmt, ap);
+ va_end(ap);
- LASTCMD ("einfovn");
+ LASTCMD("einfovn");
- return (retval);
+ return retval;
}
hidden_def(einfovn)
-int ewarnvn (const char *__EINFO_RESTRICT fmt, ...)
+int ewarnvn(const char *__EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
- if (! fmt || ! is_verbose ())
- return (0);
+ if (! fmt || ! is_verbose())
+ return 0;
- va_start (ap, fmt);
- retval = _ewarnvn (fmt, ap);
- va_end (ap);
+ va_start(ap, fmt);
+ retval = _ewarnvn(fmt, ap);
+ va_end(ap);
- LASTCMD ("ewarnvn");
+ LASTCMD("ewarnvn");
- return (retval);
+ return retval;
}
hidden_def(ewarnvn)
-int einfov (const char *__EINFO_RESTRICT fmt, ...)
+int einfov(const char *__EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
- if (! fmt || ! is_verbose ())
- return (0);
+ if (! fmt || ! is_verbose())
+ return 0;
- va_start (ap, fmt);
- retval = _einfovn (fmt, ap);
- retval += printf ("\n");
- va_end (ap);
+ va_start(ap, fmt);
+ retval = _einfovn(fmt, ap);
+ retval += printf("\n");
+ va_end(ap);
- LASTCMD ("einfov");
+ LASTCMD("einfov");
- return (retval);
+ return retval;
}
hidden_def(einfov)
-int ewarnv (const char *__EINFO_RESTRICT fmt, ...)
+int ewarnv(const char *__EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
- if (! fmt || ! is_verbose ())
- return (0);
+ if (! fmt || ! is_verbose())
+ return 0;
- va_start (ap, fmt);
- retval = _ewarnvn (fmt, ap);
- retval += printf ("\n");
- va_end (ap);
+ va_start(ap, fmt);
+ retval = _ewarnvn(fmt, ap);
+ retval += printf("\n");
+ va_end(ap);
- LASTCMD ("ewarnv");
+ LASTCMD("ewarnv");
- return (retval);
+ return retval;
}
hidden_def(ewarnv)
-int ebeginv (const char *__EINFO_RESTRICT fmt, ...)
+int ebeginv(const char *__EINFO_RESTRICT fmt, ...)
{
int retval;
va_list ap;
- if (! fmt || ! is_verbose ())
- return (0);
+ if (! fmt || ! is_verbose())
+ return 0;
- va_start (ap, fmt);
- retval = _einfovn (fmt, ap);
- retval += printf (" ...");
- if (colour_terminal (stdout))
- retval += printf ("\n");
- va_end (ap);
+ va_start(ap, fmt);
+ retval = _einfovn(fmt, ap);
+ retval += printf(" ...");
+ if (colour_terminal(stdout))
+ retval += printf("\n");
+ va_end(ap);
- LASTCMD ("ebeginv");
+ LASTCMD("ebeginv");
- return (retval);
+ return retval;
}
hidden_def(ebeginv)
-int eendv (int retval, const char *__EINFO_RESTRICT fmt, ...)
+int eendv(int retval, const char *__EINFO_RESTRICT fmt, ...)
{
va_list ap;
- if (! is_verbose ())
- return (0);
+ if (! is_verbose())
+ return 0;
- va_start (ap, fmt);
- _do_eend ("eendv", retval, fmt, ap);
- va_end (ap);
+ va_start(ap, fmt);
+ _do_eend("eendv", retval, fmt, ap);
+ va_end(ap);
- LASTCMD ("eendv");
+ LASTCMD("eendv");
- return (retval);
+ return retval;
}
hidden_def(eendv)
-int ewendv (int retval, const char *__EINFO_RESTRICT fmt, ...)
+int ewendv(int retval, const char *__EINFO_RESTRICT fmt, ...)
{
va_list ap;
- if (! is_verbose ())
- return (0);
+ if (! is_verbose())
+ return 0;
- va_start (ap, fmt);
- _do_eend ("ewendv", retval, fmt, ap);
- va_end (ap);
+ va_start(ap, fmt);
+ _do_eend("ewendv", retval, fmt, ap);
+ va_end(ap);
- LASTCMD ("ewendv");
+ LASTCMD("ewendv");
- return (retval);
+ return retval;
}
hidden_def(ewendv)
-void eindentv (void)
+void eindentv(void)
{
- if (is_verbose ())
+ if (is_verbose())
eindent ();
}
hidden_def(eindentv)
-void eoutdentv (void)
+void eoutdentv(void)
{
- if (is_verbose ())
- eoutdent ();
+ if (is_verbose())
+ eoutdent();
}
hidden_def(eoutdentv)
diff --git a/src/librc/.gitignore b/src/librc/.gitignore
index 5f6e3ee..eab6c70 100644
--- a/src/librc/.gitignore
+++ b/src/librc/.gitignore
@@ -3,12 +3,12 @@ librc.o
librc-daemon.o
librc-depend.o
librc-misc.o
-librc-strlist.o
+librc-stringlist.o
librc.So
librc-daemon.So
librc-depend.So
librc-misc.So
-librc-strlist.So
+librc-stringlist.So
librc.a
librc.so.1
librc.so
diff --git a/src/librc/Makefile b/src/librc/Makefile
index 78c97ce..15c396b 100644
--- a/src/librc/Makefile
+++ b/src/librc/Makefile
@@ -4,7 +4,7 @@ include ${MK}/os.mk
LIB= rc
SHLIB_MAJOR= 1
SRCS= librc.c librc-daemon.c librc-depend.c librc-misc.c \
- librc-strlist.c
+ librc-stringlist.c
INCS= rc.h
VERSION_MAP= rc.map
diff --git a/src/librc/librc-daemon.c b/src/librc/librc-daemon.c
index ca23ed2..9ae4ac2 100644
--- a/src/librc/librc-daemon.c
+++ b/src/librc/librc-daemon.c
@@ -32,33 +32,33 @@
#include "librc.h"
#if defined(__linux__)
-static bool pid_is_cmd (pid_t pid, const char *cmd)
+static bool pid_is_cmd(pid_t pid, const char *cmd)
{
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);
+ return false;
}
- while ((c = getc (fp)) != EOF && c == *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 *const *argv)
+static bool pid_is_exec(pid_t pid, const char *const *argv)
{
char cmdline[32];
char buffer[PATH_MAX];
@@ -66,31 +66,30 @@ static bool pid_is_exec (pid_t pid, const char *const *argv)
int fd = -1;
int r;
+ /* Check it's the right binary */
snprintf (cmdline, sizeof (cmdline), "/proc/%u/exe", pid);
memset (buffer, 0, sizeof (buffer));
-#if 0
- if (readlink (cmdline, buffer, sizeof (buffer)) != -1) {
- if (strcmp (exec, buffer) == 0)
- return (true);
+ if (readlink(cmdline, buffer, sizeof(buffer)) != -1) {
+ if (strcmp(*argv, 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) {
+ if (strlen(buffer) > 10) {
+ p = buffer + (strlen(buffer) - 10);
+ if (strcmp(p, " (deleted)") == 0) {
*p = 0;
- if (strcmp (buffer, exec) == 0)
- return (true);
+ if (strcmp(buffer, *argv) == 0)
+ return true;
}
}
}
-#endif
- snprintf (cmdline, sizeof (cmdline), "/proc/%u/cmdline", pid);
- if ((fd = open (cmdline, O_RDONLY)) < 0)
- return (false);
+ 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);
+ r = read(fd, buffer, sizeof(buffer));
+ close(fd);
if (r == -1)
return 0;
@@ -98,18 +97,18 @@ static bool pid_is_exec (pid_t pid, const char *const *argv)
buffer[r] = 0;
p = buffer;
while (*argv) {
- if (strcmp (*argv, p) != 0)
- return (false);
+ if (strcmp(*argv, p) != 0)
+ return false;
argv++;
- p += strlen (p) + 1;
+ p += strlen(p) + 1;
if ((unsigned) (p - buffer) > sizeof (buffer))
- return (false);
+ return false;
}
- return (true);
+ return true;
}
-pid_t *rc_find_pids (const char *const *argv, const char *cmd,
- uid_t uid, pid_t pid)
+pid_t *rc_find_pids(const char *const *argv, const char *cmd,
+ uid_t uid, pid_t pid)
{
DIR *procdir;
struct dirent *entry;
@@ -122,8 +121,8 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
pid_t runscript_pid = 0;
char *pp;
- if ((procdir = opendir ("/proc")) == NULL)
- return (NULL);
+ if ((procdir = opendir("/proc")) == NULL)
+ return NULL;
/*
We never match RC_RUNSCRIPT_PID if present so we avoid the below
@@ -136,13 +135,13 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
nasty
*/
- if ((pp = getenv ("RC_RUNSCRIPT_PID"))) {
- if (sscanf (pp, "%d", &runscript_pid) != 1)
+ 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)
+ while ((entry = readdir(procdir)) != NULL) {
+ if (sscanf(entry->d_name, "%d", &p) != 1)
continue;
if (runscript_pid != 0 && runscript_pid == p)
@@ -152,23 +151,23 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
continue;
if (uid) {
- snprintf (buffer, sizeof (buffer), "/proc/%d", p);
- if (stat (buffer, &sb) != 0 || sb.st_uid != uid)
+ snprintf(buffer, sizeof(buffer), "/proc/%d", p);
+ if (stat(buffer, &sb) != 0 || sb.st_uid != uid)
continue;
}
- if (cmd && ! pid_is_cmd (p, cmd))
+ if (cmd && ! pid_is_cmd(p, cmd))
continue;
- if (argv && ! cmd && ! pid_is_exec (p, (const char *const *)argv))
+ if (argv && ! cmd && ! pid_is_exec(p, (const char *const *)argv))
continue;
- tmp = realloc (pids, sizeof (pid_t) * (npids + 2));
+ tmp = realloc(pids, sizeof (pid_t) * (npids + 2));
if (! tmp) {
- free (pids);
- closedir (procdir);
+ free(pids);
+ closedir(procdir);
errno = ENOMEM;
- return (NULL);
+ return NULL;
}
pids = tmp;
@@ -176,9 +175,9 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
pids[npids + 1] = 0;
npids++;
}
- closedir (procdir);
+ closedir(procdir);
- return (pids);
+ return pids;
}
librc_hidden_def(rc_find_pids)
@@ -206,8 +205,8 @@ librc_hidden_def(rc_find_pids)
# define _KVM_FLAGS O_RDONLY
# endif
-pid_t *rc_find_pids (const char *const *argv, const char *cmd,
- uid_t uid, pid_t pid)
+pid_t *rc_find_pids(const char *const *argv, const char *cmd,
+ uid_t uid, pid_t pid)
{
static kvm_t *kd = NULL;
char errbuf[_POSIX2_LINE_MAX];
@@ -218,44 +217,45 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
char **pargv;
pid_t *pids = NULL;
pid_t *tmp;
+ pid_t p;
const char *const *arg;
int npids = 0;
int match;
- if ((kd = kvm_openfiles (_KVM_PATH, _KVM_PATH,
- NULL, _KVM_FLAGS, errbuf)) == NULL)
+ if ((kd = kvm_openfiles(_KVM_PATH, _KVM_PATH,
+ NULL, _KVM_FLAGS, errbuf)) == NULL)
{
- fprintf (stderr, "kvm_open: %s\n", errbuf);
- return (NULL);
+ fprintf(stderr, "kvm_open: %s\n", errbuf);
+ return NULL;
}
#ifdef _KVM_GETPROC2
- kp = kvm_getproc2 (kd, KERN_PROC_ALL, 0, sizeof(*kp), &processes);
+ kp = kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(*kp), &processes);
#else
- kp = kvm_getprocs (kd, KERN_PROC_PROC, 0, &processes);
+ kp = kvm_getprocs(kd, KERN_PROC_PROC, 0, &processes);
#endif
if ((kp == NULL && processes > 0) || (kp != NULL && processes < 0)) {
- fprintf (stderr, "kvm_getprocs: %s\n", kvm_geterr (kd));
- kvm_close (kd);
- return (NULL);
+ fprintf(stderr, "kvm_getprocs: %s\n", kvm_geterr(kd));
+ kvm_close(kd);
+ return NULL;
}
for (i = 0; i < processes; i++) {
- pid_t p = _GET_KINFO_PID (kp[i]);
+ p = _GET_KINFO_PID(kp[i]);
if (pid != 0 && pid != p)
continue;
- if (uid != 0 && uid != _GET_KINFO_UID (kp[i]))
+ 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)
+ if (! _GET_KINFO_COMM(kp[i]) ||
+ strcmp(cmd, _GET_KINFO_COMM(kp[i])) != 0)
continue;
}
if (argv && *argv && ! cmd) {
- pargv = _KVM_GETARGV (kd, &kp[i], pargc);
+ pargv = _KVM_GETARGV(kd, &kp[i], pargc);
if (! pargv || ! *pargv)
continue;
@@ -263,7 +263,7 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
match = 1;
while (*arg && *pargv)
- if (strcmp (*arg++, *pargv++) != 0) {
+ if (strcmp(*arg++, *pargv++) != 0) {
match = 0;
break;
}
@@ -272,12 +272,12 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
continue;
}
- tmp = realloc (pids, sizeof (pid_t) * (npids + 2));
+ tmp = realloc(pids, sizeof(pid_t) * (npids + 2));
if (! tmp) {
- free (pids);
- kvm_close (kd);
+ free(pids);
+ kvm_close(kd);
errno = ENOMEM;
- return (NULL);
+ return NULL;
}
pids = tmp;
@@ -285,9 +285,9 @@ pid_t *rc_find_pids (const char *const *argv, const char *cmd,
pids[npids + 1] = 0;
npids++;
}
- kvm_close (kd);
+ kvm_close(kd);
- return (pids);
+ return pids;
}
librc_hidden_def(rc_find_pids)
@@ -295,67 +295,72 @@ librc_hidden_def(rc_find_pids)
# error "Platform not supported!"
#endif
-static bool _match_daemon (const char *path, const char *file, char **match)
+static bool _match_daemon(const char *path, const char *file,
+ RC_STRINGLIST *match)
{
char *line;
- char *ffile = rc_strcatpaths (path, file, (char *) NULL);
+ char *ffile = rc_strcatpaths(path, file, (char *) NULL);
FILE *fp;
+ RC_STRING *m;
- fp = fopen (ffile, "r");
- free (ffile);
+ fp = fopen(ffile, "r");
+ free(ffile);
if (! fp)
- return (false);
+ return false;
- while ((line = rc_getline (fp))) {
- rc_strlist_delete (&match, line);
- if (! match || !*match)
+ while ((line = rc_getline(fp))) {
+ TAILQ_FOREACH(m, match, entries)
+ if (strcmp(line, m->value) == 0) {
+ TAILQ_REMOVE(match, m, entries);
+ break;
+ }
+ if (! TAILQ_FIRST(match))
break;
}
- fclose (fp);
- if (match && *match)
- return (false);
- return (true);
+ fclose(fp);
+ if (TAILQ_FIRST(match))
+ return false;
+ return true;
}
-static char **_match_list (const char* const* argv,
- const char *name, const char *pidfile)
+static RC_STRINGLIST *_match_list(const char* const* argv,
+ const char *name, const char *pidfile)
{
- char **match = NULL;
+ RC_STRINGLIST *match = rc_stringlist_new();
int i = 0;
size_t l;
char *m;
while (argv && argv[i]) {
- l = strlen (*argv) + strlen ("argv_=") + 16;
- m = xmalloc (sizeof (char) * l);
- snprintf (m, l, "argv_0=%s", argv[i++]);
- rc_strlist_add (&match, m);
- free (m);
+ l = strlen(*argv) + strlen("argv_=") + 16;
+ m = xmalloc(sizeof(char) * l);
+ snprintf(m, l, "argv_0=%s", argv[i++]);
+ rc_stringlist_add(match, m);
+ free(m);
}
if (name) {
- l = strlen (name) + 6;
- m = xmalloc (sizeof (char) * l);
- snprintf (m, l, "name=%s", name);
- rc_strlist_add (&match, m);
- free (m);
+ l = strlen(name) + 6;
+ m = xmalloc(sizeof (char) * l);
+ snprintf(m, l, "name=%s", name);
+ rc_stringlist_add(match, m);
+ free(m);
}
if (pidfile) {
- l = strlen (pidfile) + 9;
- m = xmalloc (sizeof (char) * l);
- snprintf (m, l, "pidfile=%s", pidfile);
- rc_strlist_add (&match, m);
+ l = strlen(pidfile) + 9;
+ m = xmalloc(sizeof (char) * l);
+ snprintf(m, l, "pidfile=%s", pidfile);
+ rc_stringlist_add(match, m);
free (m);
}
- return (match);
+ return match;
}
-bool rc_service_daemon_set (const char *service, const char *const *argv,
- const char *name, const char *pidfile,
- bool started)
+bool rc_service_daemon_set(const char *service, const char *const *argv,
+ const char *name, const char *pidfile, bool started)
{
char *dirpath;
char *file = NULL;
@@ -364,123 +369,123 @@ bool rc_service_daemon_set (const char *service, const char *const *argv,
bool retval = false;
DIR *dp;
struct dirent *d;
- char **match = NULL;
+ RC_STRINGLIST *match;
int i = 0;
+ char buffer[10];
+ FILE *fp;
- if (! (argv && *argv) && ! name && ! pidfile) {
+ if (!(argv && *argv) && ! name && ! pidfile) {
errno = EINVAL;
- return (false);
+ return false;
}
- dirpath = rc_strcatpaths (RC_SVCDIR, "daemons",
- basename_c (service), (char *) NULL);
+ dirpath = rc_strcatpaths(RC_SVCDIR, "daemons",
+ basename_c(service), (char *) NULL);
- match = _match_list (argv, name, pidfile);
+ match = _match_list(argv, name, pidfile);
/* Regardless, erase any existing daemon info */
- if ((dp = opendir (dirpath))) {
- while ((d = readdir (dp))) {
+ if ((dp = opendir(dirpath))) {
+ while ((d = readdir(dp))) {
if (d->d_name[0] == '.')
continue;
- file = rc_strcatpaths (dirpath, d->d_name, (char *) NULL);
+ file = rc_strcatpaths(dirpath, d->d_name, (char *) NULL);
nfiles++;
if (! oldfile) {
- if (_match_daemon (dirpath, d->d_name, match)) {
+ if (_match_daemon(dirpath, d->d_name, match)) {
unlink (file);
oldfile = file;
nfiles--;
}
} else {
- rename (file, oldfile);
- free (oldfile);
+ rename(file, oldfile);
+ free(oldfile);
oldfile = file;
}
}
- free (file);
- closedir (dp);
+ free(file);
+ closedir(dp);
}
/* Now store our daemon info */
if (started) {
- char buffer[10];
- FILE *fp;
-
- if (mkdir (dirpath, 0755) == 0 || errno == EEXIST) {
- snprintf (buffer, sizeof (buffer), "%03d", nfiles + 1);
- file = rc_strcatpaths (dirpath, buffer, (char *) NULL);
- if ((fp = fopen (file, "w"))) {
+ if (mkdir(dirpath, 0755) == 0 || errno == EEXIST) {
+ snprintf(buffer, sizeof(buffer), "%03d", nfiles + 1);
+ file = rc_strcatpaths(dirpath, buffer, (char *) NULL);
+ if ((fp = fopen(file, "w"))) {
while (argv && argv[i]) {
- fprintf (fp, "argv_%d=%s\n", i, argv[i]);
+ fprintf(fp, "argv_%d=%s\n", i, argv[i]);
i++;
}
- fprintf (fp, "name=");
+ fprintf(fp, "name=");
if (name)
- fprintf (fp, "%s", name);
- fprintf (fp, "\npidfile=");
+ fprintf(fp, "%s", name);
+ fprintf(fp, "\npidfile=");
if (pidfile)
- fprintf (fp, "%s", pidfile);
- fprintf (fp, "\n");
- fclose (fp);
+ fprintf(fp, "%s", pidfile);
+ fprintf(fp, "\n");
+ fclose(fp);
retval = true;
}
- free (file);
+ free(file);
}
} else
retval = true;
- rc_strlist_free (match);
- free (dirpath);
+ rc_stringlist_free(match);
+ free(dirpath);
- return (retval);
+ return retval;
}
librc_hidden_def(rc_service_daemon_set)
-bool rc_service_started_daemon (const char *service, const char *const *argv,
- int indx)
+bool
+rc_service_started_daemon (const char *service, const char *const *argv,
+ int indx)
{
char *dirpath;
char *file;
size_t l;
- char **match;
+ RC_STRINGLIST *match;
bool retval = false;
DIR *dp;
struct dirent *d;
- if (! service || ! (argv && *argv))
- return (false);
+ if (!service || !(argv && *argv))
+ return false;
- dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename_c (service),
- (char *) NULL);
+ dirpath = rc_strcatpaths(RC_SVCDIR, "daemons", basename_c(service),
+ (char *) NULL);
- match = _match_list (argv, NULL, NULL);
+ match = _match_list(argv, NULL, NULL);
if (indx > 0) {
l = sizeof (char) * 10;
- file = xmalloc (l);
- snprintf (file, l, "%03d", indx);
- retval = _match_daemon (dirpath, file, match);
- free (file);
+ file = xmalloc(l);
+ snprintf(file, l, "%03d", indx);
+ retval = _match_daemon(dirpath, file, match);
+ free(file);
} else {
- if ((dp = opendir (dirpath))) {
- while ((d = readdir (dp))) {
+ if ((dp = opendir(dirpath))) {
+ while ((d = readdir(dp))) {
if (d->d_name[0] == '.')
continue;
- retval = _match_daemon (dirpath, d->d_name, match);
+ retval = _match_daemon(dirpath, d->d_name, match);
if (retval)
break;
}
- closedir (dp);
+ closedir(dp);
}
}
- free (dirpath);
- rc_strlist_free (match);
- return (retval);
+ free(dirpath);
+ rc_stringlist_free(match);
+ return retval;
}
librc_hidden_def(rc_service_started_daemon)
-bool rc_service_daemons_crashed (const char *service)
+bool rc_service_daemons_crashed(const char *service)
{
char *dirpath;
DIR *dp;
@@ -497,116 +502,123 @@ bool rc_service_daemons_crashed (const char *service)
char *p;
char *token;
bool retval = false;
+ RC_STRINGLIST *list;
+ RC_STRING *s;
+ size_t i;
- if (! service)
- return (false);
+ dirpath = rc_strcatpaths(RC_SVCDIR, "daemons", basename_c(service),
+ (char *) NULL);
- dirpath = rc_strcatpaths (RC_SVCDIR, "daemons", basename_c (service),
- (char *) NULL);
-
- if (! (dp = opendir (dirpath))) {
- free (dirpath);
- return (false);
+ if (! (dp = opendir(dirpath))) {
+ free(dirpath);
+ return false;
}
- while ((d = readdir (dp))) {
+ while ((d = readdir(dp))) {
if (d->d_name[0] == '.')
continue;
- path = rc_strcatpaths (dirpath, d->d_name, (char *) NULL);
- fp = fopen (path, "r");
- free (path);
+ path = rc_strcatpaths(dirpath, d->d_name, (char *) NULL);
+ fp = fopen(path, "r");
+ free(path);
if (! fp)
break;
- while ((line = rc_getline (fp))) {
+ list = rc_stringlist_new();
+
+ while ((line = rc_getline(fp))) {
p = line;
- if ((token = strsep (&p, "=")) == NULL || ! p) {
- free (line);
+ if ((token = strsep(&p, "=")) == NULL || ! p) {
+ free(line);
continue;
}
- if (strlen (p) == 0) {
- free (line);
+ if (! *p) {
+ free(line);
continue;
}
- if (strncmp (token, "argv_", 5) == 0) {
- rc_strlist_add (&argv, p);
- } else if (strcmp (token, "exec") == 0) {
+ if (strncmp(token, "argv_", 5) == 0) {
+ rc_stringlist_add(list, p);
+ } else if (strcmp(token, "exec") == 0) {
if (exec)
- free (exec);
- exec = xstrdup (p);
- } else if (strcmp (token, "name") == 0) {
+ free(exec);
+ exec = xstrdup(p);
+ } else if (strcmp(token, "name") == 0) {
if (name)
- free (name);
- name = xstrdup (p);
- } else if (strcmp (token, "pidfile") == 0) {
+ free(name);
+ name = xstrdup(p);
+ } else if (strcmp(token, "pidfile") == 0) {
if (pidfile)
- free (pidfile);
- pidfile = xstrdup (p);
+ free(pidfile);
+ pidfile = xstrdup(p);
}
- free (line);
+ free(line);
}
- fclose (fp);
+ fclose(fp);
pid = 0;
if (pidfile) {
- if (! exists (pidfile)) {
+ if (! exists(pidfile)) {
retval = true;
break;
}
- if ((fp = fopen (pidfile, "r")) == NULL) {
+ if ((fp = fopen(pidfile, "r")) == NULL) {
retval = true;
break;
}
- if (fscanf (fp, "%d", &pid) != 1) {
+ if (fscanf(fp, "%d", &pid) != 1) {
fclose (fp);
retval = true;
break;
}
- fclose (fp);
- free (pidfile);
+ fclose(fp);
+ free(pidfile);
pidfile = NULL;
/* We have the pid, so no need to match on name */
- rc_strlist_free (argv);
- argv = NULL;
+ rc_stringlist_free(list);
+ list = NULL;
free (exec);
exec = NULL;
free (name);
name = NULL;
- }
-
- if (exec && ! argv) {
- rc_strlist_add (&argv, exec);
- free (exec);
+ } else {
+ if (exec && ! TAILQ_FIRST(list)) {
+ rc_stringlist_add(list, exec);
+ }
+ free(exec);
exec = NULL;
- }
- if ((pids = rc_find_pids ((const char *const *)argv, name, 0, pid)) == NULL) {
- retval = true;
- break;
+ /* We need to flatten our linked list into an array */
+ i = 0;
+ TAILQ_FOREACH(s, list, entries)
+ i++;
+ argv = xmalloc(sizeof(char *) * (i + 1));
+ i = 0;
+ TAILQ_FOREACH(s, list, entries)
+ argv[i++] = s->value;
+ argv[i] = '\0';
}
- free (pids);
- rc_strlist_free (argv);
+ if ((pids = rc_find_pids((const char *const *)argv, name, 0, pid)) == NULL)
+ retval = true;
+ free(pids);
+ free(argv);
argv = NULL;
- free (exec);
- exec = NULL;
- free (name);
+ rc_stringlist_free(list);
+ free(name);
name = NULL;
+ if (retval)
+ break;
}
- rc_strlist_free (argv);
- free (exec);
- free (name);
- free (dirpath);
- closedir (dp);
+ free(dirpath);
+ closedir(dp);
- return (retval);
+ return retval;
}
librc_hidden_def(rc_service_daemons_crashed)
diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c
index 2247036..8617d75 100644
--- a/src/librc/librc-depend.c
+++ b/src/librc/librc-depend.c
@@ -37,31 +37,18 @@
static const char *bootlevel = NULL;
-/* We use this so we can pass our char array through many functions */
-struct lhead
-{
- char **list;
-};
-
-static void *xzalloc (size_t size)
-{
- void *value = xmalloc (size);
- memset (value, 0, size);
- return (value);
-}
-
-static char *get_shell_value (char *string)
+static char *get_shell_value(char *string)
{
char *p = string;
char *e;
if (! string)
- return (NULL);
+ return NULL;
if (*p == '\'')
p++;
- e = p + strlen (p) - 1;
+ e = p + strlen(p) - 1;
if (*e == '\n')
*e-- = 0;
if (*e == '\'')
@@ -70,191 +57,184 @@ static char *get_shell_value (char *string)
if (*p != 0)
return p;
- return (NULL);
+ return NULL;
}
-void rc_deptree_free (rc_depinfo_t *deptree)
+void rc_deptree_free(RC_DEPTREE *deptree)
{
- rc_depinfo_t *di = deptree;
+ RC_DEPINFO *di;
+ RC_DEPINFO *di2;
+ RC_DEPTYPE *dt;
+ RC_DEPTYPE *dt2;
+
+ if (! deptree)
+ return;
+
+ di = STAILQ_FIRST(deptree);
while (di)
{
- rc_depinfo_t *dip = di->next;
- rc_deptype_t *dt = di->depends;
- free (di->service);
+ di2 = STAILQ_NEXT(di, entries);
+ dt = STAILQ_FIRST(&di->depends);
while (dt)
{
- rc_deptype_t *dtp = dt->next;
- free (dt->type);
- rc_strlist_free (dt->services);
- free (dt);
- dt = dtp;
+ dt2 = STAILQ_NEXT(dt, entries);
+ rc_stringlist_free(dt->services);
+ free(dt->type);
+ free(dt);
+ dt = dt2;
}
- free (di);
- di = dip;
+ free(di->service);
+ free(di);
+ di = di2;
}
+ free(deptree);
}
librc_hidden_def(rc_deptree_free)
-static rc_depinfo_t *get_depinfo (const rc_depinfo_t *deptree,
- const char *service)
+static RC_DEPINFO *get_depinfo(const RC_DEPTREE *deptree,
+ const char *service)
{
- const rc_depinfo_t *di;
-
- if (! deptree || ! service)
- return (NULL);
+ RC_DEPINFO *di;
- for (di = deptree; di; di = di->next)
- if (strcmp (di->service, service) == 0)
- return ((rc_depinfo_t *)di);
+ STAILQ_FOREACH(di, deptree, entries)
+ if (strcmp(di->service, service) == 0)
+ return di;
- return (NULL);
+ return NULL;
}
-static rc_deptype_t *get_deptype (const rc_depinfo_t *depinfo,
- const char *type)
+static RC_DEPTYPE *get_deptype(const RC_DEPINFO *depinfo,
+ const char *type)
{
- rc_deptype_t *dt;
+ RC_DEPTYPE *dt;
- if (! depinfo || !type)
- return (NULL);
+ STAILQ_FOREACH(dt, &depinfo->depends, entries)
+ if (strcmp(dt->type, type) == 0)
+ return dt;
- for (dt = depinfo->depends; dt; dt = dt->next)
- if (strcmp (dt->type, type) == 0)
- return (dt);
-
- return (NULL);
+ return NULL;
}
-rc_depinfo_t *rc_deptree_load (void)
+RC_DEPTREE *rc_deptree_load(void)
{
FILE *fp;
- rc_depinfo_t *deptree = NULL;
- rc_depinfo_t *depinfo = NULL;
- rc_deptype_t *deptype = NULL;
+ RC_DEPTREE *deptree;
+ RC_DEPINFO *depinfo = NULL;
+ RC_DEPTYPE *deptype = NULL;
char *line;
char *type;
char *p;
char *e;
int i;
- if (! (fp = fopen (RC_DEPTREE, "r")))
- return (NULL);
+ if (!(fp = fopen(RC_DEPTREE_CACHE, "r")))
+ return NULL;
+
+ deptree = xmalloc(sizeof(*deptree));
+ STAILQ_INIT(deptree);
- while ((line = rc_getline (fp)))
+ while ((line = rc_getline(fp)))
{
p = line;
- e = strsep (&p, "_");
- if (! e || strcmp (e, "depinfo") != 0)
+ e = strsep(&p, "_");
+ if (! e || strcmp(e, "depinfo") != 0)
goto next;
e = strsep (&p, "_");
- if (! e || sscanf (e, "%d", &i) != 1)
+ if (! e || sscanf(e, "%d", &i) != 1)
goto next;
- if (! (type = strsep (&p, "_=")))
+ if (! (type = strsep(&p, "_=")))
goto next;
- if (strcmp (type, "service") == 0)
+ if (strcmp(type, "service") == 0)
{
/* Sanity */
- e = get_shell_value (p);
+ e = get_shell_value(p);
if (! e || *e == '\0')
goto next;
- if (! deptree)
- {
- deptree = xzalloc (sizeof (*deptree));
- depinfo = deptree;
- }
- else
- {
- depinfo->next = xzalloc (sizeof (*depinfo->next));
- depinfo = depinfo->next;
- }
- depinfo->service = xstrdup (e);
+ depinfo = xmalloc(sizeof(*depinfo));
+ STAILQ_INIT(&depinfo->depends);
+ depinfo->service = xstrdup(e);
+ STAILQ_INSERT_TAIL(deptree, depinfo, entries);
deptype = NULL;
goto next;
}
- e = strsep (&p, "=");
- if (! e || sscanf (e, "%d", &i) != 1)
+ e = strsep(&p, "=");
+ if (! e || sscanf(e, "%d", &i) != 1)
goto next;
/* Sanity */
- e = get_shell_value (p);
+ e = get_shell_value(p);
if (! e || *e == '\0')
goto next;
- if (! deptype)
- {
- depinfo->depends = xzalloc (sizeof (*depinfo->depends));
- deptype = depinfo->depends;
- }
- else
- if (strcmp (deptype->type, type) != 0)
- {
- deptype->next = xzalloc (sizeof (*deptype->next));
- deptype = deptype->next;
- }
-
- if (! deptype->type)
+ if (! deptype || strcmp(deptype->type, type) != 0) {
+ deptype = xmalloc(sizeof(*deptype));
+ deptype->services = rc_stringlist_new();
deptype->type = xstrdup (type);
+ STAILQ_INSERT_TAIL(&depinfo->depends, deptype, entries);
+ }
- rc_strlist_addsort (&deptype->services, e);
-
+ rc_stringlist_add(deptype->services, e);
next:
- free (line);
+ free(line);
}
- fclose (fp);
-
- return (deptree);
+ fclose(fp);
+
+ return deptree;
}
librc_hidden_def(rc_deptree_load)
-static bool valid_service (const char *runlevel, const char *service)
+static bool valid_service(const char *runlevel, const char *service)
{
- rc_service_state_t state = rc_service_state (service);
+ RC_SERVICE state = rc_service_state(service);
return ((strcmp (runlevel, bootlevel) != 0 &&
- rc_service_in_runlevel (service, bootlevel)) ||
- rc_service_in_runlevel (service, runlevel) ||
+ rc_service_in_runlevel(service, bootlevel)) ||
+ rc_service_in_runlevel(service, runlevel) ||
state & RC_SERVICE_COLDPLUGGED ||
state & RC_SERVICE_STARTED);
}
-static bool get_provided1 (const char *runlevel, struct lhead *providers,
- rc_deptype_t *deptype,
- const char *level, bool coldplugged,
- rc_service_state_t state)
+static bool get_provided1(const char *runlevel, RC_STRINGLIST *providers,
+ RC_DEPTYPE *deptype,
+ const char *level, bool coldplugged,
+ RC_SERVICE state)
{
- char *service;
- int i;
+ RC_STRING *service;
+ RC_SERVICE st;
bool retval = false;
+ bool ok;
+ const char *svc;
+
+ TAILQ_FOREACH(service, deptype->services, entries) {
+ ok = true;
+ svc = service->value;
+ st = rc_service_state(svc);
- STRLIST_FOREACH (deptype->services, service, i)
- {
- bool ok = true;
- rc_service_state_t s = rc_service_state (service);
if (level)
- ok = rc_service_in_runlevel (service, level);
+ ok = rc_service_in_runlevel(svc, level);
else if (coldplugged)
- ok = (s & RC_SERVICE_COLDPLUGGED &&
- ! rc_service_in_runlevel (service, runlevel) &&
- ! rc_service_in_runlevel (service, bootlevel));
+ ok = (st & RC_SERVICE_COLDPLUGGED &&
+ ! rc_service_in_runlevel(svc, runlevel) &&
+ ! rc_service_in_runlevel(svc, bootlevel));
if (! ok)
continue;
switch (state) {
case RC_SERVICE_STARTED:
- ok = (s & RC_SERVICE_STARTED);
+ ok = (st & RC_SERVICE_STARTED);
break;
case RC_SERVICE_INACTIVE:
case RC_SERVICE_STARTING:
case RC_SERVICE_STOPPING:
- ok = (s & RC_SERVICE_STARTING ||
- s & RC_SERVICE_STOPPING ||
- s & RC_SERVICE_INACTIVE);
+ ok = (st & RC_SERVICE_STARTING ||
+ st & RC_SERVICE_STOPPING ||
+ st & RC_SERVICE_INACTIVE);
break;
default:
break;
@@ -264,10 +244,10 @@ static bool get_provided1 (const char *runlevel, struct lhead *providers,
continue;
retval = true;
- rc_strlist_add (&providers->list, service);
+ rc_stringlist_add(providers, svc);
}
- return (retval);
+ return retval;
}
/* Work out if a service is provided by another service.
@@ -279,50 +259,41 @@ static bool get_provided1 (const char *runlevel, struct lhead *providers,
If there are any bugs in rc-depend, they will probably be here as
provided dependancy can change depending on runlevel state.
*/
-static char **get_provided (const rc_depinfo_t *deptree,
- const rc_depinfo_t *depinfo,
- const char *runlevel, int options)
+static RC_STRINGLIST *get_provided (const RC_DEPINFO *depinfo,
+ const char *runlevel, int options)
{
- rc_deptype_t *dt;
- struct lhead providers;
- char *service;
- int i;
+ RC_DEPTYPE *dt;
+ RC_STRINGLIST *providers = rc_stringlist_new();
+ RC_STRING *service;
- if (! deptree || ! depinfo)
- return (NULL);
-
- if (rc_service_exists (depinfo->service))
- return (NULL);
-
- dt = get_deptype (depinfo, "providedby");
+ dt = get_deptype(depinfo, "providedby");
if (! dt)
- return (NULL);
+ return providers;
- memset (&providers, 0, sizeof (providers));
/* If we are stopping then all depends are true, regardless of state.
This is especially true for net services as they could force a restart
of the local dns resolver which may depend on net. */
if (options & RC_DEP_STOP)
{
- STRLIST_FOREACH (dt->services, service, i)
- rc_strlist_add (&providers.list, service);
-
- return (providers.list);
+ TAILQ_FOREACH(service, dt->services, entries)
+ rc_stringlist_add(providers, service->value);
+ return providers;
}
/* If we're strict or startng, then only use what we have in our
* runlevel and bootlevel. If we starting then check cold-plugged too. */
if (options & RC_DEP_STRICT || options & RC_DEP_START)
{
- STRLIST_FOREACH (dt->services, service, i)
- if (rc_service_in_runlevel (service, runlevel) ||
- rc_service_in_runlevel (service, bootlevel) ||
+
+ TAILQ_FOREACH(service, dt->services, entries)
+ if (rc_service_in_runlevel(service->value, runlevel) ||
+ rc_service_in_runlevel(service->value, bootlevel) ||
(options & RC_DEP_START &&
- rc_service_state (service) & RC_SERVICE_COLDPLUGGED))
- rc_strlist_add (&providers.list, service);
+ rc_service_state(service->value) & RC_SERVICE_COLDPLUGGED))
+ rc_stringlist_add(providers, service->value);
- if (providers.list)
- return (providers.list);
+ if (TAILQ_FIRST(providers))
+ return providers;
}
/* OK, we're not strict or there were no services in our runlevel.
@@ -333,225 +304,211 @@ static char **get_provided (const rc_depinfo_t *deptree,
We apply this to our runlevel, coldplugged services, then bootlevel
and finally any running.*/
#define DO \
- if (providers.list && providers.list[0] && providers.list[1]) \
- { \
- rc_strlist_free (providers.list); \
- return (NULL); \
- } \
- else if (providers.list) \
- return providers.list; \
+ if (TAILQ_FIRST(providers)) { \
+ if (TAILQ_NEXT(TAILQ_FIRST(providers), entries)) { \
+ rc_stringlist_free(providers); \
+ providers = rc_stringlist_new(); \
+ } \
+ return providers; \
+ }
/* Anything in the runlevel has to come first */
- if (get_provided1 (runlevel, &providers, dt, runlevel, false, RC_SERVICE_STARTED))
+ if (get_provided1 (runlevel, providers, dt, runlevel, false, RC_SERVICE_STARTED))
{ DO }
- if (get_provided1 (runlevel, &providers, dt, runlevel, false, RC_SERVICE_STARTING))
- return (providers.list);
- if (get_provided1 (runlevel, &providers, dt, runlevel, false, RC_SERVICE_STOPPED))
- return (providers.list);
+ if (get_provided1 (runlevel, providers, dt, runlevel, false, RC_SERVICE_STARTING))
+ return providers;
+ if (get_provided1 (runlevel, providers, dt, runlevel, false, RC_SERVICE_STOPPED))
+ return providers;
/* Check coldplugged services */
- if (get_provided1 (runlevel, &providers, dt, NULL, true, RC_SERVICE_STARTED))
+ if (get_provided1 (runlevel, providers, dt, NULL, true, RC_SERVICE_STARTED))
{ DO }
- if (get_provided1 (runlevel, &providers, dt, NULL, true, RC_SERVICE_STARTING))
- return (providers.list);
+ if (get_provided1 (runlevel, providers, dt, NULL, true, RC_SERVICE_STARTING))
+ return providers;
/* Check bootlevel if we're not in it */
if (bootlevel && strcmp (runlevel, bootlevel) != 0)
{
- if (get_provided1 (runlevel, &providers, dt, bootlevel, false, RC_SERVICE_STARTED))
+ if (get_provided1 (runlevel, providers, dt, bootlevel, false, RC_SERVICE_STARTED))
{ DO }
- if (get_provided1 (runlevel, &providers, dt, bootlevel, false, RC_SERVICE_STARTING))
- return (providers.list);
+ if (get_provided1 (runlevel, providers, dt, bootlevel, false, RC_SERVICE_STARTING))
+ return providers;
}
/* Check coldplugged services */
- if (get_provided1 (runlevel, &providers, dt, NULL, true, RC_SERVICE_STOPPED))
+ if (get_provided1 (runlevel, providers, dt, NULL, true, RC_SERVICE_STOPPED))
{ DO }
/* Check manually started */
- if (get_provided1 (runlevel, &providers, dt, NULL, false, RC_SERVICE_STARTED))
+ if (get_provided1 (runlevel, providers, dt, NULL, false, RC_SERVICE_STARTED))
{ DO }
- if (get_provided1 (runlevel, &providers, dt, NULL, false, RC_SERVICE_STARTING))
- return (providers.list);
+ if (get_provided1 (runlevel, providers, dt, NULL, false, RC_SERVICE_STARTING))
+ return providers;
/* Nothing started then. OK, lets get the stopped services */
- if (get_provided1 (runlevel, &providers, dt, runlevel, false, RC_SERVICE_STOPPED))
- return (providers.list);
+ if (get_provided1 (runlevel, providers, dt, runlevel, false, RC_SERVICE_STOPPED))
+ return providers;
if (bootlevel && (strcmp (runlevel, bootlevel) != 0)
- && (get_provided1 (runlevel, &providers, dt, bootlevel, false, RC_SERVICE_STOPPED)))
- return (providers.list);
+ && (get_provided1 (runlevel, providers, dt, bootlevel, false, RC_SERVICE_STOPPED)))
+ return providers;
/* Still nothing? OK, list all services */
- STRLIST_FOREACH (dt->services, service, i)
- rc_strlist_add (&providers.list, service);
+ TAILQ_FOREACH(service, dt->services, entries)
+ rc_stringlist_add(providers, service->value);
- return (providers.list);
+ return providers;
}
-static void visit_service (const rc_depinfo_t *deptree,
- const char * const *types,
- struct lhead *sorted, struct lhead *visited,
- const rc_depinfo_t *depinfo,
+static void visit_service (const RC_DEPTREE *deptree,
+ const RC_STRINGLIST *types,
+ RC_STRINGLIST *sorted,
+ RC_STRINGLIST *visited,
+ const RC_DEPINFO *depinfo,
const char *runlevel, int options)
{
- int i, j, k;
- char *lp;
- const char *item;
- char *service;
- rc_depinfo_t *di;
- rc_deptype_t *dt;
- char **provides;
- char *svcname;
-
- if (! deptree || !sorted || !visited || !depinfo)
- return;
+ RC_STRING *type;
+ RC_STRING *service;
+ RC_DEPTYPE *dt;
+ RC_DEPINFO *di;
+ RC_STRINGLIST *provided;
+ RC_STRING *p;
+ const char *svcname;
/* Check if we have already visited this service or not */
- STRLIST_FOREACH (visited->list, item, i)
- if (strcmp (item, depinfo->service) == 0)
+ TAILQ_FOREACH(type, visited, entries)
+ if (strcmp(type->value, depinfo->service) == 0)
return;
/* Add ourselves as a visited service */
- rc_strlist_add (&visited->list, depinfo->service);
+ rc_stringlist_add(visited, depinfo->service);
- STRLIST_FOREACH (types, item, i)
+ TAILQ_FOREACH(type, types, entries)
{
- if ((dt = get_deptype (depinfo, item)))
- {
- STRLIST_FOREACH (dt->services, service, j)
+ if (!(dt = get_deptype(depinfo, type->value)))
+ continue;
+
+ TAILQ_FOREACH(service, dt->services, entries) {
+ if (! options & RC_DEP_TRACE ||
+ strcmp(type->value, "iprovide") == 0)
{
- if (! options & RC_DEP_TRACE || strcmp (item, "iprovide") == 0)
- {
- rc_strlist_add (&sorted->list, service);
- continue;
- }
+ rc_stringlist_add(sorted, service->value);
+ continue;
+ }
- di = get_depinfo (deptree, service);
- if ((provides = get_provided (deptree, di, runlevel, options)))
- {
- STRLIST_FOREACH (provides, lp, k)
- {
- di = get_depinfo (deptree, lp);
- if (di && (strcmp (item, "ineed") == 0 ||
- strcmp (item, "needsme") == 0 ||
- valid_service (runlevel, di->service)))
- visit_service (deptree, types, sorted, visited, di,
- runlevel, options | RC_DEP_TRACE);
- }
- rc_strlist_free (provides);
+ if (!(di = get_depinfo(deptree, service->value)))
+ continue;
+ provided = get_provided(di, runlevel, options);
+
+ if (TAILQ_FIRST(provided)) {
+ TAILQ_FOREACH(p, provided, entries) {
+ di = get_depinfo(deptree, p->value);
+ if (di &&
+ (strcmp(type->value, "ineed") == 0 ||
+ strcmp(type->value, "needsme") == 0 ||
+ valid_service(runlevel, di->service)))
+ visit_service(deptree, types, sorted, visited, di,
+ runlevel, options | RC_DEP_TRACE);
}
- else
- if (di && (strcmp (item, "ineed") == 0 ||
- strcmp (item, "needsme") == 0 ||
- valid_service (runlevel, service)))
- visit_service (deptree, types, sorted, visited, di,
- runlevel, options | RC_DEP_TRACE);
}
+ else if (di &&
+ (strcmp(type->value, "ineed") == 0 ||
+ strcmp(type->value, "needsme") == 0 ||
+ valid_service(runlevel, service->value)))
+ visit_service(deptree, types, sorted, visited, di,
+ runlevel, options | RC_DEP_TRACE);
+
+ rc_stringlist_free(provided);
}
}
/* Now visit the stuff we provide for */
if (options & RC_DEP_TRACE &&
- (dt = get_deptype (depinfo, "iprovide")))
+ (dt = get_deptype(depinfo, "iprovide")))
{
- STRLIST_FOREACH (dt->services, service, i)
- {
- if ((di = get_depinfo (deptree, service)))
- if ((provides = get_provided (deptree, di, runlevel, options)))
- {
- STRLIST_FOREACH (provides, lp, j)
- if (strcmp (lp, depinfo->service) == 0)
- {
- visit_service (deptree, types, sorted, visited, di,
- runlevel, options | RC_DEP_TRACE);
- break;
- }
- rc_strlist_free (provides);
+ TAILQ_FOREACH(service, dt->services, entries) {
+ if (!(di = get_depinfo(deptree, service->value)))
+ continue;
+
+ provided = get_provided(di, runlevel, options);
+ TAILQ_FOREACH(p, provided, entries)
+ if (strcmp (p->value, depinfo->service) == 0) {
+ //visit_service (deptree, types, sorted, visited, di,
+ // runlevel, options | RC_DEP_TRACE);
+ break;
}
+ rc_stringlist_free(provided);
}
}
/* We've visited everything we need, so add ourselves unless we
are also the service calling us or we are provided by something */
svcname = getenv("SVCNAME");
- if (! svcname || strcmp (svcname, depinfo->service) != 0)
- if (! get_deptype (depinfo, "providedby"))
- rc_strlist_add (&sorted->list, depinfo->service);
+ if (! svcname || strcmp(svcname, depinfo->service) != 0)
+ if (! get_deptype(depinfo, "providedby"))
+ rc_stringlist_add(sorted, depinfo->service);
}
-char **rc_deptree_depend (const rc_depinfo_t *deptree,
- const char *service, const char *type)
+RC_STRINGLIST *rc_deptree_depend(const RC_DEPTREE *deptree,
+ const char *service, const char *type)
{
- rc_depinfo_t *di;
- rc_deptype_t *dt;
- char **svcs = NULL;
- int i;
- char *svc;
+ RC_DEPINFO *di;
+ RC_DEPTYPE *dt;
+ RC_STRINGLIST *svcs;
+ RC_STRING *svc;
- if (! (di = get_depinfo (deptree, service)) ||
- ! (dt = get_deptype (di, type)))
+ if (!(di = get_depinfo(deptree, service)) ||
+ ! (dt = get_deptype(di, type)))
{
errno = ENOENT;
- return (NULL);
+ return NULL;
}
/* For consistency, we copy the array */
- STRLIST_FOREACH (dt->services, svc, i)
- rc_strlist_add (&svcs, svc);
+ svcs = rc_stringlist_new();
+ TAILQ_FOREACH(svc, dt->services, entries)
+ rc_stringlist_add(svcs, svc->value);
- return (svcs);
+ return svcs;
}
librc_hidden_def(rc_deptree_depend)
-char **rc_deptree_depends (const rc_depinfo_t *deptree,
- const char *const *types,
- const char *const *services,
- const char *runlevel, int options)
+RC_STRINGLIST *rc_deptree_depends (const RC_DEPTREE *deptree,
+ const RC_STRINGLIST *types,
+ const RC_STRINGLIST *services,
+ const char *runlevel, int options)
{
- struct lhead sorted;
- struct lhead visited;
- rc_depinfo_t *di;
- const char *service;
- int i;
-
- if (! deptree || ! services)
- return (NULL);
-
- memset (&sorted, 0, sizeof (sorted));
- memset (&visited, 0, sizeof (visited));
+ RC_STRINGLIST *sorted = rc_stringlist_new();
+ RC_STRINGLIST *visited = rc_stringlist_new();
+ RC_DEPINFO *di;
+ const RC_STRING *service;
bootlevel = getenv ("RC_BOOTLEVEL");
if (! bootlevel)
bootlevel = RC_LEVEL_BOOT;
- STRLIST_FOREACH (services, service, i)
- {
- if (! (di = get_depinfo (deptree, service))) {
+ TAILQ_FOREACH(service, services, entries) {
+ if (! (di = get_depinfo(deptree, service->value))) {
errno = ENOENT;
continue;
}
if (types)
- visit_service (deptree, types, &sorted, &visited,
+ visit_service (deptree, types, sorted, visited,
di, runlevel, options);
}
- rc_strlist_free (visited.list);
- return (sorted.list);
+ rc_stringlist_free (visited);
+ return sorted;
}
librc_hidden_def(rc_deptree_depends)
- static const char * const order_types[] = { "ineed", "iuse", "iafter", NULL };
-char **rc_deptree_order (const rc_depinfo_t *deptree, const char *runlevel,
- int options)
+RC_STRINGLIST *rc_deptree_order(const RC_DEPTREE *deptree,
+ const char *runlevel, int options)
{
- char **list = NULL;
- char **services = NULL;
- bool reverse = false;
- char **tmp = NULL;
-
- if (! runlevel)
- return (NULL);
+ RC_STRINGLIST *list;
+ RC_STRINGLIST *list2;
+ RC_STRINGLIST *types;
+ RC_STRINGLIST *services;
bootlevel = getenv ("RC_BOOTLEVEL");
if (! bootlevel)
@@ -562,47 +519,48 @@ char **rc_deptree_order (const rc_depinfo_t *deptree, const char *runlevel,
strcmp (runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
strcmp (runlevel, RC_LEVEL_REBOOT) == 0)
{
- list = rc_services_in_state (RC_SERVICE_STARTED);
+ list = rc_services_in_state(RC_SERVICE_STARTED);
- tmp = rc_services_in_state (RC_SERVICE_INACTIVE);
- rc_strlist_join (&list, tmp);
- rc_strlist_free (tmp);
+ list2 = rc_services_in_state (RC_SERVICE_INACTIVE);
+ TAILQ_CONCAT(list, list2);
+ free(list2);
- tmp = rc_services_in_state (RC_SERVICE_STARTING);
- rc_strlist_join (&list, tmp);
- rc_strlist_free (tmp);
- reverse = true;
+ list2 = rc_services_in_state (RC_SERVICE_STARTING);
+ TAILQ_CONCAT(list, list2);
+ free(list2);
} else {
list = rc_services_in_runlevel (runlevel);
/* Add coldplugged services */
- tmp = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
- rc_strlist_join (&list, tmp);
- rc_strlist_free (tmp);
+ list2 = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
+ TAILQ_CONCAT(list, list2);
+ free(list2);
/* If we're not the boot runlevel then add that too */
if (strcmp (runlevel, bootlevel) != 0) {
- tmp = rc_services_in_runlevel (bootlevel);
- rc_strlist_join (&list, tmp);
- rc_strlist_free (tmp);
+ list2 = rc_services_in_runlevel (bootlevel);
+ TAILQ_CONCAT(list, list2);
+ free(list2);
}
}
/* Now we have our lists, we need to pull in any dependencies
and order them */
- services = rc_deptree_depends (deptree, order_types, (const char **) list,
- runlevel,
- RC_DEP_STRICT | RC_DEP_TRACE | options);
- rc_strlist_free (list);
+ types = rc_stringlist_new();
+ rc_stringlist_add(types, "ineed");
+ rc_stringlist_add(types, "iuse");
+ rc_stringlist_add(types, "iafter");
- if (reverse)
- rc_strlist_reverse (services);
+ services = rc_deptree_depends(deptree, types, list, runlevel,
+ RC_DEP_STRICT | RC_DEP_TRACE | options);
+ rc_stringlist_free (list);
+ rc_stringlist_free (types);
- return (services);
+ return services;
}
librc_hidden_def(rc_deptree_order)
-bool rc_newer_than (const char *source, const char *target)
+bool rc_newer_than(const char *source, const char *target)
{
struct stat buf;
time_t mtime;
@@ -613,38 +571,38 @@ bool rc_newer_than (const char *source, const char *target)
int serrno = errno;
/* We have to exist */
- if (stat (source, &buf) != 0)
- return (false);
+ if (stat(source, &buf) != 0)
+ return false;
mtime = buf.st_mtime;
/* Of course we are newer than targets that don't exist
such as broken symlinks */
- if (stat (target, &buf) != 0)
- return (true);
+ if (stat(target, &buf) != 0)
+ return true;
if (mtime < buf.st_mtime)
- return (false);
+ return false;
/* If not a dir then reset errno */
- if (! (dp = opendir (target))) {
+ if (! (dp = opendir(target))) {
errno = serrno;
- return (true);
+ return true;
}
/* Check if we're newer than all the entries in the dir */
- while ((d = readdir (dp))) {
+ while ((d = readdir(dp))) {
if (d->d_name[0] == '.')
continue;
- path = rc_strcatpaths (target, d->d_name, (char *) NULL);
- newer = rc_newer_than (source, path);
- free (path);
+ path = rc_strcatpaths(target, d->d_name, (char *) NULL);
+ newer = rc_newer_than(source, path);
+ free(path);
if (! newer)
break;
}
- closedir (dp);
+ closedir(dp);
- return (newer);
+ return newer;
}
librc_hidden_def(rc_newer_than)
@@ -652,12 +610,12 @@ typedef struct deppair
{
const char *depend;
const char *addto;
-} deppair_t;
+} DEPPAIR;
-static const deppair_t deppairs[] = {
- { "ineed", "needsme" },
- { "iuse", "usesme" },
- { "iafter", "ibefore" },
+static const DEPPAIR deppairs[] = {
+ { "ineed", "needsme" },
+ { "iuse", "usesme" },
+ { "iafter", "ibefore" },
{ "ibefore", "iafter" },
{ "iprovide", "providedby" },
{ NULL, NULL }
@@ -679,168 +637,151 @@ static const char *const depdirs[] =
NULL
};
-bool rc_deptree_update_needed (void)
+bool rc_deptree_update_needed(void)
{
bool newer = false;
- char **config;
- char *service;
+ RC_STRINGLIST *config;
+ RC_STRING *s;
int i;
/* Create base directories if needed */
for (i = 0; depdirs[i]; i++)
- if (mkdir (depdirs[i], 0755) != 0 && errno != EEXIST)
- fprintf (stderr, "mkdir `%s': %s\n", depdirs[i], strerror (errno));
+ if (mkdir(depdirs[i], 0755) != 0 && errno != EEXIST)
+ fprintf(stderr, "mkdir `%s': %s\n", depdirs[i], strerror (errno));
/* Quick test to see if anything we use has changed and we have
* data in our deptree */
- if (! existss (RC_DEPTREE) ||
- ! rc_newer_than (RC_DEPTREE, RC_INITDIR) ||
- ! rc_newer_than (RC_DEPTREE, RC_CONFDIR) ||
+ if (! existss(RC_DEPTREE_CACHE) ||
+ ! rc_newer_than(RC_DEPTREE_CACHE, RC_INITDIR) ||
+ ! rc_newer_than(RC_DEPTREE_CACHE, RC_CONFDIR) ||
#ifdef RC_PKG_INITDIR
- ! rc_newer_than (RC_DEPTREE, RC_PKG_INITDIR) ||
+ ! rc_newer_than(RC_DEPTREE_CACHE, RC_PKG_INITDIR) ||
#endif
#ifdef RC_PKG_CONFDIR
- ! rc_newer_than (RC_DEPTREE, RC_PKG_CONFDIR) ||
+ ! rc_newer_than(RC_DEPTREE_CACHE, RC_PKG_CONFDIR) ||
#endif
#ifdef RC_LOCAL_INITDIR
- ! rc_newer_than (RC_DEPTREE, RC_LOCAL_INITDIR) ||
+ ! rc_newer_than(RC_DEPTREE_CACHE, RC_LOCAL_INITDIR) ||
#endif
#ifdef RC_LOCAL_CONFDIR
- ! rc_newer_than (RC_DEPTREE, RC_LOCAL_CONFDIR) ||
+ ! rc_newer_than(RC_DEPTREE_CACHE, RC_LOCAL_CONFDIR) ||
#endif
- ! rc_newer_than (RC_DEPTREE, "/etc/rc.conf"))
- return (true);
+ ! rc_newer_than(RC_DEPTREE_CACHE, "/etc/rc.conf"))
+ return true;
/* Some init scripts dependencies change depending on config files
* outside of baselayout, like syslog-ng, so we check those too. */
config = rc_config_list (RC_DEPCONFIG);
- STRLIST_FOREACH (config, service, i) {
- if (! rc_newer_than (RC_DEPTREE, service)) {
+ TAILQ_FOREACH(s, config, entries) {
+ if (! rc_newer_than(RC_DEPTREE_CACHE, s->value)) {
newer = true;
break;
}
}
- rc_strlist_free (config);
+ rc_stringlist_free(config);
- return (newer);
+ return newer;
}
librc_hidden_def(rc_deptree_update_needed)
- /* This is a 5 phase operation
- Phase 1 is a shell script which loads each init script and config in turn
- and echos their dependency info to stdout
- Phase 2 takes that and populates a depinfo object with that data
- Phase 3 adds any provided services to the depinfo object
- Phase 4 scans that depinfo object and puts in backlinks
- Phase 5 saves the depinfo object to disk
- */
-bool rc_deptree_update (void)
+/* This is a 5 phase operation
+ Phase 1 is a shell script which loads each init script and config in turn
+ and echos their dependency info to stdout
+ Phase 2 takes that and populates a depinfo object with that data
+ Phase 3 adds any provided services to the depinfo object
+ Phase 4 scans that depinfo object and puts in backlinks
+ Phase 5 saves the depinfo object to disk
+ */
+bool rc_deptree_update(void)
{
+ FILE *fp;
+ RC_DEPTREE *deptree;
+ RC_DEPTREE *providers;
+ RC_DEPINFO *depinfo = NULL;
+ RC_DEPINFO *depinfo_np;
+ RC_DEPINFO *di;
+ RC_DEPTYPE *deptype = NULL;
+ RC_DEPTYPE *dt;
+ RC_DEPTYPE *dt_np;
+ RC_STRINGLIST *config;
+ RC_STRING *s;
+ RC_STRING *s2;
+ RC_DEPTYPE *provide;
+ char *line;
+ char *depend;
char *depends;
char *service;
char *type;
- char *depend;
- char **config = NULL;
- int retval = true;
- FILE *fp;
- rc_depinfo_t *deptree = NULL;
- rc_depinfo_t *depinfo;
- rc_depinfo_t *di;
- rc_depinfo_t *last_depinfo = NULL;
- rc_deptype_t *deptype = NULL;
- rc_deptype_t *dt;
- rc_deptype_t *last_deptype = NULL;
- char **removedp = NULL;
- char *line;
- size_t len;
size_t i;
- size_t j;
size_t k;
- bool already_added;
- const char *sys = rc_sys ();
+ size_t len;
+ int retval = true;
+ const char *sys = rc_sys();
+ char *nosys;
/* Some init scripts need RC_LIBDIR to source stuff
Ideally we should be setting our full env instead */
- if (! getenv ("RC_LIBDIR"))
- setenv ("RC_LIBDIR", RC_LIBDIR, 0);
+ if (! getenv("RC_LIBDIR"))
+ setenv("RC_LIBDIR", RC_LIBDIR, 0);
/* Phase 1 - source all init scripts and print dependencies */
- if (! (fp = popen (GENDEP, "r")))
- return (false);
+ if (! (fp = popen(GENDEP, "r")))
+ return false;
+
+ deptree = xmalloc(sizeof(*deptree));
+ STAILQ_INIT(deptree);
- while ((line = rc_getline (fp)))
+ config = rc_stringlist_new();
+
+ while ((line = rc_getline(fp)))
{
depends = line;
- service = strsep (&depends, " ");
+ service = strsep(&depends, " ");
if (! service || ! *service)
goto next;
- type = strsep (&depends, " ");
+ type = strsep(&depends, " ");
- for (depinfo = deptree; depinfo; depinfo = depinfo->next)
- {
- last_depinfo = depinfo;
- if (depinfo->service && strcmp (depinfo->service, service) == 0)
- break;
- }
-
- if (! depinfo)
- {
- if (! last_depinfo)
- deptree = depinfo = xzalloc (sizeof (*depinfo));
- else if (! last_depinfo->service)
- depinfo = last_depinfo;
- else
- {
- last_depinfo->next = xzalloc (sizeof (*last_depinfo->next));
- depinfo = last_depinfo->next;
+ if (! depinfo || strcmp(depinfo->service, service) != 0) {
+ deptype = NULL;
+ depinfo = get_depinfo(deptree, service);
+ if (! depinfo) {
+ depinfo = xmalloc(sizeof(*depinfo));
+ STAILQ_INIT(&depinfo->depends);
+ depinfo->service = xstrdup(service);
+ STAILQ_INSERT_TAIL(deptree, depinfo, entries);
}
- depinfo->service = xstrdup (service);
}
-
+
/* We may not have any depends */
if (! type || ! depends)
goto next;
/* Get the type */
- if (strcmp (type, "config") != 0) {
- last_deptype = NULL;
- for (deptype = depinfo->depends; deptype; deptype = deptype->next)
- {
- last_deptype = deptype;
- if (strcmp (deptype->type, type) == 0)
- break;
- }
-
- if (! deptype)
- {
- if (! last_deptype)
- {
- depinfo->depends = xzalloc (sizeof (*depinfo->depends));
- deptype = depinfo->depends;
- }
- else
- {
- last_deptype->next = xzalloc (sizeof (*last_deptype->next));
- deptype = last_deptype->next;
- }
- deptype->type = xstrdup (type);
+ if (strcmp(type, "config") != 0) {
+ if (! deptype || strcmp (deptype->type, type) != 0)
+ deptype = get_deptype(depinfo, type);
+ if (! deptype) {
+ deptype = xmalloc(sizeof(*deptype));
+ deptype->type = xstrdup(type);
+ deptype->services = rc_stringlist_new();
+ STAILQ_INSERT_TAIL(&depinfo->depends, deptype, entries);
}
}
/* Now add each depend to our type.
We do this individually so we handle multiple spaces gracefully */
- while ((depend = strsep (&depends, " ")))
+ while ((depend = strsep(&depends, " ")))
{
if (depend[0] == 0)
continue;
- if (strcmp (type, "config") == 0) {
- rc_strlist_addsort (&config, depend);
+ if (strcmp(type, "config") == 0) {
+ rc_stringlist_add(config, depend);
continue;
}
/* .sh files are not init scripts */
- len = strlen (depend);
+ len = strlen(depend);
if (len > 2 &&
depend[len - 3] == '.' &&
depend[len - 2] == 's' &&
@@ -849,171 +790,114 @@ bool rc_deptree_update (void)
/* Remove our dependency if instructed */
if (depend[0] == '!') {
- rc_strlist_delete (&deptype->services, depend + 1);
+ rc_stringlist_delete(deptype->services, depend + 1);
continue;
}
- rc_strlist_addsort (&deptype->services, depend);
+ rc_stringlist_add(deptype->services, depend);
/* We need to allow `after *; before local;` to work.
* Conversely, we need to allow 'before *; after modules' also */
/* If we're before something, remove us from the after list */
- if (strcmp (type, "ibefore") == 0) {
- if ((dt = get_deptype (depinfo, "iafter")))
- rc_strlist_delete (&dt->services, depend);
+ if (strcmp(type, "ibefore") == 0) {
+ if ((dt = get_deptype(depinfo, "iafter")))
+ rc_stringlist_delete(dt->services, depend);
}
/* If we're after something, remove us from the before list */
if (strcmp (type, "iafter") == 0 ||
strcmp (type, "ineed") == 0 ||
strcmp (type, "iuse") == 0) {
- if ((dt = get_deptype (depinfo, "ibefore")))
- rc_strlist_delete (&dt->services, depend);
+ if ((dt = get_deptype(depinfo, "ibefore")))
+ rc_stringlist_delete(dt->services, depend);
}
}
next:
- free (line);
+ free(line);
}
- pclose (fp);
+ pclose(fp);
/* Phase 2 - if we're a special system, remove services that don't
* work for them. This doesn't stop them from being run directly. */
if (sys) {
- char *nosys;
-
- len = strlen (sys);
- nosys = xmalloc (len + 3);
+ len = strlen(sys);
+ nosys = xmalloc(len + 3);
nosys[0] = 'n';
nosys[1] = 'o';
for (i = 0; i < len; i++)
- nosys[i + 2] = (char) tolower ((int) sys[i]);
+ nosys[i + 2] = (char) tolower((int) sys[i]);
nosys[i + 2] = '\0';
- last_depinfo = NULL;
- depinfo = deptree;
- while (depinfo) {
- bool removed = false;
- if ((deptype = get_deptype (depinfo, "keyword"))) {
- STRLIST_FOREACH (deptype->services, service, i)
- if (strcmp (service, nosys) == 0) {
- if (last_depinfo)
- last_depinfo->next = depinfo->next;
- else
- deptree = depinfo->next;
- removed = true;
- break;
+ STAILQ_FOREACH_SAFE(depinfo, deptree, entries, depinfo_np)
+ if ((deptype = get_deptype(depinfo, "keyword")))
+ TAILQ_FOREACH(s, deptype->services, entries)
+ if (strcmp (s->value, nosys) == 0) {
+ provide = get_deptype(depinfo, "iprovide");
+ STAILQ_REMOVE(deptree, depinfo, rc_depinfo, entries);
+ STAILQ_FOREACH(di, deptree, entries) {
+ STAILQ_FOREACH_SAFE(dt, &di->depends, entries, dt_np) {
+ rc_stringlist_delete(dt->services, depinfo->service);
+ if (provide)
+ TAILQ_FOREACH(s2, provide->services, entries)
+ rc_stringlist_delete(dt->services, s2->value);
+ if (! TAILQ_FIRST(dt->services)) {
+ STAILQ_REMOVE(&di->depends, dt, rc_deptype, entries);
+ free(dt->type);
+ free(dt->services);
+ free(dt);
+ }
+ }
+ }
}
- }
- if (removed) {
- dt = get_deptype (depinfo, "iprovide");
- if (dt)
- STRLIST_FOREACH (dt->services, service, i)
- rc_strlist_addu (&removedp, service);
- for (di = deptree; di; di = di->next) {
- for (dt = di->depends; dt; dt = dt->next)
- rc_strlist_delete (&dt->services, depinfo->service);
- }
- di = depinfo->next;
- depinfo->next = NULL;
- rc_deptree_free (depinfo);
- depinfo = di;
- } else {
- last_depinfo = depinfo;
- depinfo = depinfo->next;
- }
- }
-
free (nosys);
}
- /* Phase 3 - add our providors to the tree */
- for (depinfo = deptree; depinfo; depinfo = depinfo->next)
- {
- if ((deptype = get_deptype (depinfo, "iprovide")))
- STRLIST_FOREACH (deptype->services, service, i)
- {
- for (di = deptree; di; di = di->next)
- {
- last_depinfo = di;
- if (strcmp (di->service, service) == 0)
+ /* Phase 3 - add our providers to the tree */
+ providers = xmalloc(sizeof(*providers));
+ STAILQ_INIT(providers);
+ STAILQ_FOREACH(depinfo, deptree, entries)
+ if ((deptype = get_deptype(depinfo, "iprovide")))
+ TAILQ_FOREACH(s, deptype->services, entries) {
+ STAILQ_FOREACH(di, providers, entries)
+ if (strcmp(di->service, s->value) == 0)
break;
- }
- if (! di)
- {
- last_depinfo->next = xzalloc (sizeof (*last_depinfo->next));
- di = last_depinfo->next;
- di->service = xstrdup (service);
+ if (! di) {
+ di = xmalloc(sizeof(*di));
+ STAILQ_INIT(&di->depends);
+ di->service = xstrdup(s->value);
+ STAILQ_INSERT_TAIL(providers, di, entries);
}
}
- }
+ STAILQ_CONCAT(deptree, providers);
+ free(providers);
/* Phase 4 - backreference our depends */
- for (depinfo = deptree; depinfo; depinfo = depinfo->next)
- {
- for (i = 0; deppairs[i].depend; i++)
- {
- deptype = get_deptype (depinfo, deppairs[i].depend);
+ STAILQ_FOREACH(depinfo, deptree, entries)
+ for (i = 0; deppairs[i].depend; i++) {
+ deptype = get_deptype(depinfo, deppairs[i].depend);
if (! deptype)
continue;
-
- STRLIST_FOREACH (deptype->services, service, j)
- {
- di = get_depinfo (deptree, service);
- if (! di)
- {
+ TAILQ_FOREACH(s, deptype->services, entries) {
+ di = get_depinfo(deptree, s->value);
+ if (! di) {
if (strcmp (deptype->type, "ineed") == 0)
- {
- bool removed = false;
- STRLIST_FOREACH (removedp, line, k) {
- if (strcmp (line, service) == 0) {
- removed = true;
- break;
- }
- }
- if (! removed)
- fprintf (stderr,
- "Service `%s' needs non existant service `%s'\n",
- depinfo->service, service);
- }
+ fprintf (stderr,
+ "Service `%s' needs non"
+ " existant service `%s'\n",
+ depinfo->service, s->value);
continue;
}
- /* Add our deptype now */
- last_deptype = NULL;
- for (dt = di->depends; dt; dt = dt->next)
- {
- last_deptype = dt;
- if (strcmp (dt->type, deppairs[i].addto) == 0)
- break;
+ dt = get_deptype(di, deppairs[i].addto);
+ if (! dt) {
+ dt = xmalloc(sizeof(*dt));
+ dt->type = xstrdup(deppairs[i].addto);
+ dt->services = rc_stringlist_new();
+ STAILQ_INSERT_TAIL(&di->depends, dt, entries);
}
- if (! dt)
- {
- if (! last_deptype)
- {
- di->depends = xzalloc (sizeof (*di->depends));
- dt = di->depends;
- }
- else
- {
- last_deptype->next = xzalloc (sizeof (*last_deptype->next));
- dt = last_deptype->next;
- }
- dt->type = xstrdup (deppairs[i].addto);
- }
-
- already_added = false;
- STRLIST_FOREACH (dt->services, service, k)
- if (strcmp (service, depinfo->service) == 0)
- {
- already_added = true;
- break;
- }
-
- if (! already_added)
- rc_strlist_addsort (&dt->services, depinfo->service);
+ rc_stringlist_add(dt->services, depinfo->service);
}
}
- }
/* Phase 5 - save to disk
Now that we're purely in C, do we need to keep a shell parseable file?
@@ -1021,49 +905,47 @@ next:
This works and should be entirely shell parseable provided that depend
names don't have any non shell variable characters in
*/
- if ((fp = fopen (RC_DEPTREE, "w"))) {
+ if ((fp = fopen (RC_DEPTREE_CACHE, "w"))) {
i = 0;
- for (depinfo = deptree; depinfo; depinfo = depinfo->next)
- {
- fprintf (fp, "depinfo_%zu_service='%s'\n",
- i, depinfo->service);
- for (deptype = depinfo->depends; deptype; deptype = deptype->next)
- {
+ STAILQ_FOREACH(depinfo, deptree, entries) {
+ fprintf(fp, "depinfo_%zu_service='%s'\n",
+ i, depinfo->service);
+ STAILQ_FOREACH(deptype, &depinfo->depends, entries) {
k = 0;
- STRLIST_FOREACH (deptype->services, service, j)
- {
- fprintf (fp,
- "depinfo_%zu_%s_%zu='%s'\n",
- i,
- deptype->type,
- k, service);
+ TAILQ_FOREACH(s, deptype->services, entries) {
+ fprintf(fp,
+ "depinfo_%zu_%s_%zu='%s'\n",
+ i, deptype->type, k, s->value);
k++;
}
}
i++;
}
- fclose (fp);
+ fclose(fp);
} else {
- fprintf (stderr, "fopen `%s': %s\n", RC_DEPTREE, strerror (errno));
+ fprintf(stderr, "fopen `%s': %s\n",
+ RC_DEPTREE_CACHE, strerror(errno));
retval = false;
}
/* Save our external config files to disk */
- if (config) {
- if ((fp = fopen (RC_DEPCONFIG, "w"))) {
- STRLIST_FOREACH (config, service, i)
- fprintf (fp, "%s\n", service);
- fclose (fp);
+ if (TAILQ_FIRST(config)) {
+ if ((fp = fopen(RC_DEPCONFIG, "w"))) {
+ TAILQ_FOREACH(s, config, entries)
+ fprintf (fp, "%s\n", s->value);
+ fclose(fp);
} else {
- fprintf (stderr, "fopen `%s': %s\n", RC_DEPCONFIG, strerror (errno));
+ fprintf(stderr, "fopen `%s': %s\n",
+ RC_DEPCONFIG, strerror(errno));
retval = false;
}
- rc_strlist_free (config);
+ rc_stringlist_free (config);
+ } else {
+ unlink(RC_DEPCONFIG);
}
- rc_strlist_free (removedp);
- rc_deptree_free (deptree);
+ rc_deptree_free(deptree);
- return (retval);
+ return retval;
}
librc_hidden_def(rc_deptree_update)
diff --git a/src/librc/librc-depend.h b/src/librc/librc-depend.h
deleted file mode 100644
index 737920e..0000000
--- a/src/librc/librc-depend.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * librc-depend.h
- * Internal header file for dependency structures
- */
-
-/*
- * Copyright 2007-2008 Roy Marples
- * All rights reserved
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _LIBRC_DEPEND_H
-#define _LIBRC_DEPEND_H
-
-/*! @name Dependency structures
- * private to librc - rc.h exposes them just a pointers */
-
-/*! Singly linked list of dependency types that list the services the
- * type is for */
-typedef struct rc_deptype
-{
- /*! ineed, iuse, iafter, etc */
- char *type;
- /*! NULL terminated list of services */
- char **services;
- /*! Next dependency type */
- struct rc_deptype *next;
-} rc_deptype_t;
-
-/*! Singly linked list of services and their dependencies */
-typedef struct rc_depinfo
-{
- /*! Name of service */
- char *service;
- /*! Dependencies */
- rc_deptype_t *depends;
- /*! Next service dependency type */
- struct rc_depinfo *next;
-} rc_depinfo_t;
-
-#endif
diff --git a/src/librc/librc-misc.c b/src/librc/librc-misc.c
index f08a762..fac78e2 100644
--- a/src/librc/librc-misc.c
+++ b/src/librc/librc-misc.c
@@ -35,14 +35,14 @@ bool rc_yesno (const char *value)
{
if (! value) {
errno = ENOENT;
- return (false);
+ return false;
}
if (strcasecmp (value, "yes") == 0 ||
strcasecmp (value, "y") == 0 ||
strcasecmp (value, "true") == 0 ||
strcasecmp (value, "1") == 0)
- return (true);
+ return true;
if (strcasecmp (value, "no") != 0 &&
strcasecmp (value, "n") != 0 &&
@@ -50,7 +50,7 @@ bool rc_yesno (const char *value)
strcasecmp (value, "0") != 0)
errno = EINVAL;
- return (false);
+ return false;
}
librc_hidden_def(rc_yesno)
@@ -64,7 +64,7 @@ char *rc_strcatpaths (const char *path1, const char *paths, ...)
char *pathp;
if (! path1 || ! paths)
- return (NULL);
+ return NULL;
length = strlen (path1) + strlen (paths) + 1;
if (*paths != '/')
@@ -101,7 +101,7 @@ char *rc_strcatpaths (const char *path1, const char *paths, ...)
*pathp++ = 0;
- return (path);
+ return path;
}
librc_hidden_def(rc_strcatpaths)
@@ -113,7 +113,7 @@ char *rc_getline (FILE *fp)
size_t last = 0;
if (feof (fp))
- return (NULL);
+ return NULL;
do {
len += BUFSIZ;
@@ -128,74 +128,78 @@ char *rc_getline (FILE *fp)
if (*line && line[--last] == '\n')
line[last] = '\0';
- return (line);
+ return line;
}
librc_hidden_def(rc_getline)
-char **rc_config_list (const char *file)
+RC_STRINGLIST *rc_config_list(const char *file)
{
FILE *fp;
char *buffer;
char *p;
char *token;
- char **list = NULL;
+ RC_STRINGLIST *list;
- if (! (fp = fopen (file, "r")))
- return (NULL);
+ if (!(fp = fopen(file, "r")))
+ return NULL;
- while ((p = buffer = rc_getline (fp))) {
+ list = rc_stringlist_new();
+
+ while ((p = buffer = rc_getline(fp))) {
/* Strip leading spaces/tabs */
while ((*p == ' ') || (*p == '\t'))
p++;
/* Get entry - we do not want comments */
- token = strsep (&p, "#");
- if (token && (strlen (token) > 1)) {
+ token = strsep(&p, "#");
+ if (token && (strlen(token) > 1)) {
/* If not variable assignment then skip */
- if (strchr (token, '=')) {
+ if (strchr(token, '=')) {
/* Stip the newline if present */
- if (token[strlen (token) - 1] == '\n')
- token[strlen (token) - 1] = 0;
+ if (token[strlen(token) - 1] == '\n')
+ token[strlen(token) - 1] = 0;
- rc_strlist_add (&list, token);
+ rc_stringlist_add(list, token);
}
}
- free (buffer);
+ free(buffer);
}
- fclose (fp);
+ fclose(fp);
- return (list);
+ return list;
}
librc_hidden_def(rc_config_list)
-char **rc_config_load (const char *file)
+RC_STRINGLIST *rc_config_load(const char *file)
{
- char **list = NULL;
- char **config = NULL;
+ RC_STRINGLIST *list = NULL;
+ RC_STRINGLIST *config = NULL;
char *token;
- char *line;
- char *linep;
- char *linetok;
+ RC_STRING *line;
+ RC_STRING *cline;
size_t i = 0;
- int j;
bool replaced;
char *entry;
char *newline;
+ char *p;
- list = rc_config_list (file);
- STRLIST_FOREACH (list, line, j) {
+ config = rc_stringlist_new();
+
+ list = rc_config_list(file);
+ TAILQ_FOREACH(line, list, entries) {
/* Get entry */
- if (! (token = strsep (&line, "=")))
+ p = line->value;
+ if (! (token = strsep(&p, "=")))
continue;
entry = xstrdup (token);
/* Preserve shell coloring */
- if (*line == '$')
- token = line;
+ if (*p == '$')
+ token = line->value;
else
do {
/* Bash variables are usually quoted */
- token = strsep (&line, "\"\'");
+ token = strsep(&p, "\"\'");
} while (token && *token == '\0');
/* Drop a newline if that's all we have */
@@ -205,57 +209,54 @@ char **rc_config_load (const char *file)
token[i] = 0;
i = strlen (entry) + strlen (token) + 2;
- newline = xmalloc (sizeof (char) * i);
- snprintf (newline, i, "%s=%s", entry, token);
+ newline = xmalloc(sizeof(char) * i);
+ snprintf(newline, i, "%s=%s", entry, token);
} else {
i = strlen (entry) + 2;
- newline = xmalloc (sizeof (char) * i);
- snprintf (newline, i, "%s=", entry);
+ newline = xmalloc(sizeof(char) * i);
+ snprintf(newline, i, "%s=", entry);
}
replaced = false;
/* In shells the last item takes precedence, so we need to remove
any prior values we may already have */
- STRLIST_FOREACH (config, line, i) {
- char *tmp = xstrdup (line);
- linep = tmp;
- linetok = strsep (&linep, "=");
- if (strcmp (linetok, entry) == 0) {
+ TAILQ_FOREACH(cline, config, entries) {
+ p = strchr(cline->value, '=');
+ if (p && strncmp(entry, cline->value,
+ (size_t) (p - cline->value)) == 0)
+ {
/* We have a match now - to save time we directly replace it */
- free (config[i - 1]);
- config[i - 1] = newline;
+ free(cline->value);
+ cline->value = newline;
replaced = true;
- free (tmp);
break;
}
- free (tmp);
}
if (! replaced) {
- rc_strlist_addsort (&config, newline);
- free (newline);
+ rc_stringlist_add(config, newline);
+ free(newline);
}
- free (entry);
+ free(entry);
}
- rc_strlist_free (list);
+ rc_stringlist_free(list);
- return (config);
+ return config;
}
librc_hidden_def(rc_config_load)
-char *rc_config_value (const char *const *list, const char *entry)
+char *rc_config_value(RC_STRINGLIST *list, const char *entry)
{
- const char *line;
- int i;
+ RC_STRING *line;
char *p;
- STRLIST_FOREACH (list, line, i) {
- p = strchr (line, '=');
- if (p && strncmp (entry, line, (size_t) (p - line)) == 0)
- return (p += 1);
+ TAILQ_FOREACH(line, list, entries) {
+ p = strchr(line->value, '=');
+ if (p &&
+ strncmp(entry, line->value, (size_t)(p - line->value)) == 0)
+ return p += 1;
}
- return (NULL);
+ return NULL;
}
librc_hidden_def(rc_config_value)
-
diff --git a/src/librc/librc-strlist.c b/src/librc/librc-strlist.c
deleted file mode 100644
index 9b62269..0000000
--- a/src/librc/librc-strlist.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- librc-strlist.h
- String list functions for using char ** arrays
-
- Based on a previous implementation by Martin Schlemmer
- */
-
-/*
- * Copyright 2007-2008 Roy Marples
- * All rights reserved
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "librc.h"
-
-static char *_rc_strlist_add (char ***list, const char *item, bool uniq)
-{
- char **newlist;
- char **lst = *list;
- int i = 0;
-
- if (! item)
- return (NULL);
-
- while (lst && lst[i]) {
- if (uniq && strcmp (lst[i], item) == 0) {
- errno = EEXIST;
- return (NULL);
- }
- i++;
- }
-
- newlist = xrealloc (lst, sizeof (char *) * (i + 2));
- newlist[i] = xstrdup (item);
- newlist[i + 1] = NULL;
-
- *list = newlist;
- return (newlist[i]);
-}
-
-char *rc_strlist_add (char ***list, const char *item)
-{
- return (_rc_strlist_add (list, item, false));
-}
-librc_hidden_def(rc_strlist_add)
-
-char *rc_strlist_addu (char ***list, const char *item)
-{
- return (_rc_strlist_add (list, item, true));
-}
-librc_hidden_def(rc_strlist_addu)
-
-static char *_rc_strlist_addsort (char ***list, const char *item,
- int (*sortfunc) (const char *s1,
- const char *s2),
- bool uniq)
-{
- char **newlist;
- char **lst = *list;
- int i = 0;
- char *tmp1;
- char *tmp2;
- char *retval;
-
- if (! item)
- return (NULL);
-
- while (lst && lst[i]) {
- if (uniq && strcmp (lst[i], item) == 0) {
- errno = EEXIST;
- return (NULL);
- }
- i++;
- }
-
- newlist = xrealloc (lst, sizeof (char *) * (i + 2));
-
- if (! i)
- newlist[i] = NULL;
- newlist[i + 1] = NULL;
-
- i = 0;
- while (newlist[i] && sortfunc (newlist[i], item) < 0)
- i++;
-
- tmp1 = newlist[i];
- retval = newlist[i] = xstrdup (item);
- do {
- i++;
- tmp2 = newlist[i];
- newlist[i] = tmp1;
- tmp1 = tmp2;
- } while (tmp1);
-
- *list = newlist;
- return (retval);
-}
-
-char *rc_strlist_addsort (char ***list, const char *item)
-{
- return (_rc_strlist_addsort (list, item, strcoll, false));
-}
-librc_hidden_def(rc_strlist_addsort)
-
-char *rc_strlist_addsortc (char ***list, const char *item)
-{
- return (_rc_strlist_addsort (list, item, strcmp, false));
-}
-librc_hidden_def(rc_strlist_addsortc)
-
-char *rc_strlist_addsortu (char ***list, const char *item)
-{
- return (_rc_strlist_addsort (list, item, strcmp, true));
-}
-librc_hidden_def(rc_strlist_addsortu)
-
-bool rc_strlist_delete (char ***list, const char *item)
-{
- char **lst = *list;
- int i = 0;
-
- if (!lst || ! item)
- return (false);
-
- while (lst[i]) {
- if (strcmp (lst[i], item) == 0) {
- free (lst[i]);
- do {
- lst[i] = lst[i + 1];
- i++;
- } while (lst[i]);
- return (true);
- }
- i++;
- }
-
- errno = ENOENT;
- return (false);
-}
-librc_hidden_def(rc_strlist_delete)
-
-char *rc_strlist_join (char ***list1, char **list2)
-{
- char **lst1 = *list1;
- char **newlist;
- int i = 0;
- int j = 0;
-
- if (! list2)
- return (NULL);
-
- while (lst1 && lst1[i])
- i++;
-
- while (list2[j])
- j++;
-
- newlist = xrealloc (lst1, sizeof (char *) * (i + j + 1));
-
- j = 0;
- while (list2[j]) {
- newlist[i] = list2[j];
- /* Take the item off the 2nd list as it's only a shallow copy */
- list2[j] = NULL;
- i++;
- j++;
- }
- newlist[i] = NULL;
-
- *list1 = newlist;
- return (newlist[i == 0 ? 0 : i - 1]);
-}
-librc_hidden_def(rc_strlist_join)
-
-void rc_strlist_reverse (char **list)
-{
- char *item;
- int i = 0;
- int j = 0;
-
- if (! list)
- return;
-
- while (list[j])
- j++;
- j--;
-
- while (i < j && list[i] && list[j]) {
- item = list[i];
- list[i] = list[j];
- list[j] = item;
- i++;
- j--;
- }
-}
-librc_hidden_def(rc_strlist_reverse)
-
-void rc_strlist_free (char **list)
-{
- int i = 0;
-
- if (! list)
- return;
-
- while (list[i])
- free (list[i++]);
-
- free (list);
-}
-librc_hidden_def(rc_strlist_free)
diff --git a/src/librc/librc.c b/src/librc/librc.c
index 7344e37..301a388 100644
--- a/src/librc/librc.c
+++ b/src/librc/librc.c
@@ -47,7 +47,7 @@ const char librc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
FILE *rc_environ_fd = NULL;
typedef struct rc_service_state_name {
- rc_service_state_t state;
+ RC_SERVICE state;
const char *name;
} rc_service_state_name_t;
@@ -68,49 +68,53 @@ static const rc_service_state_name_t rc_service_state_names[] = {
#define LS_INITD 0x01
#define LS_DIR 0x02
-static char **ls_dir (const char *dir, int options)
+static RC_STRINGLIST *ls_dir(const char *dir, int options)
{
DIR *dp;
struct dirent *d;
- char **list = NULL;
+ RC_STRINGLIST *list;
struct stat buf;
+ size_t l;
+ char *file;
+ int r;
- if ((dp = opendir (dir)) == NULL)
- return (NULL);
+ if ((dp = opendir(dir)) == NULL)
+ return NULL;
- while (((d = readdir (dp)) != NULL)) {
+ list = rc_stringlist_new();
+ while (((d = readdir(dp)) != NULL)) {
if (d->d_name[0] != '.') {
if (options & LS_INITD) {
- int l = strlen (d->d_name);
-
/* Check that our file really exists.
* This is important as a service maybe in a runlevel, but
* could also have been removed. */
- char *file = rc_strcatpaths (dir, d->d_name, NULL);
- int ok = stat (file, &buf);
- free (file);
- if (ok != 0)
+ file = rc_strcatpaths(dir, d->d_name, NULL);
+ r = stat(file, &buf);
+ free(file);
+ if (r != 0)
continue;
/* .sh files are not init scripts */
+ l = strlen(d->d_name);
if (l > 2 && d->d_name[l - 3] == '.' &&
d->d_name[l - 2] == 's' &&
d->d_name[l - 1] == 'h')
continue;
}
if (options & LS_DIR) {
- if (stat (d->d_name, &buf) == 0 && ! S_ISDIR (buf.st_mode))
+ if (stat(d->d_name, &buf) == 0 &&
+ ! S_ISDIR(buf.st_mode))
continue;
}
- rc_strlist_addsort (&list, d->d_name);
+ rc_stringlist_add(list, d->d_name);
}
}
- closedir (dp);
+ closedir(dp);
- return (list);
+ return list;
}
-static bool rm_dir (const char *pathname, bool top)
+static bool rm_dir(const char *pathname, bool top)
{
DIR *dp;
struct dirent *d;
@@ -118,49 +122,49 @@ static bool rm_dir (const char *pathname, bool top)
struct stat s;
bool retval = true;
- if ((dp = opendir (pathname)) == NULL)
- return (false);
+ if ((dp = opendir(pathname)) == NULL)
+ return false;
errno = 0;
- while (((d = readdir (dp)) != NULL) && errno == 0) {
- if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0) {
- free (tmp);
- tmp = rc_strcatpaths (pathname, d->d_name, (char *) NULL);
+ while (((d = readdir(dp)) != NULL) && errno == 0) {
+ if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0) {
+ free(tmp);
+ tmp = rc_strcatpaths(pathname, d->d_name, (char *) NULL);
- if (stat (tmp, &s) != 0) {
+ if (stat(tmp, &s) != 0) {
retval = false;
break;
}
- if (S_ISDIR (s.st_mode)) {
- if (! rm_dir (tmp, true))
+ if (S_ISDIR(s.st_mode)) {
+ if (! rm_dir(tmp, true))
{
retval = false;
break;
}
} else {
- if (unlink (tmp)) {
+ if (unlink(tmp)) {
retval = false;
break;
}
}
}
}
- closedir (dp);
- free (tmp);
+ closedir(dp);
+ free(tmp);
if (! retval)
- return (false);
+ return false;
- if (top && rmdir (pathname) != 0)
- return (false);
+ if (top && rmdir(pathname) != 0)
+ return false;
- return (true);
+ return true;
}
/* Other systems may need this at some point, but for now it's Linux only */
#ifdef __linux__
-static bool file_regex (const char *file, const char *regex)
+static bool file_regex(const char *file, const char *regex)
{
FILE *fp;
char *line;
@@ -168,153 +172,153 @@ static bool file_regex (const char *file, const char *regex)
bool retval = false;
int result;
- if (! (fp = fopen (file, "r")))
- return (false);
+ if (! (fp = fopen(file, "r")))
+ return false;
- if ((result = regcomp (&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
- fclose (fp);
- line = xmalloc (sizeof (char) * BUFSIZ);
- regerror (result, &re, line, BUFSIZ);
- fprintf (stderr, "file_regex: %s", line);
- free (line);
- return (false);
+ if ((result = regcomp(&re, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
+ fclose(fp);
+ line = xmalloc(sizeof (char) * BUFSIZ);
+ regerror(result, &re, line, BUFSIZ);
+ fprintf(stderr, "file_regex: %s", line);
+ free(line);
+ return false;
}
- while ((line = rc_getline (fp))) {
- if (regexec (&re, line, 0, NULL, 0) == 0)
+ while ((line = rc_getline(fp))) {
+ if (regexec(&re, line, 0, NULL, 0) == 0)
retval = true;
- free (line);
+ free(line);
if (retval)
break;
}
- fclose (fp);
- regfree (&re);
+ fclose(fp);
+ regfree(&re);
- return (retval);
+ return retval;
}
#endif
-const char *rc_sys (void)
+const char *rc_sys(void)
{
#ifdef PREFIX
- return (RC_SYS_PREFIX);
+ return RC_SYS_PREFIX;
#else
#ifdef __FreeBSD__
int jailed = 0;
- size_t len = sizeof (jailed);
+ size_t len = sizeof(jailed);
- if (sysctlbyname ("security.jail.jailed", &jailed, &len, NULL, 0) == 0)
+ if (sysctlbyname("security.jail.jailed", &jailed, &len, NULL, 0) == 0)
if (jailed == 1)
- return (RC_SYS_JAIL);
+ return RC_SYS_JAIL;
#endif
#ifdef __linux__
- if (exists ("/proc/xen")) {
- if (file_regex ("/proc/xen/capabilities", "control_d"))
- return (RC_SYS_XEN0);
- return (RC_SYS_XENU);
- } else if (file_regex ("/proc/cpuinfo", "UML"))
- return (RC_SYS_UML);
- else if (file_regex ("/proc/self/status",
- "(s_context|VxID):[[:space:]]*[1-9]"))
- return (RC_SYS_VSERVER);
- else if (file_regex ("/proc/self/status",
- "envID:[[:space:]]*[1-9]"))
- return (RC_SYS_OPENVZ);
+ if (exists("/proc/xen")) {
+ if (file_regex("/proc/xen/capabilities", "control_d"))
+ return RC_SYS_XEN0;
+ return RC_SYS_XENU;
+ } else if (file_regex("/proc/cpuinfo", "UML"))
+ return RC_SYS_UML;
+ else if (file_regex("/proc/self/status",
+ "(s_context|VxID):[[:space:]]*[1-9]"))
+ return RC_SYS_VSERVER;
+ else if (file_regex("/proc/self/status",
+ "envID:[[:space:]]*[1-9]"))
+ return RC_SYS_OPENVZ;
#endif
- return (NULL);
+ return NULL;
#endif /* PREFIX */
}
-static const char *rc_parse_service_state (rc_service_state_t state)
+static const char *rc_parse_service_state(RC_SERVICE state)
{
int i;
for (i = 0; rc_service_state_names[i].name; i++) {
if (rc_service_state_names[i].state == state)
- return (rc_service_state_names[i].name);
+ return rc_service_state_names[i].name;
}
- return (NULL);
+ return NULL;
}
-bool rc_runlevel_starting (void)
+bool rc_runlevel_starting(void)
{
- return (exists (RC_STARTING));
+ return exists(RC_STARTING);
}
librc_hidden_def(rc_runlevel_starting)
-bool rc_runlevel_stopping (void)
+bool rc_runlevel_stopping(void)
{
- return (exists (RC_STOPPING));
+ return exists(RC_STOPPING);
}
librc_hidden_def(rc_runlevel_stopping)
-char **rc_runlevel_list (void)
+RC_STRINGLIST *rc_runlevel_list(void)
{
- return (ls_dir (RC_RUNLEVELDIR, LS_DIR));
+ return ls_dir(RC_RUNLEVELDIR, LS_DIR);
}
librc_hidden_def(rc_runlevel_list)
-char *rc_runlevel_get (void)
+char *rc_runlevel_get(void)
{
FILE *fp;
char *runlevel = NULL;
- if ((fp = fopen (SOFTLEVEL, "r"))) {
- runlevel = xmalloc (sizeof (char) * PATH_MAX);
- if (fgets (runlevel, PATH_MAX, fp)) {
- int i = strlen (runlevel) - 1;
+ if ((fp = fopen(SOFTLEVEL, "r"))) {
+ runlevel = xmalloc(sizeof(char) * PATH_MAX);
+ if (fgets(runlevel, PATH_MAX, fp)) {
+ int i = strlen(runlevel) - 1;
if (runlevel[i] == '\n')
runlevel[i] = 0;
} else
*runlevel = '\0';
- fclose (fp);
+ fclose(fp);
}
if (! runlevel || ! *runlevel) {
- free (runlevel);
- runlevel = xstrdup (RC_LEVEL_SYSINIT);
+ free(runlevel);
+ runlevel = xstrdup(RC_LEVEL_SYSINIT);
}
- return (runlevel);
+ return runlevel;
}
librc_hidden_def(rc_runlevel_get)
-bool rc_runlevel_set (const char *runlevel)
+bool rc_runlevel_set(const char *runlevel)
{
- FILE *fp = fopen (SOFTLEVEL, "w");
+ FILE *fp = fopen(SOFTLEVEL, "w");
if (! fp)
- return (false);
- fprintf (fp, "%s", runlevel);
- fclose (fp);
- return (true);
+ return false;
+ fprintf(fp, "%s", runlevel);
+ fclose(fp);
+ return true;
}
librc_hidden_def(rc_runlevel_set)
-bool rc_runlevel_exists (const char *runlevel)
+bool rc_runlevel_exists(const char *runlevel)
{
char *path;
struct stat buf;
bool retval = false;
if (! runlevel)
- return (false);
+ return false;
- path = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, (char *) NULL);
- if (stat (path, &buf) == 0 && S_ISDIR (buf.st_mode))
+ path = rc_strcatpaths(RC_RUNLEVELDIR, runlevel, (char *) NULL);
+ if (stat(path, &buf) == 0 && S_ISDIR(buf.st_mode))
retval = true;
- free (path);
- return (retval);
+ free(path);
+ return retval;
}
librc_hidden_def(rc_runlevel_exists)
- /* Resolve a service name to it's full path */
-char *rc_service_resolve (const char *service)
+/* Resolve a service name to it's full path */
+char *rc_service_resolve(const char *service)
{
char buffer[PATH_MAX];
char *file;
@@ -322,53 +326,53 @@ char *rc_service_resolve (const char *service)
struct stat buf;
if (! service)
- return (NULL);
+ return NULL;
if (service[0] == '/')
- return (xstrdup (service));
+ return xstrdup(service);
/* First check started services */
- file = rc_strcatpaths (RC_SVCDIR, "started", service, (char *) NULL);
- if (lstat (file, &buf) || ! S_ISLNK (buf.st_mode)) {
- free (file);
- file = rc_strcatpaths (RC_SVCDIR, "inactive", service, (char *) NULL);
- if (lstat (file, &buf) || ! S_ISLNK (buf.st_mode)) {
- free (file);
+ file = rc_strcatpaths(RC_SVCDIR, "started", service, (char *) NULL);
+ if (lstat(file, &buf) || ! S_ISLNK(buf.st_mode)) {
+ free(file);
+ file = rc_strcatpaths(RC_SVCDIR, "inactive", service, (char *) NULL);
+ if (lstat(file, &buf) || ! S_ISLNK(buf.st_mode)) {
+ free(file);
file = NULL;
}
}
- memset (buffer, 0, sizeof (buffer));
+ memset(buffer, 0, sizeof(buffer));
/* Nope, so lets see if the user has written it */
#ifdef RC_LOCAL_INITDIR
- snprintf (buffer, sizeof (buffer), RC_LOCAL_INITDIR "/%s", service);
- if (stat (buffer, &buf) == 0)
- return (xstrdup (buffer));
+ snprintf(buffer, sizeof(buffer), RC_LOCAL_INITDIR "/%s", service);
+ if (stat(buffer, &buf) == 0)
+ return xstrdup(buffer);
#endif
if (file) {
- r = readlink (file, buffer, sizeof (buffer));
- free (file);
+ r = readlink(file, buffer, sizeof(buffer));
+ free(file);
if (r > 0)
- return (xstrdup (buffer));
+ return xstrdup(buffer);
}
- snprintf (buffer, sizeof (buffer), RC_INITDIR "/%s", service);
+ snprintf(buffer, sizeof(buffer), RC_INITDIR "/%s", service);
/* So we don't exist in /etc/init.d - check RC_PKG_INITDIR */
#ifdef RC_PKG_INITDIR
- if (stat (buffer, &buf) != 0) {
- snprintf (buffer, sizeof (buffer), RC_PKG_INITDIR "/%s", service);
- if (stat (buffer, &buf) != 0)
- return (NULL);
+ if (stat(buffer, &buf) != 0) {
+ snprintf(buffer, sizeof(buffer), RC_PKG_INITDIR "/%s", service);
+ if (stat(buffer, &buf) != 0)
+ return NULL;
}
#endif
- return (xstrdup (buffer));
+ return xstrdup(buffer);
}
librc_hidden_def(rc_service_resolve)
-bool rc_service_exists (const char *service)
+bool rc_service_exists(const char *service)
{
char *file;
bool retval = false;
@@ -376,59 +380,62 @@ bool rc_service_exists (const char *service)
struct stat buf;
if (! service)
- return (false);
+ return false;
- len = strlen (service);
+ len = strlen(service);
/* .sh files are not init scripts */
if (len > 2 && service[len - 3] == '.' &&
service[len - 2] == 's' &&
service[len - 1] == 'h')
- return (false);
+ return false;
- if (! (file = rc_service_resolve (service)))
- return (false);
+ if (! (file = rc_service_resolve(service)))
+ return false;
- if (stat (file, &buf) == 0 && buf.st_mode & S_IXUGO)
+ if (stat(file, &buf) == 0 && buf.st_mode & S_IXUGO)
retval = true;
- free (file);
- return (retval);
+ free(file);
+ return retval;
}
librc_hidden_def(rc_service_exists)
#define OPTSTR ". '%s'; echo \"${opts}\""
-char **rc_service_extra_commands (const char *service)
+RC_STRINGLIST *rc_service_extra_commands(const char *service)
{
char *svc;
char *cmd = NULL;
char *buffer = NULL;
- char **commands = NULL;
+ RC_STRINGLIST *commands;
char *token;
char *p;
FILE *fp;
size_t l;
- if (! (svc = rc_service_resolve (service)))
- return (NULL);
-
- l = strlen (OPTSTR) + strlen (svc) + 1;
- cmd = xmalloc (sizeof (char) * l);
- snprintf (cmd, l, OPTSTR, svc);
- free (svc);
- if ((fp = popen (cmd, "r"))) {
- p = buffer = rc_getline (fp);
- while ((token = strsep (&p, " ")))
- rc_strlist_addsort (&commands, token);
- pclose (fp);
- free (buffer);
- }
- free (cmd);
- return (commands);
+ if (! (svc = rc_service_resolve(service)))
+ return NULL;
+
+ commands = rc_stringlist_new();
+
+ l = strlen(OPTSTR) + strlen(svc) + 1;
+ cmd = xmalloc(sizeof(char) * l);
+ snprintf(cmd, l, OPTSTR, svc);
+ free(svc);
+
+ if ((fp = popen(cmd, "r"))) {
+ p = buffer = rc_getline(fp);
+ while ((token = strsep(&p, " ")))
+ rc_stringlist_add(commands, token);
+ pclose(fp);
+ free(buffer);
+ }
+ free(cmd);
+ return commands;
}
librc_hidden_def(rc_service_extra_commands)
#define DESCSTR ". '%s'; echo \"${description%s%s}\""
-char *rc_service_description (const char *service, const char *option)
+char *rc_service_description(const char *service, const char *option)
{
char *svc;
char *cmd;
@@ -436,85 +443,90 @@ char *rc_service_description (const char *service, const char *option)
FILE *fp;
size_t l;
- if (! (svc = rc_service_resolve (service)))
- return (NULL);
+ if (! (svc = rc_service_resolve(service)))
+ return NULL;
if (! option)
option = "";
- l = strlen (DESCSTR) + strlen (svc) + strlen (option) + 2;
- cmd = xmalloc (sizeof (char) * l);
- snprintf (cmd, l, DESCSTR, svc, option ? "_" : "", option);
- free (svc);
- if ((fp = popen (cmd, "r"))) {
- desc = rc_getline (fp);
- pclose (fp);
+ l = strlen(DESCSTR) + strlen(svc) + strlen(option) + 2;
+ cmd = xmalloc(sizeof(char) * l);
+ snprintf(cmd, l, DESCSTR, svc, option ? "_" : "", option);
+ free(svc);
+ if ((fp = popen(cmd, "r"))) {
+ desc = rc_getline(fp);
+ pclose(fp);
}
- free (cmd);
- return (desc);
+ free(cmd);
+ return desc;
}
librc_hidden_def(rc_service_description)
-bool rc_service_in_runlevel (const char *service, const char *runlevel)
+bool rc_service_in_runlevel(const char *service, const char *runlevel)
{
char *file;
bool retval;
if (! runlevel || ! service)
- return (false);
+ return false;
- file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename_c (service),
- (char *) NULL);
- retval = exists (file);
- free (file);
+ file = rc_strcatpaths(RC_RUNLEVELDIR, runlevel, basename_c(service),
+ (char *) NULL);
+ retval = exists(file);
+ free(file);
- return (retval);
+ return retval;
}
librc_hidden_def(rc_service_in_runlevel)
-bool rc_service_mark (const char *service, const rc_service_state_t state)
+bool rc_service_mark(const char *service, const RC_SERVICE state)
{
char *file;
int i = 0;
int skip_state = -1;
const char *base;
- char *init = rc_service_resolve (service);
+ char *init = rc_service_resolve(service);
bool skip_wasinactive = false;
+ int s;
+ char *was;
+ RC_STRINGLIST *dirs;
+ RC_STRING *dir;
+ int serrno;
if (! init)
- return (false);
+ return false;
- base = basename_c (service);
+ base = basename_c(service);
if (state != RC_SERVICE_STOPPED) {
- if (! exists (init)) {
- free (init);
- return (false);
+ if (! exists(init)) {
+ free(init);
+ return false;
}
- file = rc_strcatpaths (RC_SVCDIR, rc_parse_service_state (state), base,
- (char *) NULL);
- if (exists (file))
- unlink (file);
- i = symlink (init, file);
- if (i != 0) {
- free (file);
- free (init);
- return (false);
+ file = rc_strcatpaths(RC_SVCDIR, rc_parse_service_state (state), base,
+ (char *) NULL);
+ if (exists(file))
+ unlink(file);
+ i = symlink(init, file);
+ if (i != 0) {
+ free(file);
+ free(init);
+ return false;
}
- free (file);
+ free(file);
skip_state = state;
}
if (state == RC_SERVICE_COLDPLUGGED || state == RC_SERVICE_FAILED) {
- free (init);
- return (true);
+ free(init);
+ return true;
}
/* Remove any old states now */
for (i = 0; rc_service_state_names[i].name; i++) {
- int s = rc_service_state_names[i].state;
+ s = rc_service_state_names[i].state;
if ((s != skip_state &&
s != RC_SERVICE_STOPPED &&
@@ -522,24 +534,24 @@ bool rc_service_mark (const char *service, const rc_service_state_t state)
s != RC_SERVICE_SCHEDULED) &&
(! skip_wasinactive || s != RC_SERVICE_WASINACTIVE))
{
- file = rc_strcatpaths (RC_SVCDIR, rc_parse_service_state (s), base,
- (char *) NULL);
- if (exists (file)) {
+ file = rc_strcatpaths(RC_SVCDIR, rc_parse_service_state(s), base,
+ (char *) NULL);
+ if (exists(file)) {
if ((state == RC_SERVICE_STARTING ||
state == RC_SERVICE_STOPPING) &&
s == RC_SERVICE_INACTIVE)
{
- char *wasfile = rc_strcatpaths (RC_SVCDIR,
- rc_parse_service_state (RC_SERVICE_WASINACTIVE),
- base, (char *) NULL);
+ was = rc_strcatpaths(RC_SVCDIR,
+ rc_parse_service_state(RC_SERVICE_WASINACTIVE),
+ base, (char *) NULL);
- symlink (init, wasfile);
+ symlink(init, was);
skip_wasinactive = true;
- free (wasfile);
+ free(was);
}
- unlink (file);
+ unlink(file);
}
- free (file);
+ free(file);
}
}
@@ -548,126 +560,133 @@ bool rc_service_mark (const char *service, const rc_service_state_t state)
state == RC_SERVICE_STOPPED ||
state == RC_SERVICE_INACTIVE)
{
- file = rc_strcatpaths (RC_SVCDIR, "exclusive", base, (char *) NULL);
- unlink (file);
- free (file);
+ file = rc_strcatpaths(RC_SVCDIR, "exclusive", base, (char *) NULL);
+ unlink(file);
+ free(file);
}
/* Remove any options and daemons the service may have stored */
if (state == RC_SERVICE_STOPPED) {
- char *dir = rc_strcatpaths (RC_SVCDIR, "options", base, (char *) NULL);
- rm_dir (dir, true);
- free (dir);
+ file = rc_strcatpaths(RC_SVCDIR, "options", base, (char *) NULL);
+ rm_dir(file, true);
+ free(file);
- dir = rc_strcatpaths (RC_SVCDIR, "daemons", base, (char *) NULL);
- rm_dir (dir, true);
- free (dir);
+ file = rc_strcatpaths(RC_SVCDIR, "daemons", base, (char *) NULL);
+ rm_dir(file, true);
+ free(file);
- rc_service_schedule_clear (service);
+ rc_service_schedule_clear(service);
}
/* These are final states, so remove us from scheduled */
if (state == RC_SERVICE_STARTED || state == RC_SERVICE_STOPPED) {
- char *sdir = rc_strcatpaths (RC_SVCDIR, "scheduled", (char *) NULL);
- char **dirs = ls_dir (sdir, 0);
- char *dir;
- int serrno;
+ file = rc_strcatpaths(RC_SVCDIR, "scheduled", (char *) NULL);
+ dirs = ls_dir(file, 0);
- STRLIST_FOREACH (dirs, dir, i) {
- char *bdir = rc_strcatpaths (sdir, dir, (char *) NULL);
- file = rc_strcatpaths (bdir, base, (char *) NULL);
- unlink (file);
- free (file);
+ TAILQ_FOREACH(dir, dirs, entries) {
+ was = rc_strcatpaths(file, dir->value, base, (char *) NULL);
+ unlink(was);
+ free(was);
/* Try and remove the dir - we don't care about errors */
+ was = rc_strcatpaths(file, dir->value, (char *) NULL);
serrno = errno;
- rmdir (bdir);
+ rmdir(was);
errno = serrno;
- free (bdir);
+ free(was);
}
- rc_strlist_free (dirs);
- free (sdir);
+ rc_stringlist_free(dirs);
}
- free (init);
- return (true);
+ free(init);
+ return true;
}
librc_hidden_def(rc_service_mark)
-rc_service_state_t rc_service_state (const char *service)
+RC_SERVICE rc_service_state(const char *service)
{
int i;
int state = RC_SERVICE_STOPPED;
+ char *file;
+ RC_STRINGLIST *dirs;
+ RC_STRING *dir;
for (i = 0; rc_service_state_names[i].name; i++) {
- char *file = rc_strcatpaths (RC_SVCDIR, rc_service_state_names[i].name,
- basename_c (service), (char*) NULL);
- if (exists (file)) {
+ file = rc_strcatpaths(RC_SVCDIR, rc_service_state_names[i].name,
+ basename_c(service), (char*) NULL);
+ if (exists(file)) {
if (rc_service_state_names[i].state <= 0x10)
state = rc_service_state_names[i].state;
else
state |= rc_service_state_names[i].state;
}
- free (file);
+ free(file);
}
if (state & RC_SERVICE_STOPPED) {
- char **services = rc_services_scheduled_by (service);
- if (services) {
- state |= RC_SERVICE_SCHEDULED;
- free (services);
+ dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
+ TAILQ_FOREACH (dir, dirs, entries) {
+ file = rc_strcatpaths(RC_SVCDIR, "scheduled",
+ dir->value,
+ service, (char *) NULL);
+ if (exists(file))
+ state |= RC_SERVICE_SCHEDULED;
+ free(file);
+ if (state & RC_SERVICE_SCHEDULED)
+ break;
}
+ rc_stringlist_free(dirs);
}
- return (state);
+ return state;
}
librc_hidden_def(rc_service_state)
-char *rc_service_value_get (const char *service, const char *option)
+char *rc_service_value_get(const char *service, const char *option)
{
FILE *fp;
char *line = NULL;
- char *file = rc_strcatpaths (RC_SVCDIR, "options", service, option,
- (char *) NULL);
+ char *file = rc_strcatpaths(RC_SVCDIR, "options", service, option,
+ (char *) NULL);
- if ((fp = fopen (file, "r"))) {
- line = rc_getline (fp);
- fclose (fp);
+ if ((fp = fopen(file, "r"))) {
+ line = rc_getline(fp);
+ fclose(fp);
}
- free (file);
+ free(file);
- return (line);
+ return line;
}
librc_hidden_def(rc_service_value_get)
-bool rc_service_value_set (const char *service, const char *option,
- const char *value)
+bool rc_service_value_set(const char *service, const char *option,
+ const char *value)
{
FILE *fp;
- char *path = rc_strcatpaths (RC_SVCDIR, "options", service, (char *) NULL);
- char *file = rc_strcatpaths (path, option, (char *) NULL);
+ char *path = rc_strcatpaths(RC_SVCDIR, "options", service, (char *) NULL);
+ char *file = rc_strcatpaths(path, option, (char *) NULL);
bool retval = false;
- if (mkdir (path, 0755) != 0 && errno != EEXIST) {
- free (path);
- free (file);
- return (false);
+ if (mkdir(path, 0755) != 0 && errno != EEXIST) {
+ free(path);
+ free(file);
+ return false;
}
- if ((fp = fopen (file, "w"))) {
+ if ((fp = fopen(file, "w"))) {
if (value)
- fprintf (fp, "%s", value);
- fclose (fp);
+ fprintf(fp, "%s", value);
+ fclose(fp);
retval = true;
}
- free (path);
- free (file);
- return (retval);
+ free(path);
+ free(file);
+ return retval;
}
librc_hidden_def(rc_service_value_set)
-static pid_t _exec_service (const char *service, const char *arg)
+static pid_t _exec_service(const char *service, const char *arg)
{
char *file;
char *fifo;
@@ -676,92 +695,92 @@ static pid_t _exec_service (const char *service, const char *arg)
sigset_t old;
struct sigaction sa;
- file = rc_service_resolve (service);
- if (! exists (file)) {
- rc_service_mark (service, RC_SERVICE_STOPPED);
- free (file);
- return (0);
+ file = rc_service_resolve(service);
+ if (! exists(file)) {
+ rc_service_mark(service, RC_SERVICE_STOPPED);
+ free(file);
+ return 0;
}
/* We create a fifo so that other services can wait until we complete */
- fifo = rc_strcatpaths (RC_SVCDIR, "exclusive", basename_c (service),
- (char *) NULL);
+ fifo = rc_strcatpaths(RC_SVCDIR, "exclusive", basename_c(service),
+ (char *) NULL);
- if (mkfifo (fifo, 0600) != 0 && errno != EEXIST) {
- free (fifo);
- free (file);
- return (-1);
+ if (mkfifo(fifo, 0600) != 0 && errno != EEXIST) {
+ free(fifo);
+ free(file);
+ return -1;
}
/* We need to block signals until we have forked */
- memset (&sa, 0, sizeof (sa));
+ memset(&sa, 0, sizeof (sa));
sa.sa_handler = SIG_DFL;
- sigemptyset (&sa.sa_mask);
- sigfillset (&full);
- sigprocmask (SIG_SETMASK, &full, &old);
+ sigemptyset(&sa.sa_mask);
+ sigfillset(&full);
+ sigprocmask(SIG_SETMASK, &full, &old);
- if ((pid = fork ()) == 0) {
+ if ((pid = fork()) == 0) {
/* Restore default handlers */
- sigaction (SIGCHLD, &sa, NULL);
- sigaction (SIGHUP, &sa, NULL);
- sigaction (SIGINT, &sa, NULL);
- sigaction (SIGQUIT, &sa, NULL);
- sigaction (SIGTERM, &sa, NULL);
- sigaction (SIGUSR1, &sa, NULL);
- sigaction (SIGWINCH, &sa, NULL);
+ sigaction(SIGCHLD, &sa, NULL);
+ sigaction(SIGHUP, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGQUIT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGUSR1, &sa, NULL);
+ sigaction(SIGWINCH, &sa, NULL);
/* Unmask signals */
- sigprocmask (SIG_SETMASK, &old, NULL);
+ sigprocmask(SIG_SETMASK, &old, NULL);
/* Safe to run now */
- execl (file, file, arg, (char *) NULL);
- fprintf (stderr, "unable to exec `%s': %s\n",
- file, strerror (errno));
- unlink (fifo);
- _exit (EXIT_FAILURE);
+ execl(file, file, arg, (char *) NULL);
+ fprintf(stderr, "unable to exec `%s': %s\n",
+ file, strerror(errno));
+ unlink(fifo);
+ _exit(EXIT_FAILURE);
}
if (pid == -1)
- fprintf (stderr, "fork: %s\n", strerror (errno));
+ fprintf(stderr, "fork: %s\n",strerror (errno));
- sigprocmask (SIG_SETMASK, &old, NULL);
+ sigprocmask(SIG_SETMASK, &old, NULL);
- free (fifo);
- free (file);
+ free(fifo);
+ free(file);
- return (pid);
+ return pid;
}
-pid_t rc_service_stop (const char *service)
+pid_t rc_service_stop(const char *service)
{
- rc_service_state_t state = rc_service_state (service);
+ RC_SERVICE state = rc_service_state(service);
if (state & RC_SERVICE_FAILED)
- return (-1);
+ return -1;
if (state & RC_SERVICE_STOPPED)
- return (0);
+ return 0;
- return (_exec_service (service, "stop"));
+ return _exec_service(service, "stop");
}
librc_hidden_def(rc_service_stop)
-pid_t rc_service_start (const char *service)
+pid_t rc_service_start(const char *service)
{
- rc_service_state_t state = rc_service_state (service);
+ RC_SERVICE state = rc_service_state(service);
if (state & RC_SERVICE_FAILED)
- return (-1);
+ return -1;
if (! state & RC_SERVICE_STOPPED)
- return (0);
+ return 0;
- return (_exec_service (service, "start"));
+ return _exec_service(service, "start");
}
librc_hidden_def(rc_service_start)
-bool rc_service_schedule_start (const char *service,
- const char *service_to_start)
+bool rc_service_schedule_start(const char *service,
+ const char *service_to_start)
{
char *dir;
char *init;
@@ -769,162 +788,156 @@ bool rc_service_schedule_start (const char *service,
bool retval;
/* service may be a provided service, like net */
- if (! service || ! rc_service_exists (service_to_start))
- return (false);
+ if (! service || ! rc_service_exists(service_to_start))
+ return false;
- dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename_c (service),
- (char *) NULL);
- if (mkdir (dir, 0755) != 0 && errno != EEXIST) {
- free (dir);
- return (false);
+ dir = rc_strcatpaths(RC_SVCDIR, "scheduled", basename_c(service),
+ (char *) NULL);
+ if (mkdir(dir, 0755) != 0 && errno != EEXIST) {
+ free(dir);
+ return false;
}
- init = rc_service_resolve (service_to_start);
- file = rc_strcatpaths (dir, basename_c (service_to_start), (char *) NULL);
- retval = (exists (file) || symlink (init, file) == 0);
- free (init);
- free (file);
- free (dir);
+ init = rc_service_resolve(service_to_start);
+ file = rc_strcatpaths(dir, basename_c(service_to_start), (char *) NULL);
+ retval = (exists(file) || symlink(init, file) == 0);
+ free(init);
+ free(file);
+ free(dir);
- return (retval);
+ return retval;
}
librc_hidden_def(rc_service_schedule_start)
-bool rc_service_schedule_clear (const char *service)
+bool rc_service_schedule_clear(const char *service)
{
- char *dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename_c (service),
- (char *) NULL);
+ char *dir = rc_strcatpaths(RC_SVCDIR, "scheduled", basename_c(service),
+ (char *) NULL);
bool retval;
- if (! (retval = rm_dir (dir, true)) && errno == ENOENT)
+ if (! (retval = rm_dir(dir, true)) && errno == ENOENT)
retval = true;
- free (dir);
- return (retval);
+ free(dir);
+ return retval;
}
librc_hidden_def(rc_service_schedule_clear)
-
-char **rc_services_in_runlevel (const char *runlevel)
+RC_STRINGLIST *rc_services_in_runlevel(const char *runlevel)
{
char *dir;
- char **list = NULL;
+ RC_STRINGLIST *list;
if (! runlevel) {
-#if defined(RC_PKG_INITDIR) || defined(RC_LOCAL_INITDIR)
- int i;
-#endif
#ifdef RC_PKG_INITDIR
- char **pkg = ls_dir (RC_PKG_INITDIR, LS_INITD);
+ RC_STRINGLIST *pkg = ls_dir(RC_PKG_INITDIR, LS_INITD);
#endif
#ifdef RC_LOCAL_INITDIR
- char **local = ls_dir (RC_LOCAL_INITDIR, LS_INITD);
+ RC_STRINGLIST *local = ls_dir(RC_LOCAL_INITDIR, LS_INITD);
#endif
- list = ls_dir (RC_INITDIR, LS_INITD);
+ list = ls_dir(RC_INITDIR, LS_INITD);
#ifdef RC_PKG_INITDIR
- STRLIST_FOREACH (pkg, dir, i)
- rc_strlist_addsortu (&list, dir);
- rc_strlist_free (pkg);
+ if (pkg) {
+ TAILQ_CONCAT(list, pkg);
+ free(pkg);
+ }
#endif
#ifdef RC_LOCAL_DIR
- STRLIST_FOREACH (local, dir, i)
- rc_strlist_addsortu (&list, dir);
- rc_strlist_free (local);
+ if (local) {
+ TAILQ_CONCAT(list, local);
+ free(local);
+ }
#endif
- return (list);
+ return list;
}
/* These special levels never contain any services */
- if (strcmp (runlevel, RC_LEVEL_SYSINIT) == 0 ||
- strcmp (runlevel, RC_LEVEL_SINGLE) == 0)
- return (NULL);
-
- dir = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, (char *) NULL);
- list = ls_dir (dir, LS_INITD);
- free (dir);
- return (list);
+ if (strcmp(runlevel, RC_LEVEL_SYSINIT) == 0 ||
+ strcmp(runlevel, RC_LEVEL_SINGLE) == 0) {
+ list = rc_stringlist_new();
+ return list;
+ }
+
+ dir = rc_strcatpaths(RC_RUNLEVELDIR, runlevel, (char *) NULL);
+ list = ls_dir(dir, LS_INITD);
+ free(dir);
+ return list;
}
librc_hidden_def(rc_services_in_runlevel)
-char **rc_services_in_state (rc_service_state_t state)
+RC_STRINGLIST *rc_services_in_state(RC_SERVICE state)
{
- char *dir = rc_strcatpaths (RC_SVCDIR, rc_parse_service_state (state),
- (char *) NULL);
- char **list = NULL;
+ char *dir = rc_strcatpaths(RC_SVCDIR, rc_parse_service_state(state),
+ (char *) NULL);
+ RC_STRINGLIST *services;
+ RC_STRINGLIST *list;
+ RC_STRINGLIST *dirs;
+ RC_STRING *d;
+ char *p;
if (state == RC_SERVICE_SCHEDULED) {
- char **dirs = ls_dir (dir, 0);
- char *d;
- int i;
-
- STRLIST_FOREACH (dirs, d, i) {
- char *p = rc_strcatpaths (dir, d, (char *) NULL);
- char **entries = ls_dir (p, LS_INITD);
- char *e;
- int j;
-
- STRLIST_FOREACH (entries, e, j)
- rc_strlist_addsortu (&list, e);
-
- if (entries)
- free (entries);
+ dirs = ls_dir(dir, 0);
+ list = rc_stringlist_new();
+ TAILQ_FOREACH(d, dirs, entries) {
+ p = rc_strcatpaths(dir, d->value, (char *) NULL);
+ services = ls_dir(p, LS_INITD);
+ free(p);
+ TAILQ_CONCAT(list, services);
+ free(services);
}
-
- if (dirs)
- free (dirs);
+ rc_stringlist_free(dirs);
} else {
- list = ls_dir (dir, LS_INITD);
+ list = ls_dir(dir, LS_INITD);
}
- free (dir);
- return (list);
+ free(dir);
+ return list;
}
librc_hidden_def(rc_services_in_state)
-bool rc_service_add (const char *runlevel, const char *service)
+bool rc_service_add(const char *runlevel, const char *service)
{
bool retval;
char *init;
char *file;
+ char path[MAXPATHLEN] = { '\0' };
+ char *p;
- if (! rc_runlevel_exists (runlevel)) {
+ if (! rc_runlevel_exists(runlevel)) {
errno = ENOENT;
- return (false);
+ return false;
}
- if (rc_service_in_runlevel (service, runlevel)) {
+ if (rc_service_in_runlevel(service, runlevel)) {
errno = EEXIST;
- return (false);
+ return false;
}
- init = rc_service_resolve (service);
+ init = rc_service_resolve(service);
/* We need to ensure that only things in /etc/init.d are added
* to the boot runlevel */
if (strcmp (runlevel, RC_LEVEL_BOOT) == 0) {
- char tmp[MAXPATHLEN] = { '\0' };
- char *p;
-
- p = realpath (dirname (init), tmp);
- free (init);
+ p = realpath(dirname (init), path);
+ free(init);
if (! *p)
- return (false);
+ return false;
- retval = (strcmp (tmp, RC_INITDIR) == 0);
+ retval = (strcmp(path, RC_INITDIR) == 0);
if (! retval) {
errno = EPERM;
- return (false);
+ return false;
}
- init = rc_strcatpaths (RC_INITDIR, service, (char *) NULL);
+ init = rc_strcatpaths(RC_INITDIR, service, (char *) NULL);
}
- file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename_c (service),
- (char *) NULL);
- retval = (symlink (init, file) == 0);
- free (init);
- free (file);
- return (retval);
+ file = rc_strcatpaths(RC_RUNLEVELDIR, runlevel, basename_c(service),
+ (char *) NULL);
+ retval = (symlink(init, file) == 0);
+ free(init);
+ free(file);
+ return retval;
}
librc_hidden_def(rc_service_add)
@@ -934,46 +947,46 @@ bool rc_service_delete (const char *runlevel, const char *service)
bool retval = false;
if (! runlevel || ! service)
- return (false);
+ return false;
- file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename_c (service),
+ file = rc_strcatpaths (RC_RUNLEVELDIR, runlevel, basename_c(service),
(char *) NULL);
- if (unlink (file) == 0)
+ if (unlink(file) == 0)
retval = true;
- free (file);
- return (retval);
+ free(file);
+ return retval;
}
librc_hidden_def(rc_service_delete)
-char **rc_services_scheduled_by (const char *service)
+RC_STRINGLIST *rc_services_scheduled_by(const char *service)
{
- char **dirs = ls_dir (RC_SVCDIR "/scheduled", 0);
- char **list = NULL;
- char *dir;
- int i;
+ RC_STRINGLIST *dirs = ls_dir(RC_SVCDIR "/scheduled", 0);
+ RC_STRINGLIST *list;
+ RC_STRING *dir;
+ char *file;
- STRLIST_FOREACH (dirs, dir, i) {
- char *file = rc_strcatpaths (RC_SVCDIR, "scheduled", dir, service,
- (char *) NULL);
- if (exists (file))
- rc_strlist_add (&list, file);
- free (file);
+ list = rc_stringlist_new();
+ TAILQ_FOREACH (dir, dirs, entries) {
+ file = rc_strcatpaths(RC_SVCDIR, "scheduled", dir->value,
+ service, (char *) NULL);
+ if (exists(file))
+ rc_stringlist_add(list, file);
+ free(file);
}
- rc_strlist_free (dirs);
+ rc_stringlist_free(dirs);
- return (list);
+ return list;
}
librc_hidden_def(rc_services_scheduled_by)
-char **rc_services_scheduled (const char *service)
+RC_STRINGLIST *rc_services_scheduled(const char *service)
{
- char *dir = rc_strcatpaths (RC_SVCDIR, "scheduled", basename_c (service),
- (char *) NULL);
- char **list = NULL;
+ char *dir = rc_strcatpaths(RC_SVCDIR, "scheduled", basename_c(service),
+ (char *) NULL);
+ RC_STRINGLIST *list = ls_dir(dir, LS_INITD);
- list = ls_dir (dir, LS_INITD);
- free (dir);
- return (list);
+ free(dir);
+ return list;
}
librc_hidden_def(rc_services_scheduled)
diff --git a/src/librc/librc.h b/src/librc/librc.h
index edbebaf..aaad7cc 100644
--- a/src/librc/librc.h
+++ b/src/librc/librc.h
@@ -64,10 +64,8 @@
#include <kvm.h>
#endif
-#include "librc-depend.h"
#include "rc.h"
#include "rc-misc.h"
-#include "strlist.h"
#include "hidden-visibility.h"
#define librc_hidden_proto(x) hidden_proto(x)
@@ -115,15 +113,11 @@ librc_hidden_proto(rc_service_state)
librc_hidden_proto(rc_service_value_get)
librc_hidden_proto(rc_service_value_set)
librc_hidden_proto(rc_strcatpaths)
-librc_hidden_proto(rc_strlist_add)
-librc_hidden_proto(rc_strlist_addu)
-librc_hidden_proto(rc_strlist_addsort)
-librc_hidden_proto(rc_strlist_addsortc)
-librc_hidden_proto(rc_strlist_addsortu)
-librc_hidden_proto(rc_strlist_delete)
-librc_hidden_proto(rc_strlist_free)
-librc_hidden_proto(rc_strlist_join)
-librc_hidden_proto(rc_strlist_reverse)
+librc_hidden_proto(rc_stringlist_add)
+librc_hidden_proto(rc_stringlist_addu)
+librc_hidden_proto(rc_stringlist_delete)
+librc_hidden_proto(rc_stringlist_free)
+librc_hidden_proto(rc_stringlist_sort)
librc_hidden_proto(rc_yesno)
#endif
diff --git a/src/librc/rc.h b/src/librc/rc.h
index 0b811f4..061959e 100644
--- a/src/librc/rc.h
+++ b/src/librc/rc.h
@@ -32,15 +32,24 @@
# if (GCC_VERSION >= 3005)
# define SENTINEL __attribute__ ((__sentinel__))
# endif
+# define DEPRECATED __attribute__ ((deprecated))
#endif
#ifndef SENTINEL
# define SENTINEL
#endif
#include <sys/types.h>
+#include <sys/queue.h>
#include <stdbool.h>
#include <stdio.h>
+/* A doubly linked list using queue(3) for ease of use */
+typedef struct rc_string {
+ char *value;
+ TAILQ_ENTRY(rc_string) entries;
+} RC_STRING;
+typedef TAILQ_HEAD(rc_stringlist, rc_string) RC_STRINGLIST;
+
/*! @name Reserved runlevel names */
#define RC_LEVEL_SYSINIT "sysinit"
#define RC_LEVEL_SINGLE "single"
@@ -49,30 +58,30 @@
/*! Return the current runlevel.
* @return the current runlevel */
-char *rc_runlevel_get (void);
+char *rc_runlevel_get(void);
/*! Checks if the runlevel exists or not
* @param runlevel to check
* @return true if the runlevel exists, otherwise false */
-bool rc_runlevel_exists (const char *runlevel);
+bool rc_runlevel_exists(const char *);
/*! Return a NULL terminated list of runlevels
* @return a NULL terminated list of runlevels */
-char **rc_runlevel_list (void);
+RC_STRINGLIST *rc_runlevel_list(void);
/*! Set the runlevel.
* This just changes the stored runlevel and does not start or stop any
* services.
* @param runlevel to store */
-bool rc_runlevel_set (const char *runlevel);
+bool rc_runlevel_set(const char *);
/*! Is the runlevel starting?
* @return true if yes, otherwise false */
-bool rc_runlevel_starting (void);
+bool rc_runlevel_starting(void);
/*! Is the runlevel stopping?
* @return true if yes, otherwise false */
-bool rc_runlevel_stopping (void);
+bool rc_runlevel_stopping(void);
/*! @name RC
* A service can be given as a full path or just its name.
@@ -97,19 +106,19 @@ typedef enum
RC_SERVICE_FAILED = 0x0200,
RC_SERVICE_SCHEDULED = 0x0400,
RC_SERVICE_WASINACTIVE = 0x0800
-} rc_service_state_t;
+} RC_SERVICE;
/*! Add the service to the runlevel
* @param runlevel to add to
* @param service to add
* @return true if successful, otherwise false */
-bool rc_service_add (const char *runlevel, const char *service);
+bool rc_service_add(const char *, const char *);
/*! Remove the service from the runlevel
* @param runlevel to remove from
* @param service to remove
* @return true if sucessful, otherwise false */
-bool rc_service_delete (const char *runlevel, const char *service);
+bool rc_service_delete(const char *, const char *);
/*! Save the arguments to find a running daemon
* @param service to save arguments for
@@ -117,116 +126,113 @@ bool rc_service_delete (const char *runlevel, const char *service);
* @param name of the process (optional)
* @param pidfile of the process (optional)
* @param started if true, add the arguments otherwise remove existing matching arguments */
-bool rc_service_daemon_set (const char *service, const char *const *argv,
- const char *name, const char *pidfile,
- bool started);
+bool rc_service_daemon_set(const char *, const char *const *, const char *, const char *,
+ bool);
/*! Returns a description of what the service and/or option does.
* @param service to check
* @param option to check (if NULL, service description)
* @return a newly allocated pointer to the description */
-char *rc_service_description (const char *service, const char *option);
+char *rc_service_description(const char *, const char *);
/*! Checks if a service exists or not.
* @param service to check
* @return true if service exists, otherwise false */
-bool rc_service_exists (const char *service);
+bool rc_service_exists(const char *);
/*! Checks if a service is in a runlevel
* @param service to check
* @param runlevel it should be in
* @return true if service is in the runlevel, otherwise false */
-bool rc_service_in_runlevel (const char *service, const char *runlevel);
+bool rc_service_in_runlevel(const char *, const char *);
/*! Marks the service state
* @param service to mark
* @param state service should be in
* @return true if service state change was successful, otherwise false */
-bool rc_service_mark (const char *service, rc_service_state_t state);
+bool rc_service_mark(const char *, RC_SERVICE);
/*! Lists the extra commands a service has
* @param service to load the commands from
* @return NULL terminated string list of commands */
-char **rc_service_extra_commands (const char *service);
+RC_STRINGLIST *rc_service_extra_commands(const char *);
/*! Resolves a service name to its full path.
* @param service to check
* @return pointer to full path of service */
-char *rc_service_resolve (const char *service);
+char *rc_service_resolve(const char *);
/*! Schedule a service to be started when another service starts
* @param service that starts the scheduled service when started
* @param service_to_start service that will be started */
-bool rc_service_schedule_start (const char *service,
- const char *service_to_start);
+bool rc_service_schedule_start(const char *, const char *);
+
/*! Return a NULL terminated list of services that are scheduled to start
* when the given service has started
* @param service to check
* @return NULL terminated list of services scheduled to start */
-char **rc_services_scheduled_by (const char *service);
+RC_STRINGLIST *rc_services_scheduled_by(const char *);
/*! Clear the list of services scheduled to be started by this service
* @param service to clear
* @return true if no errors, otherwise false */
-bool rc_service_schedule_clear (const char *service);
+bool rc_service_schedule_clear(const char *);
/*! Checks if a service in in a state
* @param service to check
* @return state of the service */
-rc_service_state_t rc_service_state (const char *service);
+RC_SERVICE rc_service_state(const char *);
/*! Start a service
* @param service to start
* @return pid of the service starting process */
-pid_t rc_service_start (const char *service);
+pid_t rc_service_start(const char *);
/*! Stop a service
* @param service to stop
* @return pid of service stopping process */
-pid_t rc_service_stop (const char *service);
+pid_t rc_service_stop(const char *);
/*! Check if the service started the daemon
* @param service to check
* @param exec to check
* @param indx of the daemon (optional - 1st daemon, 2nd daemon, etc)
* @return true if started by this service, otherwise false */
-bool rc_service_started_daemon (const char *service, const char *const *argv,
- int indx);
+bool rc_service_started_daemon(const char *, const char *const *, int);
/*! Return a saved value for a service
* @param service to check
* @param option to load
* @return saved value */
-char *rc_service_value_get (const char *service, const char *option);
+char *rc_service_value_get(const char *, const char *);
/*! Save a persistent value for a service
* @param service to save for
* @param option to save
* @param value of the option
* @return true if saved, otherwise false */
-bool rc_service_value_set (const char *service, const char *option,
- const char *value);
+bool rc_service_value_set(const char *, const char *, const char *);
/*! List the services in a runlevel
* @param runlevel to list
* @return NULL terminated list of services */
-char **rc_services_in_runlevel (const char *runlevel);
+RC_STRINGLIST *rc_services_in_runlevel(const char *);
/*! List the services in a state
* @param state to list
* @return NULL terminated list of services */
-char **rc_services_in_state (rc_service_state_t state);
+RC_STRINGLIST *rc_services_in_state(RC_SERVICE);
/*! List the services shceduled to start when this one does
* @param service to check
* @return NULL terminated list of services */
-char **rc_services_scheduled (const char *service);
+RC_STRINGLIST *rc_services_scheduled(const char *);
/*! Checks that all daemons started with start-stop-daemon by the service
* are still running.
* @param service to check
* @return true if all daemons started are still running, otherwise false */
-bool rc_service_daemons_crashed (const char *service);
+bool rc_service_daemons_crashed(const char *);
/*! @name System types
* OpenRC can support some special sub system types, normally virtualization.
@@ -238,7 +244,7 @@ bool rc_service_daemons_crashed (const char *service);
#define RC_SYS_VSERVER "VSERVER"
#define RC_SYS_XEN0 "XEN0"
#define RC_SYS_XENU "XENU"
-const char *rc_sys (void);
+const char *rc_sys(void);
/*! @name Dependency options
* These options can change the services found by the rc_get_depinfo and
@@ -256,40 +262,67 @@ const char *rc_sys (void);
* We analyse each init script and cache the resultant dependency tree.
* This tree can be accessed using the below functions. */
-#ifndef _IN_LIBRC
+#ifdef _IN_LIBRC
+/*! @name Dependency structures
+ * private to librc */
+
+/*! Singly linked list of dependency types that list the services the
+ * type is for */
+typedef struct rc_deptype
+{
+ /*! ineed, iuse, iafter, etc */
+ char *type;
+ /*! list of services */
+ RC_STRINGLIST *services;
+ /*! list of types */
+ STAILQ_ENTRY(rc_deptype) entries;
+} RC_DEPTYPE;
+
+/*! Singly linked list of services and their dependencies */
+typedef struct rc_depinfo
+{
+ /*! Name of service */
+ char *service;
+ /*! Dependencies */
+ STAILQ_HEAD(, rc_deptype) depends;
+ /*! List of entries */
+ STAILQ_ENTRY(rc_depinfo) entries;
+} RC_DEPINFO;
+
+typedef STAILQ_HEAD(,rc_depinfo) RC_DEPTREE;
+#else
/* Handles to internal structures */
-typedef void *rc_depinfo_t;
+typedef void *RC_DEPTREE;
#endif
/*! Check to see if source is newer than target.
* If target is a directory then we traverse it and it's children.
* @return true if source is newer than target, otherwise false */
-bool rc_newer_than (const char *source, const char *target);
+bool rc_newer_than(const char *, const char *);
/*! Update the cached dependency tree if it's older than any init script,
* its configuration file or an external configuration file the init script
* has specified.
* @return true if successful, otherwise false */
-bool rc_deptree_update (void);
+bool rc_deptree_update(void);
/*! Check if the cached dependency tree is older than any init script,
* its configuration file or an external configuration file the init script
* has specified.
* @return true if it needs updating, otherwise false */
-bool rc_deptree_update_needed (void);
+bool rc_deptree_update_needed(void);
/*! Load the cached dependency tree and return a pointer to it.
* This pointer should be freed with rc_deptree_free when done.
* @return pointer to the dependency tree */
-rc_depinfo_t *rc_deptree_load (void);
+RC_DEPTREE *rc_deptree_load(void);
/*! List the depend for the type of service
* @param deptree to search
* @param type to use (keywords, etc)
* @param service to check
* @return NULL terminated list of services in order */
-char **rc_deptree_depend (const rc_depinfo_t *deptree,
- const char *type, const char *service);
+RC_STRINGLIST *rc_deptree_depend(const RC_DEPTREE *, const char *, const char *);
/*! List all the services in order that the given services have
* for the given types and options.
@@ -298,10 +331,8 @@ char **rc_deptree_depend (const rc_depinfo_t *deptree,
* @param services to check
* @param options to pass
* @return NULL terminated list of services in order */
-char **rc_deptree_depends (const rc_depinfo_t *deptree,
- const char *const *types,
- const char *const *services, const char *runlevel,
- int options);
+RC_STRINGLIST *rc_deptree_depends(const RC_DEPTREE *, const RC_STRINGLIST *,
+ const RC_STRINGLIST *, const char *, int);
/*! List all the services that should be stoppned and then started, in order,
* for the given runlevel, including sysinit and boot services where
@@ -310,12 +341,11 @@ char **rc_deptree_depends (const rc_depinfo_t *deptree,
* @param runlevel to change into
* @param options to pass
* @return NULL terminated list of services in order */
-char **rc_deptree_order (const rc_depinfo_t *deptree, const char *runlevel,
- int options);
+RC_STRINGLIST *rc_deptree_order(const RC_DEPTREE *, const char *, int);
/*! Free a deptree and its information
* @param deptree to free */
-void rc_deptree_free (rc_depinfo_t *deptree);
+void rc_deptree_free(RC_DEPTREE *);
/*! @name Plugins
* For each plugin loaded we will call rc_plugin_hook with the below
@@ -347,13 +377,13 @@ typedef enum
RC_HOOK_SERVICE_START_NOW = 106,
RC_HOOK_SERVICE_START_DONE = 107,
RC_HOOK_SERVICE_START_OUT = 108
-} rc_hook_t;
+} RC_HOOK;
/*! Plugin entry point
* @param hook point
* @param name of runlevel or service
* @return 0 for success otherwise -1 */
-int rc_plugin_hook (rc_hook_t hook, const char *name);
+int rc_plugin_hook(RC_HOOK, const char *);
/*! Plugins should write FOO=BAR to this fd to set any environment
* variables they wish. Variables should be separated by NULLs. */
@@ -362,91 +392,64 @@ extern FILE *rc_environ_fd;
/*! @name Configuration
* These functions help to deal with shell based configuration files */
/*! Return a line from a file, stripping the trailing newline. */
-char *rc_getline (FILE *fp);
+char *rc_getline(FILE *);
/*! Return a NULL terminated list of non comment lines from a file. */
-char **rc_config_list (const char *file);
+RC_STRINGLIST *rc_config_list(const char *);
/*! Return a NULL terminated list of key=value lines from a file. */
-char **rc_config_load (const char *file);
+RC_STRINGLIST *rc_config_load(const char *);
/*! Return the value of the entry from a key=value list. */
-char *rc_config_value (const char *const *list, const char *entry);
+char *rc_config_value(RC_STRINGLIST *, const char *);
/*! Check if a variable is a boolean and return it's value.
* If variable is not a boolean then we set errno to be ENOENT when it does
* not exist or EINVAL if it's not a boolean.
* @param variable to check
* @return true if it matches true, yes or 1, false if otherwise. */
-bool rc_yesno (const char *variable);
+bool rc_yesno(const char *);
/*! @name String List functions
- * Handy functions for dealing with string arrays of char **.
- * It's safe to assume that any function here that uses char ** is a string
- * list that can be manipulated with the below functions. Every string list
- * should be released with a call to rc_strlist_free. */
+ * Every string list should be released with a call to rc_stringlist_free. */
+
+/*! Create a new stringlinst
+ * @return pointer to new list */
+RC_STRINGLIST *rc_stringlist_new(void);
/*! Duplicate the item, add it to end of the list and return a pointer to it.
* @param list to add the item too
* @param item to add.
* @return pointer to newly added item */
-char *rc_strlist_add (char ***list, const char *item);
+RC_STRING *rc_stringlist_add(RC_STRINGLIST *, const char *);
/*! If the item does not exist in the list, duplicate it, add it to the
* list and then return a pointer to it.
* @param list to add the item too
* @param item to add.
* @return pointer to newly added item */
-char *rc_strlist_addu (char ***list, const char *item);
-
-/*! Duplicate the item, add it to the list at the point based on locale and
- * then return a pointer to it.
- * @param list to add the item too
- * @param item to add.
- * @return pointer to newly added item */
-char *rc_strlist_addsort (char ***list, const char *item);
-
-/*! Duplicate the item, add it to the list at the point based on C locale and
- * then return a pointer to it.
- * @param list to add the item too
- * @param item to add.
- * @return pointer to newly added item */
-char *rc_strlist_addsortc (char ***list, const char *item);
-
-/*! If the item does not exist in the list, duplicate it, add it to the
- * list based on locale and then return a pointer to it.
- * @param list to add the item too
- * @param item to add.
- * @return pointer to newly added item */
-char *rc_strlist_addsortu (char ***list, const char *item);
+RC_STRING *rc_stringlist_addu(RC_STRINGLIST *, const char *);
/*! Free the item and remove it from the list. Return 0 on success otherwise -1.
* @param list to add the item too
* @param item to add.
* @return true on success, otherwise false */
-bool rc_strlist_delete (char ***list, const char *item);
-
-/*! Moves the contents of list2 onto list1, so list2 is effectively emptied.
- * Returns a pointer to the last item on the new list.
- * @param list1 to append to
- * @param list2 to move from
- * @return pointer to the last item on the list */
-char *rc_strlist_join (char ***list1, char **list2);
+bool rc_stringlist_delete(RC_STRINGLIST *, const char *);
-/*! Reverses the contents of the list.
- * @param list to reverse */
-void rc_strlist_reverse (char **list);
+/*! Sort the list according to C locale
+ * @param list to sort */
+void rc_stringlist_sort(RC_STRINGLIST **);
/*! Frees each item on the list and the list itself.
* @param list to free */
-void rc_strlist_free (char **list);
+void rc_stringlist_free(RC_STRINGLIST *);
/*! Concatenate paths adding '/' if needed. The resultant pointer should be
* freed when finished with.
* @param path1 starting path
* @param paths NULL terminated list of paths to add
* @return pointer to the new path */
-char *rc_strcatpaths (const char *path1, const char *paths, ...) SENTINEL;
+char *rc_strcatpaths(const char *, const char *, ...) SENTINEL;
/*! Find processes based on criteria.
* All of these are optional.
@@ -457,7 +460,6 @@ char *rc_strcatpaths (const char *path1, const char *paths, ...) SENTINEL;
* @param uid to check for
* @param pid to check for
* @return NULL terminated list of pids */
-pid_t *rc_find_pids (const char *const *argv, const char *cmd,
- uid_t uid, pid_t pid);
+pid_t *rc_find_pids(const char *const *, const char *, uid_t, pid_t);
#endif
diff --git a/src/librc/rc.map b/src/librc/rc.map
index e5fd350..8ad4e18 100644
--- a/src/librc/rc.map
+++ b/src/librc/rc.map
@@ -43,15 +43,12 @@ global:
rc_service_value_get;
rc_service_value_set;
rc_strcatpaths;
- rc_strlist_add;
- rc_strlist_addu;
- rc_strlist_addsort;
- rc_strlist_addsortc;
- rc_strlist_addsortu;
- rc_strlist_delete;
- rc_strlist_free;
- rc_strlist_join;
- rc_strlist_reverse;
+ rc_stringlist_add;
+ rc_stringlist_addu;
+ rc_stringlist_delete;
+ rc_stringlist_new;
+ rc_stringlist_sort;
+ rc_stringlist_free;
rc_sys;
rc_yesno;
diff --git a/src/rc/.gitignore b/src/rc/.gitignore
index eaa7de9..d249976 100644
--- a/src/rc/.gitignore
+++ b/src/rc/.gitignore
@@ -55,6 +55,7 @@ rc-abort
checkpath.o
fstabinfo.o
mountinfo.o
+start-stop-daemon.o
rc-applets.o
rc-depend.o
rc-logger.o
@@ -62,8 +63,7 @@ rc-misc.o
rc-plugin.o
rc-status.o
rc-update.o
-rc.o
runscript.o
-start-stop-daemon.o
+rc.o
rc
.depend
diff --git a/src/rc/Makefile b/src/rc/Makefile
index df185d6..469ac98 100644
--- a/src/rc/Makefile
+++ b/src/rc/Makefile
@@ -1,8 +1,8 @@
PROG= rc
-SRCS= checkpath.c fstabinfo.c mountinfo.c \
+SRCS= checkpath.c fstabinfo.c mountinfo.c start-stop-daemon.c \
rc-applets.c rc-depend.c rc-logger.c \
- rc-misc.c rc-plugin.c rc-status.c rc-update.c rc.c \
- runscript.c start-stop-daemon.c
+ rc-misc.c rc-plugin.c rc-status.c rc-update.c \
+ runscript.c rc.c
CLEANFILES= version.h
@@ -31,8 +31,9 @@ ALL_LINKS= ${BINLINKS} ${SBINLINKS} ${RC_BINLINKS} ${RC_SBINLINKS}
CLEANFILES+= ${ALL_LINKS}
LDFLAGS+= -L../librc -L../libeinfo
-#LDFLAGS+= -Wl,--rpath=../librc -Wl,--rpath=../libeinfo
LDADD+= -lutil -lrc -leinfo
+#CFLAGS+= -ggdb
+#LDFLAGS+= -Wl,--rpath=../librc -Wl,--rpath=../libeinfo
MK= ../../mk
include ${MK}/cc.mk
diff --git a/src/rc/_usage.c b/src/rc/_usage.c
index 7ad925d..afe517f 100644
--- a/src/rc/_usage.c
+++ b/src/rc/_usage.c
@@ -33,35 +33,36 @@
# define _noreturn
#endif
-_noreturn static void usage (int exit_status)
+_noreturn static void usage(int exit_status)
{
const char * const has_arg[] = { "", "<arg>", "[arg]" };
int i;
+ int len;
+ char *lo;
+ char *p;
+ char *token;
#ifdef usagestring
- printf (usagestring);
+ printf(usagestring);
#else
- printf ("Usage: %s [options] ", applet);
+ printf("Usage: %s [options] ", applet);
#endif
#ifdef extraopts
- printf (extraopts);
+ printf(extraopts);
#endif
- printf ("\n\nOptions: [" getoptstring "]\n");
+ printf("\n\nOptions: [" getoptstring "]\n");
for (i = 0; longopts[i].name; ++i) {
- int len = printf (" -%c, --%s %s", longopts[i].val, longopts[i].name,
- has_arg[longopts[i].has_arg]);
+ len = printf(" -%c, --%s %s", longopts[i].val, longopts[i].name,
+ has_arg[longopts[i].has_arg]);
- char *lo = xstrdup (longopts_help[i]);
- char *p = lo;
- char *token;
-
- while ((token = strsep (&p, "\n"))) {
+ lo = p = xstrdup(longopts_help[i]);
+ while ((token = strsep(&p, "\n"))) {
while (++len < 37)
- printf (" ");
- puts (token);
+ printf(" ");
+ puts(token);
len = 0;
}
- free (lo);
+ free(lo);
}
- exit (exit_status);
+ exit(exit_status);
}
diff --git a/src/rc/builtins.h b/src/rc/builtins.h
index 6d180ba..8132584 100644
--- a/src/rc/builtins.h
+++ b/src/rc/builtins.h
@@ -38,4 +38,4 @@ int start_stop_daemon (int argc, char **argv);
void run_applets (int argc, char **argv);
/* Handy function so we can wrap einfo around our deptree */
-rc_depinfo_t *_rc_deptree_load (int *regen);
+RC_DEPTREE *_rc_deptree_load (int *regen);
diff --git a/src/rc/checkpath.c b/src/rc/checkpath.c
index 7b16aee..4bf0c46 100644
--- a/src/rc/checkpath.c
+++ b/src/rc/checkpath.c
@@ -32,6 +32,7 @@
#include <sys/types.h>
#include <sys/stat.h>
+
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
@@ -48,84 +49,84 @@
extern const char *applet;
-static int do_check (char *path, uid_t uid, gid_t gid, mode_t mode, int file)
+static int do_check(char *path, uid_t uid, gid_t gid, mode_t mode, int file)
{
struct stat st;
+ int fd;
- memset (&st, 0, sizeof (st));
-
- if (stat (path, &st)) {
+ if (stat(path, &st)) {
if (file) {
- int fd;
- einfo ("%s: creating file", path);
- if ((fd = open (path, O_CREAT)) == -1) {
- eerror ("%s: open: %s", applet, strerror (errno));
- return (-1);
+ einfo("%s: creating file", path);
+ if ((fd = open(path, O_CREAT)) == -1) {
+ eerror("%s: open: %s", applet, strerror(errno));
+ return -1;
}
close (fd);
} else {
- einfo ("%s: creating directory", path);
+ einfo("%s: creating directory", path);
if (! mode)
mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
- if (mkdir (path, mode)) {
- eerror ("%s: mkdir: %s", applet, strerror (errno));
- return (-1);
+ if (mkdir(path, mode)) {
+ eerror("%s: mkdir: %s", applet, strerror (errno));
+ return -1;
}
mode = 0;
}
} else {
- if ((file && S_ISDIR (st.st_mode)) ||
- (! file && ! S_ISDIR (st.st_mode)))
+ if ((file && S_ISDIR(st.st_mode)) ||
+ (! file && ! S_ISDIR(st.st_mode)))
{
if (file)
- eerror ("%s: is a directory", path);
+ eerror("%s: is a directory", path);
else
- eerror ("%s: is a file", path);
- return (-1);
+ eerror("%s: is a file", path);
+ return -1;
}
}
if (mode && (st.st_mode & 0777) != mode) {
- einfo ("%s: correcting mode", applet);
- if (chmod (path, mode)) {
- eerror ("%s: chmod: %s", applet, strerror (errno));
- return (-1);
+ einfo("%s: correcting mode", applet);
+ if (chmod(path, mode)) {
+ eerror("%s: chmod: %s", applet, strerror(errno));
+ return -1;
}
}
if (st.st_uid != uid || st.st_gid != gid) {
if (st.st_dev || st.st_ino)
- einfo ("%s: correcting owner", path);
- if (chown (path, uid, gid)) {
- eerror ("%s: chown: %s", applet, strerror (errno));
- return (-1);
+ einfo("%s: correcting owner", path);
+ if (chown(path, uid, gid)) {
+ eerror("%s: chown: %s", applet, strerror(errno));
+ return -1;
}
}
- return (0);
+ return 0;
}
/* Based on busybox */
static int parse_mode (mode_t *mode, char *text)
{
+ char *p;
+ unsigned long l;
+
/* Check for a numeric mode */
if ((*text - '0') < 8) {
- char *p;
- unsigned long l = strtoul (text, &p, 8);
+ l = strtoul(text, &p, 8);
if (*p || l > 07777U) {
errno = EINVAL;
- return (-1);
+ return -1;
}
*mode = (mode_t) l;
- return (0);
+ return 0;
}
/* We currently don't check g+w type stuff */
errno = EINVAL;
- return (-1);
+ return -1;
}
-static int parse_owner (struct passwd **user, struct group **group,
+static int parse_owner(struct passwd **user, struct group **group,
const char *owner)
{
char *u = xstrdup (owner);
@@ -137,25 +138,25 @@ static int parse_owner (struct passwd **user, struct group **group,
*g++ = '\0';
if (user && *u) {
- if (sscanf (u, "%d", &id) == 1)
- *user = getpwuid ((uid_t) id);
+ if (sscanf(u, "%d", &id) == 1)
+ *user = getpwuid((uid_t) id);
else
- *user = getpwnam (u);
+ *user = getpwnam(u);
if (! *user)
retval = -1;
}
if (group && g && *g) {
- if (sscanf (g, "%d", &id) == 1)
- *group = getgrgid ((gid_t) id);
+ if (sscanf(g, "%d", &id) == 1)
+ *group = getgrgid((gid_t) id);
else
- *group = getgrnam (g);
+ *group = getgrnam(g);
if (! *group)
retval = -1;
}
- free (u);
- return (retval);
+ free(u);
+ return retval;
}
#include "_usage.h"
@@ -177,7 +178,7 @@ static const char * const longopts_help[] = {
};
#include "_usage.c"
-int checkpath (int argc, char **argv)
+int checkpath(int argc, char **argv)
{
int opt;
uid_t uid = geteuid();
@@ -188,33 +189,31 @@ int checkpath (int argc, char **argv)
bool file = 0;
int retval = EXIT_SUCCESS;
- while ((opt = getopt_long (argc, argv, getoptstring,
- longopts, (int *) 0)) != -1)
+ while ((opt = getopt_long(argc, argv, getoptstring,
+ longopts, (int *) 0)) != -1)
{
switch (opt) {
- case 'd':
- file = 0;
- break;
- case 'f':
- file = 1;
- break;
- case 'm':
- if (parse_mode (&mode, optarg) != 0)
- eerrorx ("%s: invalid mode `%s'",
- applet, optarg);
- break;
- case 'o':
- if (parse_owner (&pw, &gr, optarg) != 0)
- eerrorx ("%s: owner `%s' not found",
- applet, optarg);
- break;
-
- case_RC_COMMON_GETOPT
+ case 'd':
+ file = 0;
+ break;
+ case 'f':
+ file = 1;
+ break;
+ case 'm':
+ if (parse_mode(&mode, optarg) != 0)
+ eerrorx("%s: invalid mode `%s'", applet, optarg);
+ break;
+ case 'o':
+ if (parse_owner(&pw, &gr, optarg) != 0)
+ eerrorx("%s: owner `%s' not found", applet, optarg);
+ break;
+
+ case_RC_COMMON_GETOPT
}
}
if (optind >= argc)
- usage (EXIT_FAILURE);
+ usage(EXIT_FAILURE);
if (pw) {
uid = pw->pw_uid;
@@ -224,11 +223,11 @@ int checkpath (int argc, char **argv)
gid = gr->gr_gid;
while (optind < argc) {
- if (do_check (argv[optind], uid, gid, mode, file))
+ if (do_check(argv[optind], uid, gid, mode, file))
retval = EXIT_FAILURE;
optind++;
}
- exit (retval);
+ exit(retval);
/* NOTREACHED */
}
diff --git a/src/rc/fstabinfo.c b/src/rc/fstabinfo.c
index 309c684..54812bf 100644
--- a/src/rc/fstabinfo.c
+++ b/src/rc/fstabinfo.c
@@ -30,6 +30,7 @@
*/
#include <sys/wait.h>
+
#include <errno.h>
#include <getopt.h>
#include <stdio.h>
@@ -72,27 +73,26 @@
#include "einfo.h"
#include "rc.h"
#include "rc-misc.h"
-#include "strlist.h"
#ifdef HAVE_GETMNTENT
-static struct mntent *getmntfile (const char *file)
+static struct mntent *getmntfile(const char *file)
{
- struct mntent *ent = NULL;
+ struct mntent *ent;
FILE *fp;
START_ENT;
- while ((ent = getmntent (fp)))
- if (strcmp (file, ent->mnt_dir) == 0)
+ while ((ent = getmntent(fp)))
+ if (strcmp(file, ent->mnt_dir) == 0)
break;
END_ENT;
- return (ent);
+ return ent;
}
#endif
extern const char *applet;
-static int do_mount (struct ENT *ent)
+static int do_mount(struct ENT *ent)
{
char *argv[8];
pid_t pid;
@@ -100,29 +100,27 @@ static int do_mount (struct ENT *ent)
argv[0] = (char *) "mount";
argv[1] = (char *) "-o";
- argv[2] = ENT_OPTS (*ent);
+ argv[2] = ENT_OPTS(*ent);
argv[3] = (char *) "-t";
- argv[4] = ENT_TYPE (*ent);
- argv[5] = ENT_BLOCKDEVICE (*ent);
- argv[6] = ENT_FILE (*ent);
+ argv[4] = ENT_TYPE(*ent);
+ argv[5] = ENT_BLOCKDEVICE(*ent);
+ argv[6] = ENT_FILE(*ent);
argv[7] = NULL;
switch (pid = vfork()) {
case -1:
- eerrorx ("%s: vfork: %s", applet,
- strerror (errno));
+ eerrorx("%s: vfork: %s", applet, strerror(errno));
/* NOTREACHED */
case 0:
- execvp (argv[0], argv);
- eerror ("%s: execv: %s", applet,
- strerror (errno));
+ execvp(argv[0], argv);
+ eerror("%s: execv: %s", applet, strerror(errno));
_exit(EXIT_FAILURE);
/* NOTREACHED */
default:
- waitpid (pid, &status, 0);
- if (WIFEXITED (status))
- return (WEXITSTATUS(status));
+ waitpid(pid, &status, 0);
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
else
- return (-1);
+ return -1;
/* NOTREACHED */
}
}
@@ -155,7 +153,7 @@ static const char * const longopts_help[] = {
#define OUTPUT_BLOCKDEV (1 << 5)
#define OUTPUT_MOUNT (1 << 6)
-int fstabinfo (int argc, char **argv)
+int fstabinfo(int argc, char **argv)
{
struct ENT *ent;
int result = EXIT_SUCCESS;
@@ -163,8 +161,8 @@ int fstabinfo (int argc, char **argv)
int i;
int opt;
int output = OUTPUT_FILE;
- char **files = NULL;
- char *file;
+ RC_STRINGLIST *files = rc_stringlist_new();
+ RC_STRING *file;
bool filtered = false;
#ifdef HAVE_GETMNTENT
@@ -172,125 +170,126 @@ int fstabinfo (int argc, char **argv)
#endif
/* Ensure that we are only quiet when explicitly told to be */
- unsetenv ("EINFO_QUIET");
+ unsetenv("EINFO_QUIET");
- while ((opt = getopt_long (argc, argv, getoptstring,
- longopts, (int *) 0)) != -1)
+ while ((opt = getopt_long(argc, argv, getoptstring,
+ longopts, (int *) 0)) != -1)
{
switch (opt) {
- case 'M':
- output = OUTPUT_MOUNT;
- break;
- case 'b':
- output = OUTPUT_BLOCKDEV;
- break;
- case 'o':
- output = OUTPUT_OPTIONS;
- break;
- case 'm':
- output = OUTPUT_MOUNTARGS;
- break;
+ case 'M':
+ output = OUTPUT_MOUNT;
+ break;
+ case 'b':
+ output = OUTPUT_BLOCKDEV;
+ break;
+ case 'o':
+ output = OUTPUT_OPTIONS;
+ break;
+ case 'm':
+ output = OUTPUT_MOUNTARGS;
+ break;
- case 'p':
- switch (optarg[0]) {
- case '=':
- case '<':
- case '>':
- if (sscanf (optarg + 1, "%d", &i) != 1)
- eerrorx ("%s: invalid passno %s", argv[0], optarg + 1);
-
- filtered = true;
- START_ENT;
- while ((ent = GET_ENT)) {
- if (((optarg[0] == '=' && i == ENT_PASS (ent)) ||
- (optarg[0] == '<' && i > ENT_PASS (ent)) ||
- (optarg[0] == '>' && i < ENT_PASS (ent))) &&
- strcmp (ENT_FILE (ent), "none") != 0)
- rc_strlist_add (&files, ENT_FILE (ent));
- }
- END_ENT;
- break;
-
- default:
- rc_strlist_add (&files, optarg);
- output = OUTPUT_PASSNO;
- break;
- }
- break;
+ case 'p':
+ switch (optarg[0]) {
+ case '=':
+ case '<':
+ case '>':
+ if (sscanf(optarg + 1, "%d", &i) != 1)
+ eerrorx("%s: invalid passno %s",
+ argv[0], optarg + 1);
- case 't':
filtered = true;
- while ((token = strsep (&optarg, ","))) {
- START_ENT;
- while ((ent = GET_ENT))
- if (strcmp (token, ENT_TYPE (ent)) == 0)
- rc_strlist_add (&files, ENT_FILE (ent));
- END_ENT;
+ START_ENT;
+ while ((ent = GET_ENT)) {
+ if (((optarg[0] == '=' && i == ENT_PASS(ent)) ||
+ (optarg[0] == '<' && i > ENT_PASS(ent)) ||
+ (optarg[0] == '>' && i < ENT_PASS(ent))) &&
+ strcmp(ENT_FILE(ent), "none") != 0)
+ rc_stringlist_add(files, ENT_FILE(ent));
}
+ END_ENT;
break;
- case_RC_COMMON_GETOPT
+ default:
+ rc_stringlist_add(files, optarg);
+ output = OUTPUT_PASSNO;
+ break;
+ }
+ break;
+
+ case 't':
+ filtered = true;
+ while ((token = strsep(&optarg, ","))) {
+ START_ENT;
+ while ((ent = GET_ENT))
+ if (strcmp(token, ENT_TYPE(ent)) == 0)
+ rc_stringlist_add(files, ENT_FILE(ent));
+ END_ENT;
+ }
+ break;
+
+ case_RC_COMMON_GETOPT
}
}
- while (optind < argc)
- rc_strlist_add (&files, argv[optind++]);
-
- if (! files && ! filtered) {
+ if (optind < argc) {
+ while (optind < argc)
+ rc_stringlist_add(files, argv[optind++]);
+ } else if (! filtered) {
START_ENT;
while ((ent = GET_ENT))
- rc_strlist_add (&files, ENT_FILE (ent));
+ rc_stringlist_add(files, ENT_FILE(ent));
END_ENT;
- if (! files)
- eerrorx ("%s: emtpy fstab", argv[0]);
+ if (! TAILQ_FIRST(files))
+ eerrorx("%s: emtpy fstab", argv[0]);
}
/* Ensure we always display something */
START_ENT;
- STRLIST_FOREACH (files, file, i) {
- if (! (ent = GET_ENT_FILE (file))) {
+ TAILQ_FOREACH(file, files, entries) {
+ if (! (ent = GET_ENT_FILE(file->value))) {
result = EXIT_FAILURE;
continue;
}
/* No point in outputting if quiet */
- if (rc_yesno (getenv ("EINFO_QUIET")))
+ if (rc_yesno(getenv("EINFO_QUIET")))
continue;
switch (output) {
- case OUTPUT_BLOCKDEV:
- printf ("%s\n", ENT_BLOCKDEVICE (ent));
- break;
+ case OUTPUT_BLOCKDEV:
+ printf("%s\n", ENT_BLOCKDEVICE(ent));
+ break;
- case OUTPUT_MOUNT:
- result += do_mount (ent);
- break;
+ case OUTPUT_MOUNT:
+ result += do_mount(ent);
+ break;
- case OUTPUT_MOUNTARGS:
- printf ("-o %s -t %s %s %s\n",
- ENT_OPTS (ent),
- ENT_TYPE (ent),
- ENT_BLOCKDEVICE (ent),
- file);
- break;
+ case OUTPUT_MOUNTARGS:
+ printf("-o %s -t %s %s %s\n",
+ ENT_OPTS(ent),
+ ENT_TYPE(ent),
+ ENT_BLOCKDEVICE(ent),
+ file->value);
+ break;
- case OUTPUT_OPTIONS:
- printf ("%s\n", ENT_OPTS (ent));
- break;
+ case OUTPUT_OPTIONS:
+ printf("%s\n", ENT_OPTS(ent));
+ break;
- case OUTPUT_FILE:
- printf ("%s\n", file);
- break;
+ case OUTPUT_FILE:
+ printf("%s\n", file->value);
+ break;
- case OUTPUT_PASSNO:
- printf ("%d\n", ENT_PASS (ent));
- break;
+ case OUTPUT_PASSNO:
+ printf("%d\n", ENT_PASS(ent));
+ break;
}
}
END_ENT;
- rc_strlist_free (files);
- exit (result);
+ rc_stringlist_free(files);
+ exit(result);
/* NOTREACHED */
}
diff --git a/src/rc/mountinfo.c b/src/rc/mountinfo.c
index a05c392..3adff5d 100644
--- a/src/rc/mountinfo.c
+++ b/src/rc/mountinfo.c
@@ -47,16 +47,15 @@
#include <errno.h>
#include <getopt.h>
#include <limits.h>
+#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <regex.h>
#include "builtins.h"
#include "einfo.h"
#include "rc.h"
#include "rc-misc.h"
-#include "strlist.h"
extern const char *applet;
@@ -80,93 +79,93 @@ struct args {
regex_t *skip_fstype_regex;
regex_t *options_regex;
regex_t *skip_options_regex;
- char **mounts;
+ RC_STRINGLIST *mounts;
mount_type mount_type;
net_opts netdev;
};
-static int process_mount (char ***list, struct args *args,
- char *from, char *to, char *fstype, char *options,
- int netdev)
+static int process_mount(RC_STRINGLIST *list, struct args *args,
+ char *from, char *to, char *fstype, char *options,
+ int netdev)
{
char *p;
+ RC_STRING *s;
errno = ENOENT;
#ifdef __linux__
/* Skip the really silly rootfs */
- if (strcmp (fstype, "rootfs") == 0)
- return (-1);
+ if (strcmp(fstype, "rootfs") == 0)
+ return -1;
#endif
- if (args->netdev == net_yes && (netdev != -1 || args->mounts)) {
+ if (args->netdev == net_yes &&
+ (netdev != -1 || TAILQ_FIRST(args->mounts)))
+ {
if (netdev != 0)
- return (1);
- } else if (args->netdev == net_no && (netdev != -1 || args->mounts)) {
+ return 1;
+ } else if (args->netdev == net_no &&
+ (netdev != -1 || TAILQ_FIRST(args->mounts)))
+ {
if (netdev != 1)
- return (1);
+ return 1;
} else {
if (args->node_regex &&
- regexec (args->node_regex, from, 0, NULL, 0) != 0)
- return (1);
+ regexec(args->node_regex, from, 0, NULL, 0) != 0)
+ return 1;
if (args->skip_node_regex &&
- regexec (args->skip_node_regex, from, 0, NULL, 0) == 0)
- return (1);
+ regexec(args->skip_node_regex, from, 0, NULL, 0) == 0)
+ return 1;
if (args->fstype_regex &&
- regexec (args->fstype_regex, fstype, 0, NULL, 0) != 0)
- return (-1);
+ regexec(args->fstype_regex, fstype, 0, NULL, 0) != 0)
+ return -1;
if (args->skip_fstype_regex &&
- regexec (args->skip_fstype_regex, fstype, 0, NULL, 0) == 0)
- return (-1);
+ regexec(args->skip_fstype_regex, fstype, 0, NULL, 0) == 0)
+ return -1;
if (args->options_regex &&
- regexec (args->options_regex, options, 0, NULL, 0) != 0)
- return (-1);
+ regexec(args->options_regex, options, 0, NULL, 0) != 0)
+ return -1;
if (args->skip_options_regex &&
- regexec (args->skip_options_regex, options, 0, NULL, 0) == 0)
- return (-1);
+ regexec(args->skip_options_regex, options, 0, NULL, 0) == 0)
+ return -1;
}
- if (args->mounts) {
- bool found = false;
- int j;
- char *mnt;
- STRLIST_FOREACH (args->mounts, mnt, j)
- if (strcmp (mnt, to) == 0) {
- found = true;
+ if (TAILQ_FIRST(args->mounts)) {
+ TAILQ_FOREACH(s, args->mounts, entries)
+ if (strcmp(s->value, to) == 0)
break;
- }
- if (! found)
- return (-1);
+ if (! s)
+ return -1;
}
switch (args->mount_type) {
- case mount_from:
- p = from;
- break;
- case mount_to:
- p = to;
- break;
- case mount_fstype:
- p = fstype;
- break;
- case mount_options:
- p = options;
- break;
- default:
- p = NULL;
- errno = EINVAL;
- break;
+ case mount_from:
+ p = from;
+ break;
+ case mount_to:
+ p = to;
+ break;
+ case mount_fstype:
+ p = fstype;
+ break;
+ case mount_options:
+ p = options;
+ break;
+ default:
+ p = NULL;
+ errno = EINVAL;
+ break;
}
if (p) {
errno = 0;
- rc_strlist_addsortc (list, p);
- return (0);
+ rc_stringlist_add(list, p);
+ return 0;
}
- return (-1);
+ return -1;
}
#ifdef BSD
@@ -212,70 +211,73 @@ static struct opt {
{ 0, NULL }
};
-static char **find_mounts (struct args *args)
+static RC_STRINGLIST *find_mounts(struct args *args)
{
struct statfs *mnts;
int nmnts;
int i;
- char **list = NULL;
+ RC_STRINGLIST *list;
char *options = NULL;
uint64_t flags;
struct opt *o;
+ int netdev;
+ char *tmp;
+ size_t l;
- if ((nmnts = getmntinfo (&mnts, MNT_NOWAIT)) == 0)
- eerrorx ("getmntinfo: %s", strerror (errno));
+ if ((nmnts = getmntinfo(&mnts, MNT_NOWAIT)) == 0)
+ eerrorx("getmntinfo: %s", strerror (errno));
+ list = rc_stringlist_new();
for (i = 0; i < nmnts; i++) {
- int netdev = 0;
+ netdev = 0;
flags = mnts[i].F_FLAGS & MNT_VISFLAGMASK;
for (o = optnames; flags && o->o_opt; o++) {
if (flags & o->o_opt) {
if (o->o_opt == MNT_LOCAL)
netdev = 1;
if (! options)
- options = xstrdup (o->o_name);
+ options = xstrdup(o->o_name);
else {
- char *tmp = NULL;
- size_t l = strlen (options) + strlen (o->o_name) + 2;
- tmp = xmalloc (sizeof (char) * l);
- snprintf (tmp, l, "%s,%s", options, o->o_name);
- free (options);
+ l = strlen(options) + strlen(o->o_name) + 2;
+ tmp = xmalloc(sizeof (char) * l);
+ snprintf(tmp, l, "%s,%s", options, o->o_name);
+ free(options);
options = tmp;
}
}
flags &= ~o->o_opt;
}
- process_mount (&list, args,
- mnts[i].f_mntfromname,
- mnts[i].f_mntonname,
- mnts[i].f_fstypename,
- options,
- netdev);
+ process_mount(list, args,
+ mnts[i].f_mntfromname,
+ mnts[i].f_mntonname,
+ mnts[i].f_fstypename,
+ options,
+ netdev);
- free (options);
+ free(options);
options = NULL;
}
- return (list);
+ return list;
}
#elif defined (__linux__)
-static struct mntent *getmntfile (const char *file)
+static struct mntent *getmntfile(const char *file)
{
struct mntent *ent = NULL;
FILE *fp;
- fp = setmntent ("/etc/fstab", "r");
- while ((ent = getmntent (fp)))
- if (strcmp (file, ent->mnt_dir) == 0)
+ fp = setmntent("/etc/fstab", "r");
+ while ((ent = getmntent(fp)))
+ if (strcmp(file, ent->mnt_dir) == 0)
break;
- endmntent (fp);
+ endmntent(fp);
- return (ent);
+ return ent;
}
-static char **find_mounts (struct args *args)
+static RC_STRINGLIST *find_mounts(struct args *args)
{
FILE *fp;
char *buffer;
@@ -284,52 +286,54 @@ static char **find_mounts (struct args *args)
char *to;
char *fst;
char *opts;
- char **list = NULL;
struct mntent *ent;
int netdev;
+ RC_STRINGLIST *list;
- if ((fp = fopen ("/proc/mounts", "r")) == NULL)
- eerrorx ("getmntinfo: %s", strerror (errno));
+ if ((fp = fopen("/proc/mounts", "r")) == NULL)
+ eerrorx("getmntinfo: %s", strerror(errno));
- buffer = xmalloc (sizeof (char) * PATH_MAX * 3);
- while (fgets (buffer, PATH_MAX * 3, fp)) {
+ list = rc_stringlist_new();
+
+ buffer = xmalloc(sizeof(char) * PATH_MAX * 3);
+ while (fgets(buffer, PATH_MAX * 3, fp)) {
netdev = -1;
p = buffer;
- from = strsep (&p, " ");
- to = strsep (&p, " ");
- fst = strsep (&p, " ");
- opts = strsep (&p, " ");
+ from = strsep(&p, " ");
+ to = strsep(&p, " ");
+ fst = strsep(&p, " ");
+ opts = strsep(&p, " ");
- if ((ent = getmntfile (to))) {
- if (strstr (ent->mnt_opts, "_netdev"))
+ if ((ent = getmntfile(to))) {
+ if (strstr(ent->mnt_opts, "_netdev"))
netdev = 0;
}
- process_mount (&list, args, from, to, fst, opts, netdev);
+ process_mount(list, args, from, to, fst, opts, netdev);
}
- free (buffer);
- fclose (fp);
+ free(buffer);
+ fclose(fp);
- return (list);
+ return list;
}
#else
# error "Operating system not supported!"
#endif
-static regex_t *get_regex (const char *string)
+static regex_t *get_regex(const char *string)
{
- regex_t *reg = xmalloc (sizeof (*reg));
+ regex_t *reg = xmalloc(sizeof (*reg));
int result;
char buffer[256];
- if ((result = regcomp (reg, string, REG_EXTENDED | REG_NOSUB)) != 0)
+ if ((result = regcomp(reg, string, REG_EXTENDED | REG_NOSUB)) != 0)
{
- regerror (result, reg, buffer, sizeof (buffer));
- eerrorx ("%s: invalid regex `%s'", applet, buffer);
+ regerror(result, reg, buffer, sizeof(buffer));
+ eerrorx("%s: invalid regex `%s'", applet, buffer);
}
- return (reg);
+ return reg;
}
#include "_usage.h"
@@ -347,7 +351,7 @@ static const struct option longopts[] = {
{ "options", 0, NULL, 'i'},
{ "fstype", 0, NULL, 's'},
{ "node", 0, NULL, 't'},
- { "netdev", 0, NULL, 'e'},
+ { "netdev", 0, NULL, 'e'},
{ "nonetdev", 0, NULL, 'E'},
longopts_COMMON
};
@@ -369,112 +373,113 @@ static const char * const longopts_help[] = {
};
#include "_usage.c"
-int mountinfo (int argc, char **argv)
+int mountinfo(int argc, char **argv)
{
- int i;
struct args args;
regex_t *point_regex = NULL;
regex_t *skip_point_regex = NULL;
- char **nodes = NULL;
- char *n;
+ RC_STRINGLIST *nodes;
+ RC_STRING *s;
int opt;
int result;
bool quiet;
/* Ensure that we are only quiet when explicitly told to be */
- unsetenv ("EINFO_QUIET");
+ unsetenv("EINFO_QUIET");
#define DO_REG(_var) \
- if (_var) free (_var); \
- _var = get_regex (optarg);
+ if (_var) free(_var); \
+ _var = get_regex(optarg);
#define REG_FREE(_var) \
- if (_var) { regfree (_var); free (_var); }
+ if (_var) { regfree(_var); free(_var); }
- memset (&args, 0, sizeof (args));
+ memset (&args, 0, sizeof(args));
args.mount_type = mount_to;
args.netdev = net_ignore;
+ args.mounts = rc_stringlist_new();
- while ((opt = getopt_long (argc, argv, getoptstring,
- longopts, (int *) 0)) != -1)
+ while ((opt = getopt_long(argc, argv, getoptstring,
+ longopts, (int *) 0)) != -1)
{
switch (opt) {
- case 'e':
- args.netdev = net_yes;
- break;
- case 'E':
- args.netdev = net_no;
- break;
- case 'f':
- DO_REG (args.fstype_regex);
- break;
- case 'F':
- DO_REG (args.skip_fstype_regex);
- break;
- case 'n':
- DO_REG (args.node_regex);
- break;
- case 'N':
- DO_REG (args.skip_node_regex);
- break;
- case 'o':
- DO_REG (args.options_regex);
- break;
- case 'O':
- DO_REG (args.skip_options_regex);
- break;
- case 'p':
- DO_REG (point_regex);
- break;
- case 'P':
- DO_REG (skip_point_regex);
- break;
- case 'i':
- args.mount_type = mount_options;
- break;
- case 's':
- args.mount_type = mount_fstype;
- break;
- case 't':
- args.mount_type = mount_from;
- break;
+ case 'e':
+ args.netdev = net_yes;
+ break;
+ case 'E':
+ args.netdev = net_no;
+ break;
+ case 'f':
+ DO_REG(args.fstype_regex);
+ break;
+ case 'F':
+ DO_REG(args.skip_fstype_regex);
+ break;
+ case 'n':
+ DO_REG(args.node_regex);
+ break;
+ case 'N':
+ DO_REG(args.skip_node_regex);
+ break;
+ case 'o':
+ DO_REG(args.options_regex);
+ break;
+ case 'O':
+ DO_REG(args.skip_options_regex);
+ break;
+ case 'p':
+ DO_REG(point_regex);
+ break;
+ case 'P':
+ DO_REG(skip_point_regex);
+ break;
+ case 'i':
+ args.mount_type = mount_options;
+ break;
+ case 's':
+ args.mount_type = mount_fstype;
+ break;
+ case 't':
+ args.mount_type = mount_from;
+ break;
- case_RC_COMMON_GETOPT
+ case_RC_COMMON_GETOPT
}
}
while (optind < argc) {
if (argv[optind][0] != '/')
- eerrorx ("%s: `%s' is not a mount point", argv[0], argv[optind]);
- rc_strlist_add (&args.mounts, argv[optind++]);
+ eerrorx("%s: `%s' is not a mount point", argv[0], argv[optind]);
+ rc_stringlist_add(args.mounts, argv[optind++]);
}
+ nodes = find_mounts(&args);
+ rc_stringlist_free(args.mounts);
+ rc_stringlist_sort(&nodes);
- nodes = find_mounts (&args);
-
- REG_FREE (args.fstype_regex);
- REG_FREE (args.skip_fstype_regex);
- REG_FREE (args.node_regex);
- REG_FREE (args.skip_node_regex);
- REG_FREE (args.options_regex);
- REG_FREE (args.skip_options_regex);
-
- rc_strlist_reverse (nodes);
+ REG_FREE(args.fstype_regex);
+ REG_FREE(args.skip_fstype_regex);
+ REG_FREE(args.node_regex);
+ REG_FREE(args.skip_node_regex);
+ REG_FREE(args.options_regex);
+ REG_FREE(args.skip_options_regex);
result = EXIT_FAILURE;
- quiet = rc_yesno (getenv ("EINFO_QUIET"));
- STRLIST_FOREACH (nodes, n, i) {
- if (point_regex && regexec (point_regex, n, 0, NULL, 0) != 0)
+ quiet = rc_yesno(getenv("EINFO_QUIET"));
+ TAILQ_FOREACH_REVERSE(s, nodes, rc_stringlist, entries) {
+ if (point_regex &&
+ regexec(point_regex, s->value, 0, NULL, 0) != 0)
continue;
- if (skip_point_regex && regexec (skip_point_regex, n, 0, NULL, 0) == 0)
+ if (skip_point_regex &&
+ regexec(skip_point_regex, s->value, 0, NULL, 0) == 0)
continue;
if (! quiet)
- printf ("%s\n", n);
+ printf("%s\n", s->value);
result = EXIT_SUCCESS;
}
- rc_strlist_free (nodes);
+ rc_stringlist_free(nodes);
- REG_FREE (point_regex);
- REG_FREE (skip_point_regex);
+ REG_FREE(point_regex);
+ REG_FREE(skip_point_regex);
- exit (result);
+ exit(result);
/* NOTREACHED */
}
diff --git a/src/rc/rc-applets.c b/src/rc/rc-applets.c
index 5f242f7..96b392d 100644
--- a/src/rc/rc-applets.c
+++ b/src/rc/rc-applets.c
@@ -35,6 +35,7 @@
#define SYSLOG_NAMES
#include <sys/types.h>
+
#include <errno.h>
#include <ctype.h>
#include <inttypes.h>
@@ -49,26 +50,25 @@
#include "builtins.h"
#include "einfo.h"
#include "rc-misc.h"
-#include "strlist.h"
/* Applet is first parsed in rc.c - no point in doing it again */
extern const char *applet;
-static int syslog_decode (char *name, CODE *codetab)
+static int syslog_decode(char *name, CODE *codetab)
{
CODE *c;
- if (isdigit ((int) *name))
- return (atoi (name));
+ if (isdigit((int) *name))
+ return atoi(name);
for (c = codetab; c->c_name; c++)
- if (! strcasecmp (name, c->c_name))
- return (c->c_val);
+ if (! strcasecmp(name, c->c_name))
+ return c->c_val;
- return (-1);
+ return -1;
}
-static int do_e (int argc, char **argv)
+static int do_e(int argc, char **argv)
{
int retval = EXIT_SUCCESS;
int i;
@@ -82,42 +82,42 @@ static int do_e (int argc, char **argv)
argc--;
argv++;
- if (strcmp (applet, "eval_ecolors") == 0) {
- printf ("GOOD='%s'\nWARN='%s'\nBAD='%s'\nHILITE='%s'\nBRACKET='%s'\nNORMAL='%s'\n",
- ecolor (ECOLOR_GOOD),
- ecolor (ECOLOR_WARN),
- ecolor (ECOLOR_BAD),
- ecolor (ECOLOR_HILITE),
- ecolor (ECOLOR_BRACKET),
- ecolor (ECOLOR_NORMAL));
- exit (EXIT_SUCCESS);
+ if (strcmp(applet, "eval_ecolors") == 0) {
+ printf("GOOD='%s'\nWARN='%s'\nBAD='%s'\nHILITE='%s'\nBRACKET='%s'\nNORMAL='%s'\n",
+ ecolor(ECOLOR_GOOD),
+ ecolor(ECOLOR_WARN),
+ ecolor(ECOLOR_BAD),
+ ecolor(ECOLOR_HILITE),
+ ecolor(ECOLOR_BRACKET),
+ ecolor(ECOLOR_NORMAL));
+ exit(EXIT_SUCCESS);
}
if (argc > 0) {
- if (strcmp (applet, "eend") == 0 ||
- strcmp (applet, "ewend") == 0 ||
- strcmp (applet, "veend") == 0 ||
- strcmp (applet, "vweend") == 0)
+ if (strcmp(applet, "eend") == 0 ||
+ strcmp(applet, "ewend") == 0 ||
+ strcmp(applet, "veend") == 0 ||
+ strcmp(applet, "vweend") == 0)
{
errno = 0;
- retval = (int) strtoimax (argv[0], NULL, 0);
+ retval = (int) strtoimax(argv[0], NULL, 0);
if (errno != 0)
retval = EXIT_FAILURE;
else {
argc--;
argv++;
}
- } else if (strcmp (applet, "esyslog") == 0 ||
- strcmp (applet, "elog") == 0) {
- char *dot = strchr (argv[0], '.');
- if ((level = syslog_decode (dot + 1, prioritynames)) == -1)
- eerrorx ("%s: invalid log level `%s'", applet, argv[0]);
+ } else if (strcmp(applet, "esyslog") == 0 ||
+ strcmp(applet, "elog") == 0) {
+ p = strchr(argv[0], '.');
+ if ((level = syslog_decode(p + 1, prioritynames)) == -1)
+ eerrorx("%s: invalid log level `%s'", applet, argv[0]);
if (argc < 3)
- eerrorx ("%s: not enough arguments", applet);
+ eerrorx("%s: not enough arguments", applet);
- unsetenv ("EINFO_LOG");
- setenv ("EINFO_LOG", argv[1], 1);
+ unsetenv("EINFO_LOG");
+ setenv("EINFO_LOG", argv[1], 1);
argc -= 2;
argv += 2;
@@ -126,16 +126,17 @@ static int do_e (int argc, char **argv)
if (argc > 0) {
for (i = 0; i < argc; i++)
- l += strlen (argv[i]) + 1;
+ l += strlen(argv[i]) + 1;
- message = xmalloc (l);
+ message = xmalloc(l);
p = message;
for (i = 0; i < argc; i++) {
if (i > 0)
*p++ = ' ';
- memcpy (p, argv[i], strlen (argv[i]));
- p += strlen (argv[i]);
+ l = strlen(argv[i]);
+ memcpy(p, argv[i], l);
+ p += l;
}
*p = 0;
}
@@ -143,300 +144,302 @@ static int do_e (int argc, char **argv)
if (! message)
fmt = "";
- if (strcmp (applet, "einfo") == 0)
- einfo (fmt, message);
- else if (strcmp (applet, "einfon") == 0)
- einfon (fmt, message);
- else if (strcmp (applet, "ewarn") == 0)
- ewarn (fmt, message);
- else if (strcmp (applet, "ewarnn") == 0)
- ewarnn (fmt, message);
- else if (strcmp (applet, "eerror") == 0) {
- eerror (fmt, message);
+ if (strcmp(applet, "einfo") == 0)
+ einfo(fmt, message);
+ else if (strcmp(applet, "einfon") == 0)
+ einfon(fmt, message);
+ else if (strcmp(applet, "ewarn") == 0)
+ ewarn(fmt, message);
+ else if (strcmp(applet, "ewarnn") == 0)
+ ewarnn(fmt, message);
+ else if (strcmp(applet, "eerror") == 0) {
+ eerror(fmt, message);
retval = 1;
- } else if (strcmp (applet, "eerrorn") == 0) {
- eerrorn (fmt, message);
+ } else if (strcmp(applet, "eerrorn") == 0) {
+ eerrorn(fmt, message);
retval = 1;
- } else if (strcmp (applet, "ebegin") == 0)
- ebegin (fmt, message);
- else if (strcmp (applet, "eend") == 0)
- eend (retval, fmt, message);
- else if (strcmp (applet, "ewend") == 0)
- ewend (retval, fmt, message);
- else if (strcmp (applet, "esyslog") == 0)
- elog (level, fmt, message);
- else if (strcmp (applet, "veinfo") == 0)
- einfov (fmt, message);
- else if (strcmp (applet, "veinfon") == 0)
- einfovn (fmt, message);
- else if (strcmp (applet, "vewarn") == 0)
- ewarnv (fmt, message);
- else if (strcmp (applet, "vewarnn") == 0)
- ewarnvn (fmt, message);
- else if (strcmp (applet, "vebegin") == 0)
- ebeginv (fmt, message);
- else if (strcmp (applet, "veend") == 0)
- eendv (retval, fmt, message);
- else if (strcmp (applet, "vewend") == 0)
- ewendv (retval, fmt, message);
- else if (strcmp (applet, "eindent") == 0)
- eindent ();
- else if (strcmp (applet, "eoutdent") == 0)
- eoutdent ();
- else if (strcmp (applet, "veindent") == 0)
- eindentv ();
- else if (strcmp (applet, "veoutdent") == 0)
- eoutdentv ();
+ } else if (strcmp(applet, "ebegin") == 0)
+ ebegin(fmt, message);
+ else if (strcmp(applet, "eend") == 0)
+ eend(retval, fmt, message);
+ else if (strcmp(applet, "ewend") == 0)
+ ewend(retval, fmt, message);
+ else if (strcmp(applet, "esyslog") == 0)
+ elog(level, fmt, message);
+ else if (strcmp(applet, "veinfo") == 0)
+ einfov(fmt, message);
+ else if (strcmp(applet, "veinfon") == 0)
+ einfovn(fmt, message);
+ else if (strcmp(applet, "vewarn") == 0)
+ ewarnv(fmt, message);
+ else if (strcmp(applet, "vewarnn") == 0)
+ ewarnvn(fmt, message);
+ else if (strcmp(applet, "vebegin") == 0)
+ ebeginv(fmt, message);
+ else if (strcmp(applet, "veend") == 0)
+ eendv(retval, fmt, message);
+ else if (strcmp(applet, "vewend") == 0)
+ ewendv(retval, fmt, message);
+ else if (strcmp(applet, "eindent") == 0)
+ eindent();
+ else if (strcmp(applet, "eoutdent") == 0)
+ eoutdent();
+ else if (strcmp(applet, "veindent") == 0)
+ eindentv();
+ else if (strcmp(applet, "veoutdent") == 0)
+ eoutdentv();
else {
- eerror ("%s: unknown applet", applet);
+ eerror("%s: unknown applet", applet);
retval = EXIT_FAILURE;
}
- free (message);
- return (retval);
+ free(message);
+ return retval;
}
-static int do_service (int argc, char **argv)
+static int do_service(int argc, char **argv)
{
bool ok = false;
char *service = NULL;
+ int idx = 0;
+ char *d[] = { NULL, NULL };
if (argc > 1)
service = argv[1];
else
- service = getenv ("SVCNAME");
+ service = getenv("SVCNAME");
if (! service || *service == '\0')
- eerrorx ("%s: no service specified", applet);
-
- if (strcmp (applet, "service_started") == 0)
- ok = (rc_service_state (service) & RC_SERVICE_STARTED);
- else if (strcmp (applet, "service_stopped") == 0)
- ok = (rc_service_state (service) & RC_SERVICE_STOPPED);
- else if (strcmp (applet, "service_inactive") == 0)
- ok = (rc_service_state (service) & RC_SERVICE_INACTIVE);
- else if (strcmp (applet, "service_starting") == 0)
- ok = (rc_service_state (service) & RC_SERVICE_STARTING);
- else if (strcmp (applet, "service_stopping") == 0)
- ok = (rc_service_state (service) & RC_SERVICE_STOPPING);
- else if (strcmp (applet, "service_coldplugged") == 0)
- ok = (rc_service_state (service) & RC_SERVICE_COLDPLUGGED);
- else if (strcmp (applet, "service_wasinactive") == 0)
- ok = (rc_service_state (service) & RC_SERVICE_WASINACTIVE);
- else if (strcmp (applet, "service_started_daemon") == 0) {
- int idx = 0;
- char *d[] = { argv[1], NULL };
-
- service = getenv ("SVCNAME");
+ eerrorx("%s: no service specified", applet);
+
+ if (strcmp(applet, "service_started") == 0)
+ ok = (rc_service_state(service) & RC_SERVICE_STARTED);
+ else if (strcmp(applet, "service_stopped") == 0)
+ ok = (rc_service_state(service) & RC_SERVICE_STOPPED);
+ else if (strcmp(applet, "service_inactive") == 0)
+ ok = (rc_service_state(service) & RC_SERVICE_INACTIVE);
+ else if (strcmp(applet, "service_starting") == 0)
+ ok = (rc_service_state(service) & RC_SERVICE_STARTING);
+ else if (strcmp(applet, "service_stopping") == 0)
+ ok = (rc_service_state(service) & RC_SERVICE_STOPPING);
+ else if (strcmp(applet, "service_coldplugged") == 0)
+ ok = (rc_service_state(service) & RC_SERVICE_COLDPLUGGED);
+ else if (strcmp(applet, "service_wasinactive") == 0)
+ ok = (rc_service_state(service) & RC_SERVICE_WASINACTIVE);
+ else if (strcmp(applet, "service_started_daemon") == 0) {
+ d[0] = argv[1];
+
+ service = getenv("SVCNAME");
if (argc > 3) {
service = argv[1];
d[0] = argv[2];
- sscanf (argv[3], "%d", &idx);
+ sscanf(argv[3], "%d", &idx);
} else if (argc == 3) {
- if (sscanf (argv[2], "%d", &idx) != 1) {
+ if (sscanf(argv[2], "%d", &idx) != 1) {
service = argv[1];
- *d = argv[2];
+ d[0] = argv[2];
}
}
- ok = rc_service_started_daemon (service,
- (const char * const *)d, idx);
+ ok = rc_service_started_daemon(service,
+ (const char * const *)d, idx);
} else
- eerrorx ("%s: unknown applet", applet);
+ eerrorx("%s: unknown applet", applet);
- return (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
-static int do_mark_service (int argc, char **argv)
+static int do_mark_service(int argc, char **argv)
{
bool ok = false;
- char *svcname = getenv ("SVCNAME");
+ char *svcname = getenv("SVCNAME");
char *service = NULL;
+ char *runscript_pid;
+ char *mtime;
+ pid_t pid;
+ size_t l;
if (argc > 1)
service = argv[1];
else
- service = getenv ("SVCNAME");
+ service = getenv("SVCNAME");
if (! service || *service == '\0')
- eerrorx ("%s: no service specified", applet);
-
- if (strcmp (applet, "mark_service_started") == 0)
- ok = rc_service_mark (service, RC_SERVICE_STARTED);
- else if (strcmp (applet, "mark_service_stopped") == 0)
- ok = rc_service_mark (service, RC_SERVICE_STOPPED);
- else if (strcmp (applet, "mark_service_inactive") == 0)
- ok = rc_service_mark (service, RC_SERVICE_INACTIVE);
- else if (strcmp (applet, "mark_service_starting") == 0)
- ok = rc_service_mark (service, RC_SERVICE_STARTING);
- else if (strcmp (applet, "mark_service_stopping") == 0)
- ok = rc_service_mark (service, RC_SERVICE_STOPPING);
- else if (strcmp (applet, "mark_service_coldplugged") == 0)
- ok = rc_service_mark (service, RC_SERVICE_COLDPLUGGED);
- else if (strcmp (applet, "mark_service_failed") == 0)
- ok = rc_service_mark (service, RC_SERVICE_FAILED);
+ eerrorx("%s: no service specified", applet);
+
+ if (strcmp(applet, "mark_service_started") == 0)
+ ok = rc_service_mark(service, RC_SERVICE_STARTED);
+ else if (strcmp(applet, "mark_service_stopped") == 0)
+ ok = rc_service_mark(service, RC_SERVICE_STOPPED);
+ else if (strcmp(applet, "mark_service_inactive") == 0)
+ ok = rc_service_mark(service, RC_SERVICE_INACTIVE);
+ else if (strcmp(applet, "mark_service_starting") == 0)
+ ok = rc_service_mark(service, RC_SERVICE_STARTING);
+ else if (strcmp(applet, "mark_service_stopping") == 0)
+ ok = rc_service_mark(service, RC_SERVICE_STOPPING);
+ else if (strcmp(applet, "mark_service_coldplugged") == 0)
+ ok = rc_service_mark(service, RC_SERVICE_COLDPLUGGED);
+ else if (strcmp(applet, "mark_service_failed") == 0)
+ ok = rc_service_mark(service, RC_SERVICE_FAILED);
else
- eerrorx ("%s: unknown applet", applet);
+ eerrorx("%s: unknown applet", applet);
/* If we're marking ourselves then we need to inform our parent runscript
process so they do not mark us based on our exit code */
- if (ok && svcname && strcmp (svcname, service) == 0) {
- char *runscript_pid = getenv ("RC_RUNSCRIPT_PID");
- char *mtime;
- pid_t pid = 0;
- size_t l;
-
- if (runscript_pid && sscanf (runscript_pid, "%d", &pid) == 1)
- if (kill (pid, SIGHUP) != 0)
- eerror ("%s: failed to signal parent %d: %s",
- applet, pid, strerror (errno));
+ if (ok && svcname && strcmp(svcname, service) == 0) {
+ runscript_pid = getenv("RC_RUNSCRIPT_PID");
+ if (runscript_pid && sscanf(runscript_pid, "%d", &pid) == 1)
+ if (kill(pid, SIGHUP) != 0)
+ eerror("%s: failed to signal parent %d: %s",
+ applet, pid, strerror(errno));
/* Remove the exclusive time test. This ensures that it's not
in control as well */
- l = strlen (RC_SVCDIR "exclusive") +
- strlen (svcname) +
- strlen (runscript_pid) +
- 4;
- mtime = xmalloc (l);
- snprintf (mtime, l, RC_SVCDIR "exclusive/%s.%s",
- svcname, runscript_pid);
- if (exists (mtime) && unlink (mtime) != 0)
- eerror ("%s: unlink: %s", applet, strerror (errno));
- free (mtime);
+ l = strlen(RC_SVCDIR "exclusive") + strlen(svcname) +
+ strlen(runscript_pid) + 4;
+ mtime = xmalloc(l);
+ snprintf(mtime, l, RC_SVCDIR "exclusive/%s.%s",
+ svcname, runscript_pid);
+ if (exists(mtime) && unlink(mtime) != 0)
+ eerror("%s: unlink: %s", applet, strerror(errno));
+ free(mtime);
}
- return (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
-static int do_value (int argc, char **argv)
+static int do_value(int argc, char **argv)
{
bool ok = false;
- char *service = getenv ("SVCNAME");
+ char *service = getenv("SVCNAME");
+ char *option;
if (! service)
- eerrorx ("%s: no service specified", applet);
+ eerrorx("%s: no service specified", applet);
if (argc < 2 || ! argv[1] || *argv[1] == '\0')
- eerrorx ("%s: no option specified", applet);
+ eerrorx("%s: no option specified", applet);
- if (strcmp (applet, "service_get_value") == 0 ||
- strcmp (applet, "get_options") == 0)
+ if (strcmp(applet, "service_get_value") == 0 ||
+ strcmp(applet, "get_options") == 0)
{
- char *option = rc_service_value_get (service, argv[1]);
+ option = rc_service_value_get(service, argv[1]);
if (option) {
- printf ("%s", option);
- free (option);
+ printf("%s", option);
+ free(option);
ok = true;
}
- } else if (strcmp (applet, "service_set_value") == 0 ||
- strcmp (applet, "save_options") == 0)
- ok = rc_service_value_set (service, argv[1], argv[2]);
+ } else if (strcmp(applet, "service_set_value") == 0 ||
+ strcmp(applet, "save_options") == 0)
+ ok = rc_service_value_set(service, argv[1], argv[2]);
else
- eerrorx ("%s: unknown applet", applet);
+ eerrorx("%s: unknown applet", applet);
- return (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
-static int do_shell_var (int argc, char **argv)
+static int do_shell_var(int argc, char **argv)
{
int i;
+ char *p;
+ int c;
for (i = 1; i < argc; i++) {
- char *p = argv[i];
+ p = argv[i];
if (i != 1)
- putchar (' ');
+ putchar(' ');
while (*p) {
- char c = *p++;
- if (! isalnum ((int) c))
+ c = *p++;
+ if (! isalnum(c))
c = '_';
- putchar (c);
+ putchar(c);
}
}
- putchar ('\n');
+ putchar('\n');
- return (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
-void run_applets (int argc, char **argv)
+void run_applets(int argc, char **argv)
{
+ int i = 2;
+ bool match = false;
+ char *p;
+ pid_t pid = 0;
+
/* These are designed to be applications in their own right */
- if (strcmp (applet, "fstabinfo") == 0)
- exit (fstabinfo (argc, argv));
- else if (strcmp (applet, "mountinfo") == 0)
- exit (mountinfo (argc, argv));
- else if (strcmp (applet, "rc-depend") == 0)
- exit (rc_depend (argc, argv));
- else if (strcmp (applet, "rc-status") == 0)
- exit (rc_status (argc, argv));
- else if (strcmp (applet, "rc-update") == 0 ||
- strcmp (applet, "update-rc") == 0)
- exit (rc_update (argc, argv));
- else if (strcmp (applet, "runscript") == 0)
- exit (runscript (argc, argv));
- else if (strcmp (applet, "start-stop-daemon") == 0)
- exit (start_stop_daemon (argc, argv));
+ if (strcmp(applet, "fstabinfo") == 0)
+ exit(fstabinfo(argc, argv));
+ else if (strcmp(applet, "mountinfo") == 0)
+ exit(mountinfo(argc, argv));
+ else if (strcmp(applet, "rc-depend") == 0)
+ exit(rc_depend(argc, argv));
+ else if (strcmp(applet, "rc-status") == 0)
+ exit(rc_status(argc, argv));
+ else if (strcmp(applet, "rc-update") == 0 ||
+ strcmp(applet, "update-rc") == 0)
+ exit(rc_update(argc, argv));
+ else if (strcmp(applet, "runscript") == 0)
+ exit(runscript(argc, argv));
+ else if (strcmp(applet, "start-stop-daemon") == 0)
+ exit(start_stop_daemon(argc, argv));
else if (strcmp (applet, "checkpath") == 0)
- exit (checkpath (argc, argv));
+ exit(checkpath(argc, argv));
/* These could also be applications in their own right */
- if (strcmp (applet, "shell_var") == 0)
- exit (do_shell_var (argc, argv));
+ if (strcmp(applet, "shell_var") == 0)
+ exit(do_shell_var(argc, argv));
- if (strcmp (applet, "is_newer_than") == 0 ||
- strcmp (applet, "is_older_than") == 0)
+ if (strcmp(applet, "is_newer_than") == 0 ||
+ strcmp(applet, "is_older_than") == 0)
{
- bool match = false;
- int i = 2;
-
if (argc < 3)
exit (EXIT_FAILURE);
- if (strcmp (applet, "is_newer_than") == 0)
+ if (strcmp(applet, "is_newer_than") == 0)
match = true;
while (i < argc) {
- if (rc_newer_than (argv[1], argv[i++]) != match)
+ if (rc_newer_than(argv[1], argv[i++]) != match)
exit (EXIT_FAILURE);
}
- exit (EXIT_SUCCESS);
+ exit(EXIT_SUCCESS);
};
if (applet[0] == 'e' || (applet[0] == 'v' && applet[1] == 'e'))
- exit (do_e (argc, argv));
+ exit(do_e(argc, argv));
/* These are purely for init scripts and do not make sense as
* anything else */
- if (strcmp (applet, "service_get_value") == 0 ||
- strcmp (applet, "service_set_value") == 0 ||
- strcmp (applet, "get_options") == 0 ||
- strcmp (applet, "save_options") == 0)
- exit (do_value (argc, argv));
+ if (strcmp(applet, "service_get_value") == 0 ||
+ strcmp(applet, "service_set_value") == 0 ||
+ strcmp(applet, "get_options") == 0 ||
+ strcmp(applet, "save_options") == 0)
+ exit(do_value(argc, argv));
- if (strncmp (applet, "service_", strlen ("service_")) == 0)
- exit (do_service (argc, argv));
+ if (strncmp(applet, "service_", strlen("service_")) == 0)
+ exit(do_service(argc, argv));
- if (strncmp (applet, "mark_service_", strlen ("mark_service_")) == 0)
- exit (do_mark_service (argc, argv));
+ if (strncmp(applet, "mark_service_", strlen("mark_service_")) == 0)
+ exit(do_mark_service(argc, argv));
- if (strcmp (applet, "is_runlevel_start") == 0)
- exit (rc_runlevel_starting () ? 0 : 1);
+ if (strcmp(applet, "is_runlevel_start") == 0)
+ exit(rc_runlevel_starting() ? 0 : 1);
else if (strcmp (applet, "is_runlevel_stop") == 0)
- exit (rc_runlevel_stopping () ? 0 : 1);
-
- if (strcmp (applet, "rc-abort") == 0) {
- char *p = getenv ("RC_PID");
- pid_t pid = 0;
-
- if (p && sscanf (p, "%d", &pid) == 1) {
- if (kill (pid, SIGUSR1) != 0)
- eerrorx ("rc-abort: failed to signal parent %d: %s",
- pid, strerror (errno));
- exit (EXIT_SUCCESS);
+ exit(rc_runlevel_stopping() ? 0 : 1);
+
+ if (strcmp(applet, "rc-abort") == 0) {
+ p = getenv("RC_PID");
+ if (p && sscanf(p, "%d", &pid) == 1) {
+ if (kill(pid, SIGUSR1) != 0)
+ eerrorx("rc-abort: failed to signal parent %d: %s",
+ pid, strerror(errno));
+ exit(EXIT_SUCCESS);
}
- exit (EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
- if (strcmp (applet, "rc" ) != 0)
- eerrorx ("%s: unknown applet", applet);
+ if (strcmp(applet, "rc") != 0)
+ eerrorx("%s: unknown applet", applet);
}
diff --git a/src/rc/rc-depend.c b/src/rc/rc-depend.c
index 0eda7f0..33a50f0 100644
--- a/src/rc/rc-depend.c
+++ b/src/rc/rc-depend.c
@@ -45,34 +45,33 @@
#include "einfo.h"
#include "rc.h"
#include "rc-misc.h"
-#include "strlist.h"
extern const char *applet;
-rc_depinfo_t *_rc_deptree_load (int *regen) {
- if (rc_deptree_update_needed ()) {
- int fd;
- int retval;
- int serrno = errno;
- int merrno;
+RC_DEPTREE *_rc_deptree_load(int *regen) {
+ int fd;
+ int retval;
+ int serrno = errno;
+ int merrno;
+ if (rc_deptree_update_needed()) {
/* Test if we have permission to update the deptree */
- fd = open (RC_DEPTREE, O_WRONLY);
+ fd = open(RC_DEPTREE_CACHE, O_WRONLY);
merrno = errno;
errno = serrno;
if (fd == -1 && merrno == EACCES)
- return (rc_deptree_load ());
- close (fd);
+ return rc_deptree_load();
+ close(fd);
if (regen)
*regen = 1;
- ebegin ("Caching service dependencies");
- retval = rc_deptree_update ();
+ ebegin("Caching service dependencies");
+ retval = rc_deptree_update();
eend (retval ? 0 : -1, "Failed to update the dependency tree");
}
- return (rc_deptree_load ());
+ return rc_deptree_load();
}
#include "_usage.h"
@@ -97,117 +96,114 @@ static const char * const longopts_help[] = {
};
#include "_usage.c"
-int rc_depend (int argc, char **argv)
+int rc_depend(int argc, char **argv)
{
- char **types = NULL;
- char **services = NULL;
- char **depends = NULL;
- char **list;
- rc_depinfo_t *deptree = NULL;
- char *service;
+ RC_STRINGLIST *list;
+ RC_STRINGLIST *types;
+ RC_STRINGLIST *services;
+ RC_STRINGLIST *depends;
+ RC_STRING *s;
+ RC_DEPTREE *deptree = NULL;
int options = RC_DEP_TRACE;
bool first = true;
- int i;
bool update = false;
- char *runlevel = xstrdup( getenv ("RC_SOFTLEVEL"));
+ char *runlevel = xstrdup(getenv("RC_SOFTLEVEL"));
int opt;
char *token;
- while ((opt = getopt_long (argc, argv, getoptstring,
- longopts, (int *) 0)) != -1)
+ types = rc_stringlist_new();
+
+ while ((opt = getopt_long(argc, argv, getoptstring,
+ longopts, (int *) 0)) != -1)
{
switch (opt) {
- case 'a':
- options |= RC_DEP_START;
- break;
- case 'o':
- options |= RC_DEP_STOP;
- break;
- case 's':
- options |= RC_DEP_STRICT;
- break;
- case 't':
- while ((token = strsep (&optarg, ",")))
- rc_strlist_addu (&types, token);
- break;
- case 'u':
- update = true;
- break;
- case 'T':
- options &= RC_DEP_TRACE;
- break;
-
- case_RC_COMMON_GETOPT
+ case 'a':
+ options |= RC_DEP_START;
+ break;
+ case 'o':
+ options |= RC_DEP_STOP;
+ break;
+ case 's':
+ options |= RC_DEP_STRICT;
+ break;
+ case 't':
+ while ((token = strsep(&optarg, ",")))
+ rc_stringlist_add(types, token);
+ break;
+ case 'u':
+ update = true;
+ break;
+ case 'T':
+ options &= RC_DEP_TRACE;
+ break;
+
+ case_RC_COMMON_GETOPT
}
}
if (update) {
- bool u = false;
- ebegin ("Caching service dependencies");
- u = rc_deptree_update ();
- eend (u ? 0 : -1, "%s: %s", applet, strerror (errno));
- if (! u)
- eerrorx ("Failed to update the dependency tree");
+ ebegin("Caching service dependencies");
+ update = rc_deptree_update();
+ eend(update ? 0 : -1, "%s: %s", applet, strerror(errno));
+ if (! update)
+ eerrorx("Failed to update the dependency tree");
}
- if (! (deptree = _rc_deptree_load (NULL)))
- eerrorx ("failed to load deptree");
+ if (! (deptree = _rc_deptree_load(NULL)))
+ eerrorx("failed to load deptree");
if (! runlevel)
- runlevel = rc_runlevel_get ();
+ runlevel = rc_runlevel_get();
+ services = rc_stringlist_new();
while (optind < argc) {
- list = NULL;
- rc_strlist_add (&list, argv[optind]);
+ list = rc_stringlist_new();
+ rc_stringlist_add(list, argv[optind]);
errno = 0;
- depends = rc_deptree_depends (deptree, NULL, (const char **) list,
- runlevel, 0);
+ depends = rc_deptree_depends(deptree, NULL, list, runlevel, 0);
if (! depends && errno == ENOENT)
- eerror ("no dependency info for service `%s'", argv[optind]);
+ eerror("no dependency info for service `%s'", argv[optind]);
else
- rc_strlist_add (&services, argv[optind]);
+ rc_stringlist_add(services, argv[optind]);
- rc_strlist_free (depends);
- rc_strlist_free (list);
+ rc_stringlist_free(depends);
+ rc_stringlist_free(list);
optind++;
}
-
- if (! services) {
- rc_strlist_free (types);
- rc_deptree_free (deptree);
- free (runlevel);
+ if (! TAILQ_FIRST(services)) {
+ rc_stringlist_free(services);
+ rc_stringlist_free(types);
+ rc_deptree_free(deptree);
+ free(runlevel);
if (update)
- return (EXIT_SUCCESS);
- eerrorx ("no services specified");
+ return EXIT_SUCCESS;
+ eerrorx("no services specified");
}
/* If we don't have any types, then supply some defaults */
- if (! types) {
- rc_strlist_add (&types, "ineed");
- rc_strlist_add (&types, "iuse");
+ if (! TAILQ_FIRST(types)) {
+ rc_stringlist_add(types, "ineed");
+ rc_stringlist_add(types, "iuse");
}
- depends = rc_deptree_depends (deptree, (const char **) types,
- (const char **) services, runlevel, options);
+ depends = rc_deptree_depends(deptree, types, services, runlevel, options);
- if (depends) {
- STRLIST_FOREACH (depends, service, i) {
+ if (TAILQ_FIRST(depends)) {
+ TAILQ_FOREACH(s, depends, entries) {
if (first)
first = false;
else
printf (" ");
-
- if (service)
- printf ("%s", service);
+ printf ("%s", s->value);
}
printf ("\n");
}
- rc_strlist_free (types);
- rc_strlist_free (services);
- rc_strlist_free (depends);
- rc_deptree_free (deptree);
- free (runlevel);
- return (EXIT_SUCCESS);
+ rc_stringlist_free(types);
+ rc_stringlist_free(services);
+ rc_stringlist_free(depends);
+ rc_deptree_free(deptree);
+ free(runlevel);
+ return EXIT_SUCCESS;
}
diff --git a/src/rc/rc-logger.c b/src/rc/rc-logger.c
index 3e02a1a..b4e4e35 100644
--- a/src/rc/rc-logger.c
+++ b/src/rc/rc-logger.c
@@ -33,6 +33,7 @@
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
+
#include <ctype.h>
#include <fcntl.h>
#include <signal.h>
@@ -76,67 +77,67 @@ pid_t rc_logger_pid = -1;
int rc_logger_tty = -1;
bool rc_in_logger = false;
-static void write_log (int logfd, const char *buffer, size_t bytes)
+static void write_log(int logfd, const char *buffer, size_t bytes)
{
const char *p = buffer;
while ((size_t) (p - buffer) < bytes) {
switch (*p) {
- case '\r':
- goto cont;
- case '\033':
- in_escape = true;
- in_term = false;
- goto cont;
- case '\n':
- in_escape = in_term = false;
- break;
- case '[':
- if (in_escape)
- in_term = true;
- break;
+ case '\r':
+ goto cont;
+ case '\033':
+ in_escape = true;
+ in_term = false;
+ goto cont;
+ case '\n':
+ in_escape = in_term = false;
+ break;
+ case '[':
+ if (in_escape)
+ in_term = true;
+ break;
}
if (! in_escape) {
- write (logfd, p++, 1);
+ write(logfd, p++, 1);
continue;
}
- if (! in_term || isalpha ((int) *p))
+ if (! in_term || isalpha((int) *p))
in_escape = in_term = false;
cont:
p++;
}
}
-
-static void write_time (FILE *f, const char *s)
+static void write_time(FILE *f, const char *s)
{
- time_t now = time (NULL);
- struct tm *tm = localtime (&now);
+ time_t now = time(NULL);
+ struct tm *tm = localtime(&now);
- fprintf (f, "\nrc %s logging %s at %s\n", runlevel, s, asctime (tm));
- fflush (f);
+ fprintf(f, "\nrc %s logging %s at %s\n", runlevel, s, asctime(tm));
+ fflush(f);
}
-void rc_logger_close ()
+void rc_logger_close(void)
{
+ int sig = SIGTERM;
+
if (signal_pipe[1] > -1) {
- int sig = SIGTERM;
- write (signal_pipe[1], &sig, sizeof (sig));
- close (signal_pipe[1]);
+ write(signal_pipe[1], &sig, sizeof(sig));
+ close(signal_pipe[1]);
signal_pipe[1] = -1;
}
if (rc_logger_pid > 0)
- waitpid (rc_logger_pid, 0, 0);
+ waitpid(rc_logger_pid, 0, 0);
if (fd_stdout > -1)
- dup2 (fd_stdout, STDOUT_FILENO);
+ dup2(fd_stdout, STDOUT_FILENO);
if (fd_stderr > -1)
- dup2 (fd_stderr, STDERR_FILENO);
+ dup2(fd_stderr, STDERR_FILENO);
}
-void rc_logger_open (const char *level)
+void rc_logger_open(const char *level)
{
int slave_tty;
struct termios tt;
@@ -149,125 +150,127 @@ void rc_logger_open (const char *level)
int i;
FILE *log = NULL;
- if (! isatty (STDOUT_FILENO))
+ if (! isatty(STDOUT_FILENO))
return;
- if (! rc_conf_yesno ("rc_logger"))
+ if (! rc_conf_yesno("rc_logger"))
return;
- if (pipe (signal_pipe) == -1)
- eerrorx ("pipe: %s", strerror (errno));
+ if (pipe(signal_pipe) == -1)
+ eerrorx("pipe: %s", strerror(errno));
for (i = 0; i < 2; i++)
if ((s = fcntl (signal_pipe[i], F_GETFD, 0) == -1 ||
fcntl (signal_pipe[i], F_SETFD, s | FD_CLOEXEC) == -1))
- eerrorx ("fcntl: %s", strerror (errno));
+ eerrorx("fcntl: %s", strerror (errno));
- tcgetattr (STDOUT_FILENO, &tt);
- ioctl (STDOUT_FILENO, TIOCGWINSZ, &ws);
+ tcgetattr(STDOUT_FILENO, &tt);
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
/* /dev/pts may not be available yet */
- if (openpty (&rc_logger_tty, &slave_tty, NULL, &tt, &ws))
+ if (openpty(&rc_logger_tty, &slave_tty, NULL, &tt, &ws))
return;
- if ((s = fcntl (rc_logger_tty, F_GETFD, 0)) == 0)
- fcntl (rc_logger_tty, F_SETFD, s | FD_CLOEXEC);
+ if ((s = fcntl(rc_logger_tty, F_GETFD, 0)) == 0)
+ fcntl(rc_logger_tty, F_SETFD, s | FD_CLOEXEC);
- if ((s = fcntl (slave_tty, F_GETFD, 0)) == 0)
- fcntl (slave_tty, F_SETFD, s | FD_CLOEXEC);
+ if ((s = fcntl(slave_tty, F_GETFD, 0)) == 0)
+ fcntl(slave_tty, F_SETFD, s | FD_CLOEXEC);
- rc_logger_pid = fork ();
+ rc_logger_pid = fork();
switch (rc_logger_pid) {
- case -1:
- eerror ("forkpty: %s", strerror (errno));
- break;
- case 0:
- rc_in_logger = true;
- close (signal_pipe[1]);
- signal_pipe[1] = -1;
-
- runlevel = level;
- if ((log = fopen (LOGFILE, "a")))
- write_time (log, "started");
- else {
- free (logbuf);
- logbuf_size = BUFSIZ * 10;
- logbuf = xmalloc (sizeof (char) * logbuf_size);
- logbuf_len = 0;
- }
+ case -1:
+ eerror("fork: %s", strerror(errno));
+ break;
+ case 0:
+ rc_in_logger = true;
+ close(signal_pipe[1]);
+ signal_pipe[1] = -1;
- buffer = xmalloc (sizeof (char) * BUFSIZ);
- selfd = rc_logger_tty > signal_pipe[0] ? rc_logger_tty : signal_pipe[0];
- for (;;) {
- FD_ZERO (&rset);
- FD_SET (rc_logger_tty, &rset);
- FD_SET (signal_pipe[0], &rset);
+ runlevel = level;
+ if ((log = fopen(LOGFILE, "a")))
+ write_time(log, "started");
+ else {
+ free(logbuf);
+ logbuf_size = BUFSIZ * 10;
+ logbuf = xmalloc(sizeof (char) * logbuf_size);
+ logbuf_len = 0;
+ }
- if ((s = select (selfd + 1, &rset, NULL, NULL, NULL)) == -1) {
- eerror ("select: %s", strerror (errno));
- break;
- }
+ buffer = xmalloc(sizeof (char) * BUFSIZ);
+ selfd = rc_logger_tty > signal_pipe[0] ? rc_logger_tty : signal_pipe[0];
+ for (;;) {
+ FD_ZERO(&rset);
+ FD_SET(rc_logger_tty, &rset);
+ FD_SET(signal_pipe[0], &rset);
- if (s > 0) {
- if (FD_ISSET (rc_logger_tty, &rset)) {
- memset (buffer, 0, BUFSIZ);
- bytes = read (rc_logger_tty, buffer, BUFSIZ);
- write (STDOUT_FILENO, buffer, bytes);
-
- if (log)
- write_log (fileno (log), buffer, bytes);
- else {
- if (logbuf_size - logbuf_len < bytes) {
- logbuf_size += BUFSIZ * 10;
- logbuf = xrealloc (logbuf, sizeof (char ) *
- logbuf_size);
- }
-
- memcpy (logbuf + logbuf_len, buffer, bytes);
- logbuf_len += bytes;
+ if ((s = select(selfd + 1, &rset, NULL, NULL, NULL)) == -1) {
+ eerror("select: %s", strerror(errno));
+ break;
+ }
+
+ if (s > 0) {
+ if (FD_ISSET(rc_logger_tty, &rset)) {
+ memset(buffer, 0, BUFSIZ);
+ bytes = read(rc_logger_tty, buffer, BUFSIZ);
+ write(STDOUT_FILENO, buffer, bytes);
+
+ if (log)
+ write_log(fileno (log), buffer, bytes);
+ else {
+ if (logbuf_size - logbuf_len < bytes) {
+ logbuf_size += BUFSIZ * 10;
+ logbuf = xrealloc(logbuf,
+ sizeof(char ) *
+ logbuf_size);
}
- }
- /* Only SIGTERMS signals come down this pipe */
- if (FD_ISSET (signal_pipe[0], &rset))
- break;
- }
- }
- free (buffer);
- if (logbuf) {
- if ((log = fopen (LOGFILE, "a"))) {
- write_time (log, "started");
- write_log (fileno (log), logbuf, logbuf_len);
+ memcpy(logbuf + logbuf_len, buffer, bytes);
+ logbuf_len += bytes;
+ }
}
- free (logbuf);
+
+ /* Only SIGTERMS signals come down this pipe */
+ if (FD_ISSET(signal_pipe[0], &rset))
+ break;
}
- if (log) {
- write_time (log, "stopped");
- fclose (log);
+ }
+ free(buffer);
+ if (logbuf) {
+ if ((log = fopen(LOGFILE, "a"))) {
+ write_time(log, "started");
+ write_log(fileno(log), logbuf, logbuf_len);
}
+ free(logbuf);
+ }
+ if (log) {
+ write_time(log, "stopped");
+ fclose(log);
+ }
- /* Try and cat our new logfile to a more permament location and then
- * punt it */
- system (MOVELOG);
-
- exit (0);
- /* NOTREACHED */
- default:
- setpgid (rc_logger_pid, 0);
- fd_stdout = dup (STDOUT_FILENO);
- fd_stderr = dup (STDERR_FILENO);
- if ((s = fcntl (fd_stdout, F_GETFD, 0)) == 0)
- fcntl (fd_stdout, F_SETFD, s | FD_CLOEXEC);
-
- if ((s = fcntl (fd_stderr, F_GETFD, 0)) == 0)
- fcntl (fd_stderr, F_SETFD, s | FD_CLOEXEC);
- dup2 (slave_tty, STDOUT_FILENO);
- dup2 (slave_tty, STDERR_FILENO);
- if (slave_tty != STDIN_FILENO &&
- slave_tty != STDOUT_FILENO &&
- slave_tty != STDERR_FILENO)
- close (slave_tty);
- close (signal_pipe[0]);
- signal_pipe[0] = -1;
- break;
+ /* Try and cat our new logfile to a more permament location and then
+ * punt it */
+ system(MOVELOG);
+
+ exit(0);
+ /* NOTREACHED */
+
+ default:
+ setpgid(rc_logger_pid, 0);
+ fd_stdout = dup(STDOUT_FILENO);
+ fd_stderr = dup(STDERR_FILENO);
+ if ((s = fcntl(fd_stdout, F_GETFD, 0)) == 0)
+ fcntl(fd_stdout, F_SETFD, s | FD_CLOEXEC);
+
+ if ((s = fcntl(fd_stderr, F_GETFD, 0)) == 0)
+ fcntl(fd_stderr, F_SETFD, s | FD_CLOEXEC);
+ dup2(slave_tty, STDOUT_FILENO);
+ dup2(slave_tty, STDERR_FILENO);
+ if (slave_tty != STDIN_FILENO &&
+ slave_tty != STDOUT_FILENO &&
+ slave_tty != STDERR_FILENO)
+ close(slave_tty);
+ close(signal_pipe[0]);
+ signal_pipe[0] = -1;
+ break;
}
}
diff --git a/src/rc/rc-misc.c b/src/rc/rc-misc.c
index 343a153..3167f26 100644
--- a/src/rc/rc-misc.c
+++ b/src/rc/rc-misc.c
@@ -30,13 +30,13 @@
*/
#include <sys/types.h>
+#include <sys/utsname.h>
#ifdef __linux__
#include <sys/sysinfo.h>
#include <regex.h>
#endif
-#include <sys/utsname.h>
#include <ctype.h>
#include <limits.h>
#include <signal.h>
@@ -47,7 +47,6 @@
#include "einfo.h"
#include "rc.h"
#include "rc-misc.h"
-#include "strlist.h"
#define PROFILE_ENV SYSCONFDIR "/profile.env"
#define SYS_WHITELIST RC_LIBDIR "/conf.d/env_whitelist"
@@ -57,314 +56,253 @@
#define PATH_PREFIX RC_LIBDIR "/bin:/bin:/sbin:/usr/bin:/usr/sbin"
-static char **rc_conf = NULL;
+static RC_STRINGLIST *rc_conf = NULL;
+
+extern char** environ;
-static void _free_rc_conf (void)
+static void _free_rc_conf(void)
{
- rc_strlist_free (rc_conf);
+ rc_stringlist_free(rc_conf);
}
-char *rc_conf_value (const char *setting)
+char *rc_conf_value(const char *setting)
{
- if (! rc_conf) {
- char *line;
- int i;
+ RC_STRINGLIST *old;
+ RC_STRING *s;
+ char *p;
- rc_conf = rc_config_load (RC_CONF);
- atexit (_free_rc_conf);
+ if (! rc_conf) {
+ rc_conf = rc_config_load(RC_CONF);
+ atexit(_free_rc_conf);
/* Support old configs */
- if (exists (RC_CONF_OLD)) {
- char **old = rc_config_load (RC_CONF_OLD);
- rc_strlist_join (&rc_conf, old);
- rc_strlist_free (old);
+ if (exists(RC_CONF_OLD)) {
+ old = rc_config_load(RC_CONF_OLD);
+ if (old) {
+ TAILQ_CONCAT(rc_conf, old);
+ free(old);
+ }
}
/* Convert old uppercase to lowercase */
- STRLIST_FOREACH (rc_conf, line, i) {
- char *p = line;
+ TAILQ_FOREACH(s, rc_conf, entries) {
+ p = s->value;
while (p && *p && *p != '=') {
- if (isupper ((int) *p))
- *p = tolower ((int) *p);
+ if (isupper((int) *p))
+ *p = tolower((int) *p);
p++;
}
}
}
- return (rc_config_value ((const char *const *)rc_conf, setting));
+ return rc_config_value(rc_conf, setting);
}
-bool rc_conf_yesno (const char *setting)
+bool rc_conf_yesno(const char *setting)
{
- return (rc_yesno (rc_conf_value (setting)));
+ return rc_yesno(rc_conf_value (setting));
}
-char **env_filter (void)
+static const char *const env_whitelist[] = {
+ "PATH", "SHELL", "USER", "HOME", "TERM",
+ "LANG", "LC_CTYPE", "LC_NUMERIC", "LC_TIME", "LC_COLLATE",
+ "LC_MONETARY", "LC_MESSAGES", "LC_PAPER", "LC_NAME", "LC_ADDRESS",
+ "LC_TELEPHONE", "LC_MEASUREMENT", "LC_IDENTIFICATION", "LC_ALL",
+ "INIT_HALT", "INIT_VERSION", "RUNLEVEL", "PREVLEVEL", "CONSOLE",
+ "IN_HOTPLUG", "IN_BACKGROUND", "RC_INTERFACE_KEEP_CONFIG",
+ NULL
+};
+
+void env_filter(void)
{
- char **env = NULL;
- char **whitelist = NULL;
- char *env_name = NULL;
- char **profile = NULL;
- int count = 0;
- bool got_path = false;
- char *env_var;
- size_t env_len;
- char *token;
- char *sep;
+ RC_STRINGLIST *env_allow;
+ RC_STRINGLIST *profile = NULL;
+ RC_STRINGLIST *env_list;
+ RC_STRING *env;
+ RC_STRING *s;
+ char *env_name;
char *e;
- char *p;
- size_t pplen = strlen (PATH_PREFIX);
-
- /* Init a system whitelist, start with shell vars we need */
- rc_strlist_add (&whitelist, "PATH");
- rc_strlist_add (&whitelist, "SHELL");
- rc_strlist_add (&whitelist, "USER");
- rc_strlist_add (&whitelist, "HOME");
- rc_strlist_add (&whitelist, "TERM");
-
- /* Add Language vars */
- rc_strlist_add (&whitelist, "LANG");
- rc_strlist_add (&whitelist, "LC_CTYPE");
- rc_strlist_add (&whitelist, "LC_NUMERIC");
- rc_strlist_add (&whitelist, "LC_TIME");
- rc_strlist_add (&whitelist, "LC_COLLATE");
- rc_strlist_add (&whitelist, "LC_MONETARY");
- rc_strlist_add (&whitelist, "LC_MESSAGES");
- rc_strlist_add (&whitelist, "LC_PAPER");
- rc_strlist_add (&whitelist, "LC_NAME");
- rc_strlist_add (&whitelist, "LC_ADDRESS");
- rc_strlist_add (&whitelist, "LC_TELEPHONE");
- rc_strlist_add (&whitelist, "LC_MEASUREMENT");
- rc_strlist_add (&whitelist, "LC_IDENTIFICATION");
- rc_strlist_add (&whitelist, "LC_ALL");
-
- /* Allow rc to override library path */
- rc_strlist_add (&whitelist, "LD_LIBRARY_PATH");
-
- /* We need to know sysvinit stuff - we emulate this for BSD too */
- rc_strlist_add (&whitelist, "INIT_HALT");
- rc_strlist_add (&whitelist, "INIT_VERSION");
- rc_strlist_add (&whitelist, "RUNLEVEL");
- rc_strlist_add (&whitelist, "PREVLEVEL");
- rc_strlist_add (&whitelist, "CONSOLE");
-
- /* Hotplug and daemon vars */
- rc_strlist_add (&whitelist, "IN_HOTPLUG");
- rc_strlist_add (&whitelist, "IN_BACKGROUND");
- rc_strlist_add (&whitelist, "RC_INTERFACE_KEEP_CONFIG");
+ char *token;
+ size_t i = 0;
/* Add the user defined list of vars */
- e = env_name = xstrdup (rc_conf_value ("rc_env_allow"));
- while ((token = strsep (&e, " "))) {
+ env_allow = rc_stringlist_new();
+ e = env_name = xstrdup(rc_conf_value ("rc_env_allow"));
+ while ((token = strsep(&e, " "))) {
if (token[0] == '*') {
- free (env_name);
- return (NULL);
+ free(env_name);
+ rc_stringlist_free(env_allow);
+ return;
}
- rc_strlist_add (&whitelist, token);
+ rc_stringlist_add(env_allow, token);
}
- free (env_name);
-
- if (exists (PROFILE_ENV))
- profile = rc_config_load (PROFILE_ENV);
+ free(env_name);
- STRLIST_FOREACH (whitelist, env_name, count) {
- char *space = strchr (env_name, ' ');
- if (space)
- *space = 0;
+ if (exists(PROFILE_ENV))
+ profile = rc_config_load(PROFILE_ENV);
- env_var = getenv (env_name);
+ /* Copy the env and work from this so we can remove safely */
+ env_list = rc_stringlist_new();
+ while (environ[i])
+ rc_stringlist_add(env_list, environ[i++]);
- if (! env_var && profile) {
- env_len = strlen (env_name) + strlen ("export ") + 1;
- p = xmalloc (sizeof (char) * env_len);
- snprintf (p, env_len, "export %s", env_name);
- env_var = rc_config_value ((const char *const *) profile, p);
- free (p);
+ TAILQ_FOREACH(env, env_list, entries) {
+ /* Check the whitelist */
+ i = 0;
+ while (env_whitelist[i]) {
+ if (strcmp(env_whitelist[i++], env->value))
+ break;
}
+ if (env_whitelist[i])
+ continue;
- if (! env_var)
+ /* Check our user defined list */
+ TAILQ_FOREACH(s, env_allow, entries)
+ if (strcmp(s->value, env->value) == 0)
+ break;
+ if (s)
continue;
- /* Ensure our PATH is prefixed with the system locations first
- for a little extra security */
- if (strcmp (env_name, "PATH") == 0 &&
- strncmp (PATH_PREFIX, env_var, pplen) != 0)
- {
- got_path = true;
- env_len = strlen (env_name) + strlen (env_var) + pplen + 3;
- e = p = xmalloc (sizeof (char) * env_len);
- p += snprintf (e, env_len, "%s=%s", env_name, PATH_PREFIX);
-
- /* Now go through the env var and only add bits not in our PREFIX */
- sep = env_var;
- while ((token = strsep (&sep, ":"))) {
- char *np = xstrdup (PATH_PREFIX);
- char *npp = np;
- char *tok = NULL;
- while ((tok = strsep (&npp, ":")))
- if (strcmp (tok, token) == 0)
- break;
- if (! tok)
- p += snprintf (p, env_len - (p - e), ":%s", token);
- free (np);
- }
- *p++ = 0;
- } else {
- env_len = strlen (env_name) + strlen (env_var) + 2;
- e = xmalloc (sizeof (char) * env_len);
- snprintf (e, env_len, "%s=%s", env_name, env_var);
- }
+ /* Now check our profile */
- rc_strlist_add (&env, e);
- free (e);
+ /* OK, not allowed! */
+ e = strchr(env->value, '=');
+ *e = '\0';
+ unsetenv(env->value);
}
-
- /* We filtered the env but didn't get a PATH? Very odd.
- However, we do need a path, so use a default. */
- if (! got_path) {
- env_len = strlen ("PATH=") + strlen (PATH_PREFIX) + 1;
- e = xmalloc (sizeof (char) * env_len);
- snprintf (e, env_len, "PATH=%s", PATH_PREFIX);
- rc_strlist_add (&env, e);
- free (e);
- }
-
- rc_strlist_free (whitelist);
- rc_strlist_free (profile);
-
- return (env);
+ rc_stringlist_free(env_list);
+ rc_stringlist_free(env_allow);
+ rc_stringlist_free(profile);
}
-char **env_config (void)
+void env_config(void)
{
- char **env = NULL;
- char *line;
+ size_t pplen = strlen(PATH_PREFIX);
+ char *path;
+ char *p;
+ char *e;
size_t l;
- const char *sys = rc_sys ();
struct utsname uts;
FILE *fp;
+ char *token;
+ char *np;
+ char *npp;
+ char *tok;
+ const char *sys = rc_sys();
char buffer[PATH_MAX];
- char *runlevel = rc_runlevel_get ();
-
- /* One char less to drop the trailing / */
- l = strlen ("RC_LIBDIR=") + strlen (RC_LIBDIR) + 1;
- line = xmalloc (sizeof (char) * l);
- snprintf (line, l, "RC_LIBDIR=" RC_LIBDIR);
- rc_strlist_add (&env, line);
- free (line);
-
- /* One char less to drop the trailing / */
- l = strlen ("RC_SVCDIR=") + strlen (RC_SVCDIR) + 1;
- line = xmalloc (sizeof (char) * l);
- snprintf (line, l, "RC_SVCDIR=" RC_SVCDIR);
- rc_strlist_add (&env, line);
- free (line);
-
- rc_strlist_add (&env, "RC_BOOTLEVEL=" RC_LEVEL_BOOT);
-
- l = strlen ("RC_SOFTLEVEL=") + strlen (runlevel) + 1;
- line = xmalloc (sizeof (char) * l);
- snprintf (line, l, "RC_SOFTLEVEL=%s", runlevel);
- rc_strlist_add (&env, line);
- free (line);
-
- if ((fp = fopen (RC_KSOFTLEVEL, "r"))) {
- memset (buffer, 0, sizeof (buffer));
- if (fgets (buffer, sizeof (buffer), fp)) {
+
+ /* Ensure our PATH is prefixed with the system locations first
+ for a little extra security */
+ path = getenv("PATH");
+ if (! path)
+ setenv("PATH", PATH_PREFIX, 1);
+ else if (strncmp (PATH_PREFIX, path, pplen) != 0) {
+ l = strlen(path) + pplen + 3;
+ e = p = xmalloc(sizeof(char) * l);
+ p += snprintf(p, l, "%s", PATH_PREFIX);
+
+ /* Now go through the env var and only add bits not in our PREFIX */
+ while ((token = strsep(&path, ":"))) {
+ np = npp = xstrdup(PATH_PREFIX);
+ while ((tok = strsep(&npp, ":")))
+ if (strcmp(tok, token) == 0)
+ break;
+ if (! tok)
+ p += snprintf(p, l - (p - e), ":%s", token);
+ free (np);
+ }
+ *p++ = '\0';
+ unsetenv("PATH");
+ setenv("PATH", e, 1);
+ free(e);
+ }
+
+ setenv("RC_LIBDIR", RC_LIBDIR, 1);
+ setenv("RC_SVCDIR", RC_SVCDIR, 1);
+ setenv("RC_BOOTLEVEL", RC_LEVEL_BOOT, 1);
+ e = rc_runlevel_get();
+ setenv("RC_RUNLEVEL", e, 1);
+ free(e);
+
+ if ((fp = fopen(RC_KSOFTLEVEL, "r"))) {
+ memset(buffer, 0, sizeof (buffer));
+ if (fgets(buffer, sizeof (buffer), fp)) {
l = strlen (buffer) - 1;
if (buffer[l] == '\n')
buffer[l] = 0;
- l += strlen ("RC_DEFAULTLEVEL=") + 2;
- line = xmalloc (sizeof (char) * l);
- snprintf (line, l, "RC_DEFAULTLEVEL=%s", buffer);
- rc_strlist_add (&env, line);
- free (line);
+ setenv("RC_DEFAULTLEVEL", buffer, 1);
}
- fclose (fp);
+ fclose(fp);
} else
- rc_strlist_add (&env, "RC_DEFAULTLEVEL=" RC_LEVEL_DEFAULT);
-
- if (sys) {
- l = strlen ("RC_SYS=") + strlen (sys) + 2;
- line = xmalloc (sizeof (char) * l);
- snprintf (line, l, "RC_SYS=%s", sys);
- rc_strlist_add (&env, line);
- free (line);
- }
+ setenv("RC_DEFAULTLEVEL", RC_LEVEL_DEFAULT, 1);
+
+ if (sys)
+ setenv("RC_SYS", sys, 1);
/* Some scripts may need to take a different code path if Linux/FreeBSD, etc
To save on calling uname, we store it in an environment variable */
- if (uname (&uts) == 0) {
- l = strlen ("RC_UNAME=") + strlen (uts.sysname) + 2;
- line = xmalloc (sizeof (char) * l);
- snprintf (line, l, "RC_UNAME=%s", uts.sysname);
- rc_strlist_add (&env, line);
- free (line);
- }
+ if (uname(&uts) == 0)
+ setenv("RC_UNAME", uts.sysname, 1);
/* Be quiet or verbose as necessary */
- if (rc_conf_yesno ("rc_quiet"))
- rc_strlist_add (&env, "EINFO_QUIET=YES");
- if (rc_conf_yesno ("rc_verbose"))
- rc_strlist_add (&env, "EINFO_VERBOSE=YES");
+ if (rc_conf_yesno("rc_quiet"))
+ setenv("EINFO_QUIET", "YES", 1);
+ if (rc_conf_yesno("rc_verbose"))
+ setenv("EINFO_VERBOSE", "YES", 1);
errno = 0;
- if ((! rc_conf_yesno ("rc_color") && errno == 0) ||
- rc_conf_yesno ("rc_nocolor"))
- rc_strlist_add (&env, "EINFO_COLOR=NO");
-
- free (runlevel);
- return (env);
+ if ((! rc_conf_yesno("rc_color") && errno == 0) ||
+ rc_conf_yesno("rc_nocolor"))
+ setenv("EINFO_COLOR", "NO", 1);
}
-bool service_plugable (const char *service)
+bool service_plugable(const char *service)
{
char *list;
char *p;
char *star;
char *token;
bool allow = true;
- char *match = rc_conf_value ("rc_plug_services");
+ char *match = rc_conf_value("rc_plug_services");
+ bool truefalse;
if (! match)
- return (true);
+ return true;
- list = xstrdup (match);
+ list = xstrdup(match);
p = list;
- while ((token = strsep (&p, " "))) {
- bool truefalse = true;
-
+ while ((token = strsep(&p, " "))) {
if (token[0] == '!') {
truefalse = false;
token++;
- }
+ } else
+ truefalse = true;
- star = strchr (token, '*');
+ star = strchr(token, '*');
if (star) {
- if (strncmp (service, token, (size_t) (star - token))
- == 0)
+ if (strncmp(service, token, (size_t)(star - token)) == 0)
{
allow = truefalse;
break;
}
} else {
- if (strcmp (service, token) == 0) {
+ if (strcmp(service, token) == 0) {
allow = truefalse;
break;
}
}
}
- free (list);
- return (allow);
+ free(list);
+ return allow;
}
-int signal_setup (int sig, void (*handler)(int))
+int signal_setup(int sig, void (*handler)(int))
{
struct sigaction sa;
- memset (&sa, 0, sizeof (sa));
- sigemptyset (&sa.sa_mask);
+ memset(&sa, 0, sizeof (sa));
+ sigemptyset(&sa.sa_mask);
sa.sa_handler = handler;
- return (sigaction (sig, &sa, NULL));
+ return sigaction(sig, &sa, NULL);
}
diff --git a/src/rc/rc-plugin.c b/src/rc/rc-plugin.c
index e3184a3..f0ee5a6 100644
--- a/src/rc/rc-plugin.c
+++ b/src/rc/rc-plugin.c
@@ -31,6 +31,7 @@
#include <sys/types.h>
#include <sys/wait.h>
+
#include <dirent.h>
#include <dlfcn.h>
#include <errno.h>
@@ -46,7 +47,6 @@
#include "rc.h"
#include "rc-misc.h"
#include "rc-plugin.h"
-#include "strlist.h"
#define RC_PLUGIN_HOOK "rc_plugin_hook"
@@ -56,129 +56,117 @@ typedef struct plugin
{
char *name;
void *handle;
- int (*hook) (rc_hook_t, const char *);
- struct plugin *next;
-} plugin_t;
-
-static plugin_t *plugins = NULL;
+ int (*hook)(RC_HOOK, const char *);
+ STAILQ_ENTRY(plugin) entries;
+} PLUGIN;
+STAILQ_HEAD(, plugin) plugins;
#ifndef __FreeBSD__
-dlfunc_t dlfunc (void * __restrict handle, const char * __restrict symbol)
+dlfunc_t dlfunc(void * __restrict handle, const char * __restrict symbol)
{
union {
void *d;
dlfunc_t f;
} rv;
- rv.d = dlsym (handle, symbol);
- return (rv.f);
+ rv.d = dlsym(handle, symbol);
+ return rv.f;
}
#endif
-void rc_plugin_load (void)
+void rc_plugin_load(void)
{
DIR *dp;
struct dirent *d;
- plugin_t *plugin = plugins;
+ PLUGIN *plugin;
char *p;
void *h;
- int (*fptr) (rc_hook_t, const char *);
+ int (*fptr)(RC_HOOK, const char *);
/* Don't load plugins if we're in one */
if (rc_in_plugin)
return;
- /* Ensure some sanity here */
- rc_plugin_unload ();
+ STAILQ_INIT(&plugins);
- if (! (dp = opendir (RC_PLUGINDIR)))
+ if (! (dp = opendir(RC_PLUGINDIR)))
return;
- while ((d = readdir (dp))) {
+ while ((d = readdir(dp))) {
if (d->d_name[0] == '.')
continue;
- p = rc_strcatpaths (RC_PLUGINDIR, d->d_name, NULL);
- h = dlopen (p, RTLD_LAZY);
- free (p);
+ p = rc_strcatpaths(RC_PLUGINDIR, d->d_name, NULL);
+ h = dlopen(p, RTLD_LAZY);
+ free(p);
if (! h) {
- eerror ("dlopen: %s", dlerror ());
+ eerror("dlopen: %s", dlerror());
continue;
}
- fptr = (int (*)(rc_hook_t, const char*)) dlfunc (h, RC_PLUGIN_HOOK);
+ fptr = (int (*)(RC_HOOK, const char*))dlfunc(h, RC_PLUGIN_HOOK);
if (! fptr) {
- eerror ("%s: cannot find symbol `%s'", d->d_name, RC_PLUGIN_HOOK);
- dlclose (h);
+ eerror("%s: cannot find symbol `%s'", d->d_name, RC_PLUGIN_HOOK);
+ dlclose(h);
} else {
- if (plugin) {
- plugin->next = xmalloc (sizeof (*plugin->next));
- plugin = plugin->next;
- } else
- plugin = plugins = xmalloc (sizeof (*plugin));
-
- plugin->name = xstrdup (d->d_name);
+ plugin = xmalloc(sizeof(*plugin));
+ plugin->name = xstrdup(d->d_name);
plugin->handle = h;
plugin->hook = fptr;
- plugin->next = NULL;
+ STAILQ_INSERT_TAIL(&plugins, plugin, entries);
}
}
- closedir (dp);
+ closedir(dp);
}
-int rc_waitpid (pid_t pid)
+int rc_waitpid(pid_t pid)
{
int status = 0;
pid_t savedpid = pid;
int retval = -1;
errno = 0;
- while ((pid = waitpid (savedpid, &status, 0)) > 0) {
+ while ((pid = waitpid(savedpid, &status, 0)) > 0) {
if (pid == savedpid)
- retval = WIFEXITED (status) ? WEXITSTATUS (status) : EXIT_FAILURE;
+ retval = WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE;
}
- return (retval);
+ return retval;
}
-void rc_plugin_run (rc_hook_t hook, const char *value)
+void rc_plugin_run(RC_HOOK hook, const char *value)
{
- plugin_t *plugin = plugins;
+ PLUGIN *plugin;
struct sigaction sa;
sigset_t empty;
sigset_t full;
sigset_t old;
+ int i;
+ int flags;
+ int pfd[2];
+ pid_t pid;
+ char *buffer;
+ char *token;
+ char *p;
+ ssize_t nr;
+ int retval;
/* Don't run plugins if we're in one */
if (rc_in_plugin)
return;
/* We need to block signals until we have forked */
- memset (&sa, 0, sizeof (sa));
+ memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
- sigemptyset (&sa.sa_mask);
- sigemptyset (&empty);
- sigfillset (&full);
-
- while (plugin) {
- int i;
- int flags;
- int pfd[2];
- pid_t pid;
- char *buffer;
- char *token;
- char *p;
- ssize_t nr;
-
- if (! plugin->hook) {
- plugin = plugin->next;
- continue;
- }
+ sigemptyset(&sa.sa_mask);
+ sigemptyset(&empty);
+ sigfillset(&full);
+ STAILQ_FOREACH(plugin, &plugins, entries) {
/* We create a pipe so that plugins can affect our environment
* vars, which in turn influence our scripts. */
- if (pipe (pfd) == -1) {
- eerror ("pipe: %s", strerror (errno));
+ if (pipe(pfd) == -1) {
+ eerror("pipe: %s", strerror(errno));
return;
}
@@ -188,81 +176,78 @@ void rc_plugin_run (rc_hook_t hook, const char *value)
for (i = 0; i < 2; i++)
if ((flags = fcntl (pfd[i], F_GETFD, 0)) < 0 ||
fcntl (pfd[i], F_SETFD, flags | FD_CLOEXEC) < 0)
- eerror ("fcntl: %s", strerror (errno));
+ eerror("fcntl: %s", strerror(errno));
- sigprocmask (SIG_SETMASK, &full, &old);
+ sigprocmask(SIG_SETMASK, &full, &old);
/* We run the plugin in a new process so we never crash
* or otherwise affected by it */
- if ((pid = fork ()) == -1) {
- eerror ("fork: %s", strerror (errno));
+ if ((pid = fork()) == -1) {
+ eerror("fork: %s", strerror(errno));
break;
}
if (pid == 0) {
- int retval;
-
/* Restore default handlers */
- sigaction (SIGCHLD, &sa, NULL);
- sigaction (SIGHUP, &sa, NULL);
- sigaction (SIGINT, &sa, NULL);
- sigaction (SIGQUIT, &sa, NULL);
- sigaction (SIGTERM, &sa, NULL);
- sigaction (SIGUSR1, &sa, NULL);
- sigaction (SIGWINCH, &sa, NULL);
- sigprocmask (SIG_SETMASK, &old, NULL);
+ sigaction(SIGCHLD, &sa, NULL);
+ sigaction(SIGHUP, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGQUIT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGUSR1, &sa, NULL);
+ sigaction(SIGWINCH, &sa, NULL);
+ sigprocmask(SIG_SETMASK, &old, NULL);
rc_in_plugin = true;
- close (pfd[0]);
- rc_environ_fd = fdopen (pfd[1], "w");
- retval = plugin->hook (hook, value);
- fclose (rc_environ_fd);
+ close(pfd[0]);
+ rc_environ_fd = fdopen(pfd[1], "w");
+ retval = plugin->hook(hook, value);
+ fclose(rc_environ_fd);
rc_environ_fd = NULL;
/* Just in case the plugin sets this to false */
rc_in_plugin = true;
- exit (retval);
+ exit(retval);
}
- sigprocmask (SIG_SETMASK, &old, NULL);
- close (pfd[1]);
- buffer = xmalloc (sizeof (char) * BUFSIZ);
- memset (buffer, 0, BUFSIZ);
+ sigprocmask(SIG_SETMASK, &old, NULL);
+ close(pfd[1]);
+ buffer = xmalloc(sizeof(char) * BUFSIZ);
+ memset(buffer, 0, BUFSIZ);
- while ((nr = read (pfd[0], buffer, BUFSIZ)) > 0) {
+ while ((nr = read(pfd[0], buffer, BUFSIZ)) > 0) {
p = buffer;
while (*p && p - buffer < nr) {
- token = strsep (&p, "=");
+ token = strsep(&p, "=");
if (token) {
- unsetenv (token);
+ unsetenv(token);
if (*p) {
- setenv (token, p, 1);
- p += strlen (p) + 1;
+ setenv(token, p, 1);
+ p += strlen(p) + 1;
} else
p++;
}
}
}
- free (buffer);
- close (pfd[0]);
+ free(buffer);
+ close(pfd[0]);
- rc_waitpid (pid);
- plugin = plugin->next;
+ rc_waitpid(pid);
}
}
-void rc_plugin_unload (void)
+void rc_plugin_unload(void)
{
- plugin_t *plugin = plugins;
- plugin_t *next;
+ PLUGIN *plugin = STAILQ_FIRST(&plugins);
+ PLUGIN *next;
while (plugin) {
- next = plugin->next;
- dlclose (plugin->handle);
- free (plugin->name);
- free (plugin);
+ next = STAILQ_NEXT(plugin, entries);
+ dlclose(plugin->handle);
+ free(plugin->name);
+ free(plugin);
plugin = next;
}
- plugins = NULL;
+ STAILQ_INIT(&plugins);
}
diff --git a/src/rc/rc-plugin.h b/src/rc/rc-plugin.h
index 91ba561..0b8ab09 100644
--- a/src/rc/rc-plugin.h
+++ b/src/rc/rc-plugin.h
@@ -36,10 +36,10 @@
* Mainly used in atexit code. */
extern bool rc_in_plugin;
-int rc_waitpid (pid_t pid);
-void rc_plugin_load ();
-void rc_plugin_unload ();
-void rc_plugin_run (rc_hook_t, const char *value);
+int rc_waitpid(pid_t pid);
+void rc_plugin_load(void);
+void rc_plugin_unload(void);
+void rc_plugin_run(RC_HOOK, const char *value);
/* dlfunc defines needed to avoid ISO errors. FreeBSD has this right :) */
#ifndef __FreeBSD__
@@ -47,7 +47,7 @@ struct __dlfunc_arg {
int __dlfunc_dummy;
};
-typedef void (*dlfunc_t) (struct __dlfunc_arg);
+typedef void (*dlfunc_t)(struct __dlfunc_arg);
dlfunc_t dlfunc (void * __restrict handle, const char * __restrict symbol);
#endif
diff --git a/src/rc/rc-status.c b/src/rc/rc-status.c
index 579c416..9f7167f 100644
--- a/src/rc/rc-status.c
+++ b/src/rc/rc-status.c
@@ -39,57 +39,56 @@
#include "einfo.h"
#include "rc.h"
#include "rc-misc.h"
-#include "strlist.h"
extern const char *applet;
static const char *const types_nua[] = { "ineed", "iuse", "iafter", NULL };
-static void print_level (char *level)
+static void print_level(char *level)
{
printf ("Runlevel: ");
- if (isatty (fileno (stdout)))
- printf ("%s%s%s\n",
- ecolor (ECOLOR_HILITE),
- level,
- ecolor (ECOLOR_NORMAL));
+ if (isatty(fileno(stdout)))
+ printf("%s%s%s\n",
+ ecolor(ECOLOR_HILITE),
+ level,
+ ecolor(ECOLOR_NORMAL));
else
- printf ("%s\n", level);
+ printf("%s\n", level);
}
-static void print_service (char *service)
+static void print_service(char *service)
{
char status[10];
- int cols = printf (" %s", service);
- const char *c = ecolor (ECOLOR_GOOD);
- rc_service_state_t state = rc_service_state (service);
- einfo_color_t color = ECOLOR_BAD;
+ int cols = printf(" %s", service);
+ const char *c = ecolor(ECOLOR_GOOD);
+ RC_SERVICE state = rc_service_state(service);
+ ECOLOR color = ECOLOR_BAD;
if (state & RC_SERVICE_STOPPING)
- snprintf (status, sizeof (status), "stopping ");
+ snprintf(status, sizeof(status), "stopping ");
else if (state & RC_SERVICE_STARTING) {
- snprintf (status, sizeof (status), "starting ");
+ snprintf(status, sizeof(status), "starting ");
color = ECOLOR_WARN;
} else if (state & RC_SERVICE_INACTIVE) {
- snprintf (status, sizeof (status), "inactive ");
+ snprintf(status, sizeof(status), "inactive ");
color = ECOLOR_WARN;
} else if (state & RC_SERVICE_STARTED) {
- if (geteuid () == 0 && rc_service_daemons_crashed (service))
- snprintf (status, sizeof (status), " crashed ");
+ if (rc_service_daemons_crashed(service))
+ snprintf(status, sizeof(status), " crashed ");
else {
- snprintf (status, sizeof (status), " started ");
+ snprintf(status, sizeof(status), " started ");
color = ECOLOR_GOOD;
}
} else if (state & RC_SERVICE_SCHEDULED) {
- snprintf (status, sizeof (status), "scheduled");
+ snprintf(status, sizeof(status), "scheduled");
color = ECOLOR_WARN;
} else
- snprintf (status, sizeof (status), " stopped ");
+ snprintf(status, sizeof(status), " stopped ");
errno = 0;
- if (c && *c && isatty (fileno (stdout)))
- printf ("\n");
- ebracket (cols, color, status);
+ if (c && *c && isatty(fileno(stdout)))
+ printf("\n");
+ ebracket(cols, color, status);
}
#include "_usage.h"
@@ -115,99 +114,100 @@ static const char * const longopts_help[] = {
int rc_status (int argc, char **argv)
{
- rc_depinfo_t *deptree = NULL;
- char **levels = NULL;
- char **services = NULL;
- char **ordered = NULL;
- char *level;
- char *service;
+ RC_DEPTREE *deptree = NULL;
+ RC_STRINGLIST *levels = NULL;
+ RC_STRINGLIST *services;
+ RC_STRINGLIST *types = NULL;
+ RC_STRINGLIST *ordered;
+ RC_STRING *s;
+ RC_STRING *l;
+ char *p;
int opt;
- int i;
- int j;
int depopts = RC_DEP_STRICT | RC_DEP_START | RC_DEP_TRACE;
- while ((opt = getopt_long (argc, argv, getoptstring, longopts,
- (int *) 0)) != -1)
+ while ((opt = getopt_long(argc, argv, getoptstring, longopts,
+ (int *) 0)) != -1)
switch (opt) {
- case 'a':
- levels = rc_runlevel_list ();
- break;
- case 'l':
- levels = rc_runlevel_list ();
- STRLIST_FOREACH (levels, level, i)
- printf ("%s\n", level);
- rc_strlist_free (levels);
- exit (EXIT_SUCCESS);
- /* NOTREACHED */
- case 'r':
- level = rc_runlevel_get ();
- printf ("%s\n", level);
- free (level);
- exit (EXIT_SUCCESS);
- /* NOTREACHED */
- case 's':
- services = rc_services_in_runlevel (NULL);
- STRLIST_FOREACH (services, service, i)
- print_service (service);
- rc_strlist_free (services);
- exit (EXIT_SUCCESS);
- /* NOTREACHED */
- case 'u':
- services = rc_services_in_runlevel (NULL);
- levels = rc_runlevel_list ();
- STRLIST_FOREACH (services, service, i) {
- bool found = false;
- STRLIST_FOREACH (levels, level, j)
- if (rc_service_in_runlevel (service, level)) {
- found = true;
- break;
- }
- if (! found)
- print_service (service);
- }
- rc_strlist_free (levels);
- rc_strlist_free (services);
- exit (EXIT_SUCCESS);
- /* NOTREACHED */
-
- case_RC_COMMON_GETOPT
+ case 'a':
+ levels = rc_runlevel_list();
+ break;
+ case 'l':
+ levels = rc_runlevel_list();
+ TAILQ_FOREACH (l, levels, entries)
+ printf("%s\n", l->value);
+ rc_stringlist_free(levels);
+ exit(EXIT_SUCCESS);
+ /* NOTREACHED */
+ case 'r':
+ p = rc_runlevel_get ();
+ printf("%s\n", p);
+ free(p);
+ exit(EXIT_SUCCESS);
+ /* NOTREACHED */
+ case 's':
+ services = rc_services_in_runlevel(NULL);
+ TAILQ_FOREACH(s, services, entries)
+ print_service(s->value);
+ rc_stringlist_free(services);
+ exit (EXIT_SUCCESS);
+ /* NOTREACHED */
+ case 'u':
+ services = rc_services_in_runlevel(NULL);
+ levels = rc_runlevel_list();
+ TAILQ_FOREACH(s, services, entries) {
+ TAILQ_FOREACH(l, levels, entries)
+ if (rc_service_in_runlevel(s->value, l->value))
+ break;
+ if (! l)
+ print_service(s->value);
+ }
+ rc_stringlist_free(levels);
+ rc_stringlist_free(services);
+ exit (EXIT_SUCCESS);
+ /* NOTREACHED */
+
+ case_RC_COMMON_GETOPT
}
+ if (! levels)
+ levels = rc_stringlist_new();
while (optind < argc)
- rc_strlist_add (&levels, argv[optind++]);
-
- if (! levels) {
- level = rc_runlevel_get ();
- rc_strlist_add (&levels, level);
- free (level);
+ rc_stringlist_add(levels, argv[optind++]);
+ if (! TAILQ_FIRST(levels)) {
+ p = rc_runlevel_get();
+ rc_stringlist_add(levels, p);
+ free(p);
}
/* Output the services in the order in which they would start */
- if (geteuid () == 0)
- deptree = _rc_deptree_load (NULL);
- else
- deptree = rc_deptree_load ();
+ deptree = _rc_deptree_load(NULL);
- STRLIST_FOREACH (levels, level, i) {
- print_level (level);
- services = rc_services_in_runlevel (level);
+ TAILQ_FOREACH(l, levels, entries) {
+ print_level(l->value);
+ services = rc_services_in_runlevel(l->value);
if (deptree) {
- ordered = rc_deptree_depends (deptree, types_nua,
- (const char **) services,
- level, depopts);
- rc_strlist_free (services);
+ if (! types) {
+ types = rc_stringlist_new();
+ rc_stringlist_add(types, "ineed");
+ rc_stringlist_add(types, "iuse");
+ rc_stringlist_add(types, "iafter");
+ }
+ ordered = rc_deptree_depends(deptree, types, services,
+ l->value, depopts);
+ rc_stringlist_free(services);
services = ordered;
ordered = NULL;
}
- STRLIST_FOREACH (services, service, j)
- if (rc_service_in_runlevel (service, level))
- print_service (service);
- rc_strlist_free (services);
+ TAILQ_FOREACH(s, services, entries)
+ if (rc_service_in_runlevel(s->value, l->value))
+ print_service(s->value);
+ rc_stringlist_free(services);
}
- rc_strlist_free (levels);
- rc_deptree_free (deptree);
+ rc_stringlist_free(types);
+ rc_stringlist_free(levels);
+ rc_deptree_free(deptree);
- exit (EXIT_SUCCESS);
+ exit(EXIT_SUCCESS);
/* NOTREACHED */
}
diff --git a/src/rc/rc-update.c b/src/rc/rc-update.c
index fdd1417..e09f521 100644
--- a/src/rc/rc-update.c
+++ b/src/rc/rc-update.c
@@ -42,7 +42,6 @@
#include "einfo.h"
#include "rc.h"
#include "rc-misc.h"
-#include "strlist.h"
extern const char *applet;
@@ -68,7 +67,7 @@ static int add (const char *runlevel, const char *service)
eerror ("%s: failed to add service `%s' to runlevel `%s': %s",
applet, service, runlevel, strerror (errno));
- return (retval);
+ return retval;
}
static int delete (const char *runlevel, const char *service)
@@ -88,44 +87,47 @@ static int delete (const char *runlevel, const char *service)
eerror ("%s: failed to remove service `%s' from runlevel `%s': %s",
applet, service, runlevel, strerror (errno));
- return (retval);
+ return retval;
}
-static void show (char **runlevels, bool verbose)
+static void show (RC_STRINGLIST *runlevels, bool verbose)
{
- char *service;
- char **services = rc_services_in_runlevel (NULL);
- char *runlevel;
- int i;
- int j;
-
- STRLIST_FOREACH (services, service, i) {
- char **in = NULL;
- bool inone = false;
-
- STRLIST_FOREACH (runlevels, runlevel, j) {
- if (rc_service_in_runlevel (service, runlevel)) {
- rc_strlist_add (&in, runlevel);
+ RC_STRINGLIST *services = rc_services_in_runlevel(NULL);
+ RC_STRING *service;
+ RC_STRING *runlevel;
+ RC_STRINGLIST *in;
+ bool inone;
+ char buffer[PATH_MAX];
+ size_t l;
+
+ TAILQ_FOREACH(service, services, entries) {
+ in = rc_stringlist_new();
+ inone = false;
+
+ TAILQ_FOREACH(runlevel, runlevels, entries) {
+ if (rc_service_in_runlevel(service->value,
+ runlevel->value))
+ {
+ rc_stringlist_add(in, runlevel->value);
inone = true;
} else {
- char buffer[PATH_MAX];
- memset (buffer, ' ', strlen (runlevel));
- buffer[strlen (runlevel)] = 0;
- rc_strlist_add (&in, buffer);
+ l = strlen(runlevel->value);
+ memset (buffer, ' ', l);
+ buffer[l] = 0;
+ rc_stringlist_add (in, buffer);
}
}
- if (! inone && ! verbose)
- continue;
-
- printf (" %20s |", service);
- STRLIST_FOREACH (in, runlevel, j)
- printf (" %s", runlevel);
- printf ("\n");
- rc_strlist_free (in);
+ if (inone || verbose) {
+ printf(" %20s |", service->value);
+ TAILQ_FOREACH(runlevel, in, entries)
+ printf (" %s", runlevel->value);
+ printf ("\n");
+ }
+ rc_stringlist_free(in);
}
- rc_strlist_free (services);
+ rc_stringlist_free (services);
}
#include "_usage.h"
@@ -146,111 +148,124 @@ static const char * const longopts_help[] = {
#define DODELETE (1 << 2)
#define DOSHOW (1 << 3)
-int rc_update (int argc, char **argv)
+int rc_update(int argc, char **argv)
{
- int i;
+ RC_STRINGLIST *runlevels;
+ RC_STRING *runlevel;
char *service = NULL;
- char **runlevels = NULL;
- char *runlevel;
+ char *p;
int action = 0;
bool verbose = false;
int opt;
int retval = EXIT_FAILURE;
+ int num_updated = 0;
+ int (*actfunc)(const char *, const char *);
+ int ret;
- while ((opt = getopt_long (argc, argv, getoptstring,
+ while ((opt = getopt_long(argc, argv, getoptstring,
longopts, (int *) 0)) != -1)
- {
switch (opt) {
- case_RC_COMMON_GETOPT
+ case_RC_COMMON_GETOPT
}
- }
- verbose = rc_yesno (getenv ("EINFO_VERBOSE"));
+ verbose = rc_yesno(getenv ("EINFO_VERBOSE"));
if ((action & DOSHOW && action != DOSHOW) ||
(action & DOADD && action != DOADD) ||
(action & DODELETE && action != DODELETE))
- eerrorx ("%s: cannot mix commands", applet);
+ eerrorx("%s: cannot mix commands", applet);
/* We need to be backwards compatible */
if (optind < argc) {
- if (strcmp (argv[optind], "add") == 0)
+ if (strcmp(argv[optind], "add") == 0)
action = DOADD;
- else if (strcmp (argv[optind], "delete") == 0 ||
- strcmp (argv[optind], "del") == 0)
+ else if (strcmp(argv[optind], "delete") == 0 ||
+ strcmp(argv[optind], "del") == 0)
action = DODELETE;
- else if (strcmp (argv[optind], "show") == 0)
+ else if (strcmp(argv[optind], "show") == 0)
action = DOSHOW;
if (action)
optind++;
else
- eerrorx ("%s: invalid command `%s'", applet, argv[optind]);
+ eerrorx("%s: invalid command `%s'", applet, argv[optind]);
}
if (! action)
action = DOSHOW;
+ runlevels = rc_stringlist_new();
+
if (optind >= argc) {
if (! action & DOSHOW)
- eerrorx ("%s: no service specified", applet);
+ eerrorx("%s: no service specified", applet);
} else {
service = argv[optind];
optind++;
while (optind < argc)
- if (rc_runlevel_exists (argv[optind]))
- rc_strlist_add (&runlevels, argv[optind++]);
+ if (rc_runlevel_exists(argv[optind]))
+ rc_stringlist_add(runlevels, argv[optind++]);
else {
- rc_strlist_free (runlevels);
- eerrorx ("%s: `%s' is not a valid runlevel", applet, argv[optind]);
+ rc_stringlist_free(runlevels);
+ eerrorx ("%s: `%s' is not a valid runlevel",
+ applet, argv[optind]);
}
}
retval = EXIT_SUCCESS;
if (action & DOSHOW) {
if (service)
- rc_strlist_add (&runlevels, service);
- if (! runlevels)
- runlevels = rc_runlevel_list ();
+ rc_stringlist_add(runlevels, service);
+ if (! TAILQ_FIRST(runlevels)) {
+ free(runlevels);
+ runlevels = rc_runlevel_list();
+ }
show (runlevels, verbose);
} else {
if (! service)
eerror ("%s: no service specified", applet);
else {
- int num_updated = 0;
- int (*actfunc)(const char *, const char *);
- int ret;
-
if (action & DOADD) {
actfunc = add;
} else if (action & DODELETE) {
actfunc = delete;
- } else
+ } else {
+ rc_stringlist_free(runlevels);
eerrorx ("%s: invalid action", applet);
+ }
- if (! runlevels)
- rc_strlist_add (&runlevels, rc_runlevel_get ());
+ if (! TAILQ_FIRST(runlevels)) {
+ p = rc_runlevel_get();
+ rc_stringlist_add(runlevels, p);
+ free(p);
+ }
- if (! runlevels)
+ if (! TAILQ_FIRST(runlevels)) {
+ free(runlevels);
eerrorx ("%s: no runlevels found", applet);
+ }
- STRLIST_FOREACH (runlevels, runlevel, i) {
- if (! rc_runlevel_exists (runlevel)) {
- eerror ("%s: runlevel `%s' does not exist", applet, runlevel);
+ TAILQ_FOREACH (runlevel, runlevels, entries) {
+ if (! rc_runlevel_exists(runlevel->value)) {
+ eerror ("%s: runlevel `%s' does not exist",
+ applet, runlevel->value);
continue;
}
- ret = actfunc (runlevel, service);
+ ret = actfunc(runlevel->value, service);
if (ret < 0)
retval = EXIT_FAILURE;
num_updated += ret;
}
- if (retval == EXIT_SUCCESS && num_updated == 0 && action & DODELETE)
- ewarnx ("%s: service `%s' not found in any of the specified runlevels", applet, service);
+ if (retval == EXIT_SUCCESS &&
+ num_updated == 0 && action & DODELETE)
+ ewarnx("%s: service `%s' not found in any"
+ " of the specified runlevels",
+ applet, service);
}
}
- rc_strlist_free (runlevels);
- return (retval);
+ rc_stringlist_free(runlevels);
+ return retval;
}
diff --git a/src/rc/rc.c b/src/rc/rc.c
index 98b44cc..6a6aa0a 100644
--- a/src/rc/rc.c
+++ b/src/rc/rc.c
@@ -42,10 +42,18 @@ const char rc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
#include <sys/stat.h>
#include <sys/utsname.h>
#include <sys/wait.h>
+
+/* So we can coldplug net devices */
+#ifdef BSD
+# include <sys/socket.h>
+# include <ifaddrs.h>
+#endif
+
#include <errno.h>
#include <dirent.h>
#include <ctype.h>
#include <getopt.h>
+#include <libgen.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
@@ -56,19 +64,12 @@ const char rc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
#include <termios.h>
#include <unistd.h>
-/* So we can coldplug net devices */
-#ifdef BSD
-# include <sys/socket.h>
-# include <ifaddrs.h>
-#endif
-
#include "builtins.h"
#include "einfo.h"
#include "rc.h"
#include "rc-logger.h"
#include "rc-misc.h"
#include "rc-plugin.h"
-#include "strlist.h"
#include "version.h"
@@ -81,43 +82,31 @@ const char rc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
#define INTERACTIVE RC_SVCDIR "/interactive"
-#define DEVBOOT "/dev/.rcboot"
-
-/* Cleanup anything in main */
-#define CHAR_FREE(_item) if (_item) { \
- free (_item); \
- _item = NULL; \
-}
-
-extern char **environ;
+#define DEVBOOT "/dev/.rcboot"
static char *RUNLEVEL = NULL;
static char *PREVLEVEL = NULL;
const char *applet = NULL;
static char *runlevel = NULL;
-static char **env = NULL;
-static char **newenv = NULL;
-static char **coldplugged_services = NULL;
-static char **stop_services = NULL;
-static char **start_services = NULL;
-static rc_depinfo_t *deptree = NULL;
-static rc_hook_t hook_out = 0;
-static char *tmp = NULL;
+static RC_STRINGLIST *coldplugged_services = NULL;
+static RC_STRINGLIST *stop_services = NULL;
+static RC_STRINGLIST *start_services = NULL;
+static RC_STRINGLIST *types_n = NULL;
+static RC_STRINGLIST *types_nua = NULL;
+static RC_DEPTREE *deptree = NULL;
+static RC_HOOK hook_out = 0;
struct termios *termios_orig = NULL;
-typedef struct pidlist
+typedef struct piditem
{
pid_t pid;
- struct pidlist *next;
-} pidlist_t;
-static pidlist_t *service_pids = NULL;
-
-static const char *const types_n[] = { "needsme", NULL };
-static const char *const types_nua[] = { "ineed", "iuse", "iafter", NULL };
+ LIST_ENTRY(piditem) entries;
+} PIDITEM;
+LIST_HEAD(, piditem) service_pids;
-static void clean_failed (void)
+static void clean_failed(void)
{
DIR *dp;
struct dirent *d;
@@ -125,70 +114,71 @@ static void clean_failed (void)
char *path;
/* Clean the failed services state dir now */
- if ((dp = opendir (RC_SVCDIR "/failed"))) {
- while ((d = readdir (dp))) {
+ if ((dp = opendir(RC_SVCDIR "/failed"))) {
+ while ((d = readdir(dp))) {
if (d->d_name[0] == '.' &&
(d->d_name[1] == '\0' ||
(d->d_name[1] == '.' && d->d_name[2] == '\0')))
continue;
- l = strlen (RC_SVCDIR "/failed/") + strlen (d->d_name) + 1;
- path = xmalloc (sizeof (char) * l);
- snprintf (path, l, RC_SVCDIR "/failed/%s", d->d_name);
+ l = strlen(RC_SVCDIR "/failed/") + strlen(d->d_name) + 1;
+ path = xmalloc(sizeof(char) * l);
+ snprintf(path, l, RC_SVCDIR "/failed/%s", d->d_name);
if (path) {
- if (unlink (path))
- eerror ("%s: unlink `%s': %s", applet, path,
- strerror (errno));
- free (path);
+ if (unlink(path))
+ eerror("%s: unlink `%s': %s", applet, path,
+ strerror(errno));
+ free(path);
}
}
- closedir (dp);
+ closedir(dp);
}
}
-static void cleanup (void)
+static void cleanup(void)
{
- if (applet && strcmp (applet, "rc") == 0) {
- pidlist_t *pl = service_pids;
+ if (applet && strcmp(applet, "rc") == 0) {
+ PIDITEM *p1 = LIST_FIRST(&service_pids);
+ PIDITEM *p2;
if (hook_out)
- rc_plugin_run (hook_out, runlevel);
+ rc_plugin_run(hook_out, runlevel);
- rc_plugin_unload ();
+ rc_plugin_unload();
if (! rc_in_plugin && termios_orig) {
- tcsetattr (fileno (stdin), TCSANOW, termios_orig);
- free (termios_orig);
+ tcsetattr(fileno(stdin), TCSANOW, termios_orig);
+ free(termios_orig);
}
- while (pl) {
- pidlist_t *p = pl->next;
- free (pl);
- pl = p;
+ while (p1) {
+ p2 = LIST_NEXT(p1, entries);
+ free(p1);
+ p1 = p2;
}
- rc_strlist_free (env);
- rc_strlist_free (newenv);
- rc_strlist_free (coldplugged_services);
- rc_strlist_free (stop_services);
- rc_strlist_free (start_services);
- rc_deptree_free (deptree);
+ rc_stringlist_free(coldplugged_services);
+ rc_stringlist_free(stop_services);
+ rc_stringlist_free(start_services);
+ rc_stringlist_free(types_n);
+ rc_stringlist_free(types_nua);
+ rc_deptree_free(deptree);
/* Clean runlevel start, stop markers */
if (! rc_in_plugin && ! rc_in_logger) {
- rmdir (RC_STARTING);
- rmdir (RC_STOPPING);
- clean_failed ();
+ rmdir(RC_STARTING);
+ rmdir(RC_STOPPING);
+ clean_failed();
- rc_logger_close ();
+ rc_logger_close();
}
- free (runlevel);
+ free(runlevel);
}
}
#ifdef __linux__
-static char *proc_getent (const char *ent)
+static char *proc_getent(const char *ent)
{
FILE *fp;
char *proc;
@@ -196,50 +186,50 @@ static char *proc_getent (const char *ent)
char *value = NULL;
int i;
- if (! exists ("/proc/cmdline"))
- return (NULL);
+ if (! exists("/proc/cmdline"))
+ return NULL;
- if (! (fp = fopen ("/proc/cmdline", "r"))) {
- eerror ("failed to open `/proc/cmdline': %s", strerror (errno));
- return (NULL);
+ if (! (fp = fopen("/proc/cmdline", "r"))) {
+ eerror("failed to open `/proc/cmdline': %s", strerror(errno));
+ return NULL;
}
- if ((proc = rc_getline (fp)) &&
- (p = strstr (proc, ent)))
+ if ((proc = rc_getline(fp)) &&
+ (p = strstr(proc, ent)))
{
i = p - proc;
if (i == '\0' || proc[i - 1] == ' ') {
- p += strlen (ent);
+ p += strlen(ent);
if (*p == '=')
p++;
- value = xstrdup (strsep (&p, " "));
+ value = xstrdup(strsep(&p, " "));
}
} else
errno = ENOENT;
- free (proc);
- fclose (fp);
+ free(proc);
+ fclose(fp);
- return (value);
+ return value;
}
#endif
-static char read_key (bool block)
+static char read_key(bool block)
{
struct termios termios;
char c = 0;
- int fd = fileno (stdin);
+ int fd = fileno(stdin);
- if (! isatty (fd))
- return (false);
+ if (! isatty(fd))
+ return false;
/* Now save our terminal settings. We need to restore them at exit as we
* will be changing it for non-blocking reads for Interactive */
if (! termios_orig) {
- termios_orig = xmalloc (sizeof (*termios_orig));
- tcgetattr (fd, termios_orig);
+ termios_orig = xmalloc(sizeof(*termios_orig));
+ tcgetattr(fd, termios_orig);
}
- tcgetattr (fd, &termios);
+ tcgetattr(fd, &termios);
termios.c_lflag &= ~(ICANON | ECHO);
if (block)
termios.c_cc[VMIN] = 1;
@@ -247,49 +237,49 @@ static char read_key (bool block)
termios.c_cc[VMIN] = 0;
termios.c_cc[VTIME] = 0;
}
- tcsetattr (fd, TCSANOW, &termios);
+ tcsetattr(fd, TCSANOW, &termios);
- read (fd, &c, 1);
+ read(fd, &c, 1);
- tcsetattr (fd, TCSANOW, termios_orig);
+ tcsetattr(fd, TCSANOW, termios_orig);
- return (c);
+ return c;
}
-static bool want_interactive (void)
+static bool want_interactive(void)
{
char c;
static bool gotinteractive;
static bool interactive;
- if (rc_yesno (getenv ("EINFO_QUIET")))
- return (false);
+ if (rc_yesno(getenv("EINFO_QUIET")))
+ return false;
if (PREVLEVEL &&
- strcmp (PREVLEVEL, "N") != 0 &&
- strcmp (PREVLEVEL, "S") != 0 &&
- strcmp (PREVLEVEL, "1") != 0)
- return (false);
+ strcmp(PREVLEVEL, "N") != 0 &&
+ strcmp(PREVLEVEL, "S") != 0 &&
+ strcmp(PREVLEVEL, "1") != 0)
+ return false;
if (! gotinteractive) {
gotinteractive = true;
- interactive = rc_conf_yesno ("rc_interactive");
+ interactive = rc_conf_yesno("rc_interactive");
}
if (! interactive)
- return (false);
+ return false;
- c = read_key (false);
- return ((c == 'I' || c == 'i') ? true : false);
+ c = read_key(false);
+ return (c == 'I' || c == 'i') ? true : false;
}
-static void mark_interactive (void)
+static void mark_interactive(void)
{
- FILE *fp = fopen (INTERACTIVE, "w");
+ FILE *fp = fopen(INTERACTIVE, "w");
if (fp)
- fclose (fp);
+ fclose(fp);
}
-static void sulogin (bool cont)
+static void sulogin(bool cont)
{
int status = 0;
struct sigaction sa;
@@ -297,287 +287,276 @@ static void sulogin (bool cont)
sigset_t old;
pid_t pid;
#ifdef __linux__
- const char *sys = rc_sys ();
+ const char *sys = rc_sys();
/* VSERVER and OPENVZ systems cannot do a sulogin */
- if (sys && (strcmp (sys, "VSERVER") == 0 || strcmp (sys, "OPENVZ") == 0)) {
- execl ("/sbin/halt", "/sbin/halt", "-f", (char *) NULL);
- eerrorx ("%s: unable to exec `/sbin/halt': %s", applet, strerror (errno));
+ if (sys && (strcmp(sys, "VSERVER") == 0 || strcmp(sys, "OPENVZ") == 0)) {
+ execl("/sbin/halt", "/sbin/halt", "-f", (char *) NULL);
+ eerrorx("%s: unable to exec `/sbin/halt': %s",
+ applet, strerror(errno));
}
#endif
- newenv = env_filter ();
-
if (! cont) {
- rc_logger_close ();
+ rc_logger_close();
#ifdef __linux__
- execle ("/sbin/sulogin", "/sbin/sulogin", (char *) NULL, newenv);
- eerrorx ("%s: unable to exec `/sbin/sulogin': %s", applet, strerror (errno));
+ execl("/sbin/sulogin", "/sbin/sulogin", (char *) NULL);
+ eerrorx("%s: unable to exec `/sbin/sulogin': %s",
+ applet, strerror(errno));
#else
- exit (EXIT_SUCCESS);
+ exit(EXIT_SUCCESS);
#endif
}
/* We need to block signals until we have forked */
- memset (&sa, 0, sizeof (sa));
+ memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
- sigemptyset (&sa.sa_mask);
- sigfillset (&full);
- sigprocmask (SIG_SETMASK, &full, &old);
- pid = vfork ();
+ sigemptyset(&sa.sa_mask);
+ sigfillset(&full);
+ sigprocmask(SIG_SETMASK, &full, &old);
+ pid = vfork();
if (pid == -1)
- eerrorx ("%s: fork: %s", applet, strerror (errno));
+ eerrorx("%s: fork: %s", applet, strerror(errno));
if (pid == 0) {
/* Restore default handlers */
- sigaction (SIGCHLD, &sa, NULL);
- sigaction (SIGHUP, &sa, NULL);
- sigaction (SIGINT, &sa, NULL);
- sigaction (SIGQUIT, &sa, NULL);
- sigaction (SIGTERM, &sa, NULL);
- sigaction (SIGUSR1, &sa, NULL);
- sigaction (SIGWINCH, &sa, NULL);
+ sigaction(SIGCHLD, &sa, NULL);
+ sigaction(SIGHUP, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGQUIT, &sa, NULL);
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGUSR1, &sa, NULL);
+ sigaction(SIGWINCH, &sa, NULL);
/* Unmask signals */
- sigprocmask (SIG_SETMASK, &old, NULL);
+ sigprocmask(SIG_SETMASK, &old, NULL);
if (termios_orig)
- tcsetattr (fileno (stdin), TCSANOW, termios_orig);
+ tcsetattr(fileno(stdin), TCSANOW, termios_orig);
#ifdef __linux__
- execle (SULOGIN, SULOGIN, (char *) NULL, newenv);
- eerror ("%s: unable to exec `%s': %s", applet, SULOGIN,
- strerror (errno));
+ execl(SULOGIN, SULOGIN, (char *) NULL);
+ eerror("%s: unable to exec `%s': %s", applet, SULOGIN,
+ strerror(errno));
#else
- execle ("/bin/sh", "/bin/sh", (char *) NULL, newenv);
- eerror ("%s: unable to exec `/bin/sh': %s", applet,
- strerror (errno));
+ execl("/bin/sh", "/bin/sh", (char *) NULL);
+ eerror("%s: unable to exec `/bin/sh': %s", applet,
+ strerror(errno));
#endif
- _exit (EXIT_FAILURE);
+ _exit(EXIT_FAILURE);
}
/* Unmask signals and wait for child */
- sigprocmask (SIG_SETMASK, &old, NULL);
- waitpid (pid, &status, 0);
+ sigprocmask(SIG_SETMASK, &old, NULL);
+ waitpid(pid, &status, 0);
}
-static void single_user (void)
+static void single_user(void)
{
- rc_logger_close ();
+ rc_logger_close();
- execl (SHUTDOWN, SHUTDOWN, "now", (char *) NULL);
- eerrorx ("%s: unable to exec `" SHUTDOWN "': %s",
- applet, strerror (errno));
+ execl(SHUTDOWN, SHUTDOWN, "now", (char *) NULL);
+ eerrorx("%s: unable to exec `" SHUTDOWN "': %s",
+ applet, strerror(errno));
}
-static bool set_ksoftlevel (const char *level)
+static bool set_ksoftlevel(const char *level)
{
FILE *fp;
if (! level ||
- strcmp (level, getenv ("RC_BOOTLEVEL")) == 0 ||
- strcmp (level, RC_LEVEL_SINGLE) == 0 ||
- strcmp (level, RC_LEVEL_SYSINIT) == 0)
+ strcmp(level, getenv ("RC_BOOTLEVEL")) == 0 ||
+ strcmp(level, RC_LEVEL_SINGLE) == 0 ||
+ strcmp(level, RC_LEVEL_SYSINIT) == 0)
{
- if (exists (RC_KSOFTLEVEL) &&
- unlink (RC_KSOFTLEVEL) != 0)
- eerror ("unlink `%s': %s", RC_KSOFTLEVEL, strerror (errno));
- return (false);
+ if (exists(RC_KSOFTLEVEL) &&
+ unlink(RC_KSOFTLEVEL) != 0)
+ eerror("unlink `%s': %s", RC_KSOFTLEVEL, strerror(errno));
+ return false;
}
- if (! (fp = fopen (RC_KSOFTLEVEL, "w"))) {
- eerror ("fopen `%s': %s", RC_KSOFTLEVEL, strerror (errno));
- return (false);
+ if (! (fp = fopen(RC_KSOFTLEVEL, "w"))) {
+ eerror("fopen `%s': %s", RC_KSOFTLEVEL, strerror(errno));
+ return false;
}
- fprintf (fp, "%s", level);
- fclose (fp);
- return (true);
+ fprintf(fp, "%s", level);
+ fclose(fp);
+ return true;
}
-static int get_ksoftlevel (char *buffer, int buffer_len)
+static int get_ksoftlevel(char *buffer, int buffer_len)
{
FILE *fp;
int i = 0;
- if (! exists (RC_KSOFTLEVEL))
- return (0);
+ if (! exists(RC_KSOFTLEVEL))
+ return 0;
- if (! (fp = fopen (RC_KSOFTLEVEL, "r"))) {
- eerror ("fopen `%s': %s", RC_KSOFTLEVEL, strerror (errno));
- return (-1);
+ if (! (fp = fopen(RC_KSOFTLEVEL, "r"))) {
+ eerror("fopen `%s': %s", RC_KSOFTLEVEL, strerror(errno));
+ return -1;
}
- if (fgets (buffer, buffer_len, fp)) {
- i = strlen (buffer) - 1;
+ if (fgets(buffer, buffer_len, fp)) {
+ i = strlen(buffer) - 1;
if (buffer[i] == '\n')
buffer[i] = 0;
}
- fclose (fp);
- return (i);
+ fclose(fp);
+ return i;
}
-static void add_pid (pid_t pid)
+static void add_pid(pid_t pid)
{
- pidlist_t *sp = service_pids;
- if (sp) {
- while (sp->next)
- sp = sp->next;
- sp->next = xmalloc (sizeof (*sp->next));
- sp = sp->next;
- } else
- sp = service_pids = xmalloc (sizeof (*sp));
- memset (sp, 0, sizeof (*sp));
- sp->pid = pid;
+ PIDITEM *p = xmalloc(sizeof(*p));
+ p->pid = pid;
+ LIST_INSERT_HEAD(&service_pids, p, entries);
}
-static void remove_pid (pid_t pid)
+static void remove_pid(pid_t pid)
{
- pidlist_t *last = NULL;
- pidlist_t *pl;
+ PIDITEM *p;
- for (pl = service_pids; pl; pl = pl->next) {
- if (pl->pid == pid) {
- if (last)
- last->next = pl->next;
- else
- service_pids = pl->next;
- free (pl);
- break;
+ LIST_FOREACH(p, &service_pids, entries)
+ if (p->pid == pid) {
+ LIST_REMOVE(p, entries);
+ free(p);
+ return;
}
- last = pl;
- }
}
-static void wait_for_services ()
+static void wait_for_services(void)
{
- while (waitpid (0, 0, 0) != -1);
+ while (waitpid(0, 0, 0) != -1);
}
-static void handle_signal (int sig)
+static void handle_signal(int sig)
{
int serrno = errno;
char signame[10] = { '\0' };
- pidlist_t *pl;
pid_t pid;
+ PIDITEM *pi;
int status = 0;
struct winsize ws;
sigset_t sset;
switch (sig) {
- case SIGCHLD:
- do {
- pid = waitpid (-1, &status, WNOHANG);
- if (pid < 0) {
- if (errno != ECHILD)
- eerror ("waitpid: %s", strerror (errno));
- return;
- }
- } while (! WIFEXITED (status) && ! WIFSIGNALED (status));
-
- /* Remove that pid from our list */
- if (pid > 0)
- remove_pid (pid);
- break;
-
- case SIGWINCH:
- if (rc_logger_tty >= 0) {
- ioctl (STDIN_FILENO, TIOCGWINSZ, &ws);
- ioctl (rc_logger_tty, TIOCSWINSZ, &ws);
+ case SIGCHLD:
+ do {
+ pid = waitpid(-1, &status, WNOHANG);
+ if (pid < 0) {
+ if (errno != ECHILD)
+ eerror("waitpid: %s", strerror(errno));
+ return;
}
- break;
-
- case SIGINT:
- if (! signame[0])
- snprintf (signame, sizeof (signame), "SIGINT");
- /* FALLTHROUGH */
- case SIGTERM:
- if (! signame[0])
- snprintf (signame, sizeof (signame), "SIGTERM");
- /* FALLTHROUGH */
- case SIGQUIT:
- if (! signame[0])
- snprintf (signame, sizeof (signame), "SIGQUIT");
- eerrorx ("%s: caught %s, aborting", applet, signame);
- /* NOTREACHED */
- case SIGUSR1:
- eerror ("rc: Aborting!");
-
- /* Block child signals */
- sigemptyset (&sset);
- sigaddset (&sset, SIGCHLD);
- sigprocmask (SIG_BLOCK, &sset, NULL);
-
- /* Kill any running services we have started */
- for (pl = service_pids; pl; pl = pl->next)
- kill (pl->pid, SIGTERM);
-
- /* Notify plugins we are aborting */
- rc_plugin_run (RC_HOOK_ABORT, NULL);
-
- /* Only drop into single user mode if we're booting */
- if ((PREVLEVEL &&
- (strcmp (PREVLEVEL, "S") == 0 ||
- strcmp (PREVLEVEL, "1") == 0)) ||
- (RUNLEVEL &&
- (strcmp (RUNLEVEL, "S") == 0 ||
- strcmp (RUNLEVEL, "1") == 0)))
- single_user ();
-
- exit (EXIT_FAILURE);
- /* NOTREACHED */
+ } while (! WIFEXITED(status) && ! WIFSIGNALED(status));
- default:
- eerror ("%s: caught unknown signal %d", applet, sig);
+ /* Remove that pid from our list */
+ if (pid > 0)
+ remove_pid(pid);
+ break;
+
+ case SIGWINCH:
+ if (rc_logger_tty >= 0) {
+ ioctl(STDIN_FILENO, TIOCGWINSZ, &ws);
+ ioctl(rc_logger_tty, TIOCSWINSZ, &ws);
+ }
+ break;
+
+ case SIGINT:
+ if (! signame[0])
+ snprintf(signame, sizeof(signame), "SIGINT");
+ /* FALLTHROUGH */
+ case SIGTERM:
+ if (! signame[0])
+ snprintf(signame, sizeof(signame), "SIGTERM");
+ /* FALLTHROUGH */
+ case SIGQUIT:
+ if (! signame[0])
+ snprintf(signame, sizeof(signame), "SIGQUIT");
+ eerrorx("%s: caught %s, aborting", applet, signame);
+ /* NOTREACHED */
+ case SIGUSR1:
+ eerror("rc: Aborting!");
+
+ /* Block child signals */
+ sigemptyset(&sset);
+ sigaddset(&sset, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &sset, NULL);
+
+ /* Kill any running services we have started */
+ LIST_FOREACH(pi, &service_pids, entries)
+ kill(pi->pid, SIGTERM);
+
+ /* Notify plugins we are aborting */
+ rc_plugin_run(RC_HOOK_ABORT, NULL);
+
+ /* Only drop into single user mode if we're booting */
+ if ((PREVLEVEL &&
+ (strcmp(PREVLEVEL, "S") == 0 ||
+ strcmp(PREVLEVEL, "1") == 0)) ||
+ (RUNLEVEL &&
+ (strcmp(RUNLEVEL, "S") == 0 ||
+ strcmp(RUNLEVEL, "1") == 0)))
+ single_user();
+
+ exit(EXIT_FAILURE);
+ /* NOTREACHED */
+
+ default:
+ eerror("%s: caught unknown signal %d", applet, sig);
}
/* Restore errno */
errno = serrno;
}
-static void run_script (const char *script)
+static void run_script(const char *script)
{
int status = 0;
- pid_t pid = vfork ();
+ pid_t pid = vfork();
+ pid_t wpid;
if (pid < 0)
- eerrorx ("%s: vfork: %s", applet, strerror (errno));
+ eerrorx("%s: vfork: %s", applet, strerror(errno));
else if (pid == 0) {
- execl (script, script, (char *) NULL);
- eerror ("%s: unable to exec `%s': %s",
- script, applet, strerror (errno));
- _exit (EXIT_FAILURE);
+ execl(script, script, (char *) NULL);
+ eerror("%s: unable to exec `%s': %s",
+ script, applet, strerror(errno));
+ _exit(EXIT_FAILURE);
}
do {
- pid_t wpid = waitpid (pid, &status, 0);
+ wpid = waitpid(pid, &status, 0);
if (wpid < 1)
- eerror ("waitpid: %s", strerror (errno));
- } while (! WIFEXITED (status) && ! WIFSIGNALED (status));
+ eerror("waitpid: %s", strerror(errno));
+ } while (! WIFEXITED(status) && ! WIFSIGNALED(status));
- if (! WIFEXITED (status) || ! WEXITSTATUS (status) == 0)
- eerrorx ("%s: failed to exec `%s'", applet, script);
+ if (! WIFEXITED(status) || ! WEXITSTATUS(status) == 0)
+ eerrorx("%s: failed to exec `%s'", applet, script);
}
-static void do_coldplug (void)
+static void do_coldplug(void)
{
- size_t s;
- int i;
+ size_t l;
DIR *dp;
struct dirent *d;
char *service;
+ RC_STRING *s;
#ifdef BSD
struct ifaddrs *ifap;
struct ifaddrs *ifa;
+ char *p;
#endif
- if (! rc_conf_yesno ("rc_coldplug") && errno != ENOENT)
+ if (! rc_conf_yesno("rc_coldplug") && errno != ENOENT)
return;
/* We need to ensure our state dirs exist.
* We should have a better call than this, but oh well. */
- rc_deptree_update_needed ();
+ rc_deptree_update_needed();
#ifdef BSD
if (getifaddrs(&ifap) == 0) {
@@ -585,33 +564,33 @@ static void do_coldplug (void)
if (ifa->ifa_addr->sa_family != AF_LINK)
continue;
- s = strlen ("net.") + strlen (ifa->ifa_name) + 1;
- tmp = xmalloc (sizeof (char) * s);
- snprintf (tmp, s, "net.%s", ifa->ifa_name);
- if (rc_service_exists (tmp) &&
- service_plugable (tmp))
- rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED);
- CHAR_FREE (tmp);
+ l = strlen("net.") + strlen(ifa->ifa_name) + 1;
+ service = xmalloc(sizeof (char) * l);
+ snprintf(service, l, "net.%s", ifa->ifa_name);
+ if (rc_service_exists(service) &&
+ service_plugable(service))
+ rc_service_mark(service, RC_SERVICE_COLDPLUGGED);
+ free(service);
}
freeifaddrs (ifap);
}
/* The mice are a little more tricky.
* If we coldplug anything else, we'll probably do it here. */
- if ((dp = opendir ("/dev"))) {
- while ((d = readdir (dp))) {
- if (strncmp (d->d_name, "psm", 3) == 0 ||
- strncmp (d->d_name, "ums", 3) == 0)
+ if ((dp = opendir("/dev"))) {
+ while ((d = readdir(dp))) {
+ if (strncmp(d->d_name, "psm", 3) == 0 ||
+ strncmp(d->d_name, "ums", 3) == 0)
{
- char *p = d->d_name + 3;
- if (p && isdigit ((int) *p)) {
- s = strlen ("moused.") + strlen (d->d_name) + 1;
- tmp = xmalloc (sizeof (char) * s);
- snprintf (tmp, s, "moused.%s", d->d_name);
- if (rc_service_exists (tmp) &&
- service_plugable (tmp))
- rc_service_mark (tmp, RC_SERVICE_COLDPLUGGED);
- CHAR_FREE (tmp);
+ p = d->d_name + 3;
+ if (p && isdigit((int) *p)) {
+ l = strlen("moused.") + strlen(d->d_name) + 1;
+ service = xmalloc(sizeof(char) * l);
+ snprintf (service, l, "moused.%s", d->d_name);
+ if (rc_service_exists (service) &&
+ service_plugable (service))
+ rc_service_mark (service, RC_SERVICE_COLDPLUGGED);
+ free(service);
}
}
}
@@ -624,41 +603,57 @@ static void do_coldplug (void)
* its coldplugging thing. runscript knows when we're not ready so it
* stores a list of coldplugged services in DEVBOOT for us to pick up
* here when we are ready for them */
- if ((dp = opendir (DEVBOOT))) {
- while ((d = readdir (dp))) {
+ if ((dp = opendir(DEVBOOT))) {
+ while ((d = readdir(dp))) {
if (d->d_name[0] == '.' &&
(d->d_name[1] == '\0' ||
(d->d_name[1] == '.' && d->d_name[2] == '\0')))
continue;
- if (rc_service_exists (d->d_name) &&
- service_plugable (d->d_name))
- rc_service_mark (d->d_name, RC_SERVICE_COLDPLUGGED);
-
- s = strlen (DEVBOOT "/") + strlen (d->d_name) + 1;
- tmp = xmalloc (sizeof (char) * s);
- snprintf (tmp, s, DEVBOOT "/%s", d->d_name);
- if (tmp) {
- if (unlink (tmp))
- eerror ("%s: unlink `%s': %s", applet, tmp,
- strerror (errno));
- free (tmp);
- }
+ if (rc_service_exists(d->d_name) &&
+ service_plugable(d->d_name))
+ rc_service_mark(d->d_name, RC_SERVICE_COLDPLUGGED);
+
+ l = strlen(DEVBOOT "/") + strlen(d->d_name) + 1;
+ service = xmalloc(sizeof (char) * l);
+ snprintf(service, l, DEVBOOT "/%s", d->d_name);
+ if (unlink(service))
+ eerror("%s: unlink `%s': %s", applet, service,
+ strerror(errno));
+ free(service);
}
- closedir (dp);
- rmdir (DEVBOOT);
+ closedir(dp);
+ rmdir(DEVBOOT);
}
#endif
- if (rc_yesno (getenv ("EINFO_QUIET")))
+ if (rc_yesno(getenv("EINFO_QUIET")))
return;
/* Load our list of coldplugged services and display them */
- einfon ("Device initiated services:%s", ecolor (ECOLOR_HILITE));
- coldplugged_services = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
- STRLIST_FOREACH (coldplugged_services, service, i)
- printf (" %s", service);
- printf ("%s\n", ecolor (ECOLOR_NORMAL));
+ einfon("Device initiated services:%s", ecolor(ECOLOR_HILITE));
+ coldplugged_services = rc_services_in_state(RC_SERVICE_COLDPLUGGED);
+ TAILQ_FOREACH(s, coldplugged_services, entries)
+ printf(" %s", s->value);
+ printf ("%s\n", ecolor(ECOLOR_NORMAL));
+}
+
+static bool runlevel_config(const char *service, const char *level)
+{
+ char *init = rc_service_resolve(service);
+ char *conf;
+ size_t l;
+ bool retval;
+
+ init = dirname(init);
+ init = dirname(init);
+ l = strlen(init) + strlen(level) + strlen(service) + 10;
+ conf = xmalloc(sizeof(char) * l);
+ snprintf(conf, l, "%s/conf.d/%s.%s", init, service, level);
+ retval = exists(conf);
+ free(conf);
+
+ return retval;
}
#include "_usage.h"
@@ -673,16 +668,14 @@ static const char * const longopts_help[] = {
};
#include "_usage.c"
-int main (int argc, char **argv)
+int main(int argc, char **argv)
{
const char *bootlevel = NULL;
- const char *sys = rc_sys ();
+ const char *sys = rc_sys();
char *newlevel = NULL;
- char *service = NULL;
- char **deporder = NULL;
- char **tmplist;
- int i = 0;
- int j = 0;
+ RC_STRINGLIST *deporder = NULL;
+ RC_STRINGLIST *tmplist;
+ RC_STRING *service;
bool going_down = false;
bool interactive = false;
int depoptions = RC_DEP_STRICT | RC_DEP_TRACE;
@@ -692,116 +685,94 @@ int main (int argc, char **argv)
bool parallel;
int regen = 0;
pid_t pid;
+ RC_STRING *svc1;
+ RC_STRING *svc2 = NULL;
+ struct utsname uts;
+#ifdef __linux__
+ char *cmd;
+ char *proc;
+ char *p;
+ char *token;
+#endif
- applet = basename_c (argv[0]);
- atexit (cleanup);
+ applet = basename_c(argv[0]);
+ LIST_INIT(&service_pids);
+ atexit(cleanup);
if (! applet)
- eerrorx ("arguments required");
+ eerrorx("arguments required");
- if (argc > 1 && (strcmp (argv[1], "--version") == 0)) {
- printf ("%s (OpenRC", applet);
+ if (argc > 1 && (strcmp(argv[1], "--version") == 0)) {
+ printf("%s (OpenRC", applet);
if (sys)
- printf (" [%s]", sys);
- printf (") " VERSION
+ printf(" [%s]", sys);
+ printf(") " VERSION
#ifdef BRANDING
- " (" BRANDING ")"
+ " (" BRANDING ")"
#endif
- "\n");
- exit (EXIT_SUCCESS);
+ "\n");
+ exit(EXIT_SUCCESS);
}
/* Run our built in applets. If we ran one, we don't return. */
- run_applets (argc, argv);
+ run_applets(argc, argv);
argc--;
argv++;
/* Change dir to / to ensure all scripts don't use stuff in pwd */
- chdir ("/");
+ chdir("/");
/* RUNLEVEL is set by sysvinit as is a magic number
* RC_SOFTLEVEL is set by us and is the name for this magic number
* even though all our userland documentation refers to runlevel */
- RUNLEVEL = getenv ("RUNLEVEL");
- PREVLEVEL = getenv ("PREVLEVEL");
+ RUNLEVEL = getenv("RUNLEVEL");
+ PREVLEVEL = getenv("PREVLEVEL");
/* Ensure our environment is pure
* Also, add our configuration to it */
- env = env_filter ();
- tmplist = env_config ();
- rc_strlist_join (&env, tmplist);
- rc_strlist_free (tmplist);
-
- if (env) {
- char *p;
-
-#ifdef __linux__
- /* clearenv isn't portable, but there's no harm in using it
- * if we have it */
- clearenv ();
-#else
- char *var;
- /* No clearenv present here then.
- * We could manipulate environ directly ourselves, but it seems that
- * some kernels bitch about this according to the environ man pages
- * so we walk though environ and call unsetenv for each value. */
- while (environ[0]) {
- tmp = xstrdup (environ[0]);
- p = tmp;
- var = strsep (&p, "=");
- unsetenv (var);
- free (tmp);
- }
- tmp = NULL;
-#endif
-
- STRLIST_FOREACH (env, p, i)
- if (strcmp (p, "RC_SOFTLEVEL") != 0 && strcmp (p, "SOFTLEVEL") != 0)
- putenv (p);
-
- /* We don't free our list as that would be null in environ */
- }
+ env_filter();
+ env_config();
argc++;
argv--;
- while ((opt = getopt_long (argc, argv, getoptstring,
- longopts, (int *) 0)) != -1)
+ while ((opt = getopt_long(argc, argv, getoptstring,
+ longopts, (int *) 0)) != -1)
{
switch (opt) {
- case 'o':
- if (*optarg == '\0')
- optarg = NULL;
- exit (set_ksoftlevel (optarg) ? EXIT_SUCCESS : EXIT_FAILURE);
- /* NOTREACHED */
- case_RC_COMMON_GETOPT
+ case 'o':
+ if (*optarg == '\0')
+ optarg = NULL;
+ exit(set_ksoftlevel(optarg) ? EXIT_SUCCESS : EXIT_FAILURE);
+ /* NOTREACHED */
+ case_RC_COMMON_GETOPT
}
}
newlevel = argv[optind++];
/* Enable logging */
- setenv ("EINFO_LOG", "rc", 1);
+ setenv("EINFO_LOG", "rc", 1);
/* Export our PID */
- snprintf (pidstr, sizeof (pidstr), "%d", getpid ());
- setenv ("RC_PID", pidstr, 1);
+ snprintf(pidstr, sizeof(pidstr), "%d", getpid());
+ setenv("RC_PID", pidstr, 1);
/* Load current softlevel */
- bootlevel = getenv ("RC_BOOTLEVEL");
- runlevel = rc_runlevel_get ();
+ bootlevel = getenv("RC_BOOTLEVEL");
+ runlevel = rc_runlevel_get();
- rc_logger_open (newlevel ? newlevel : runlevel);
+ rc_logger_open(newlevel ? newlevel : runlevel);
/* Setup a signal handler */
- signal_setup (SIGINT, handle_signal);
- signal_setup (SIGQUIT, handle_signal);
- signal_setup (SIGTERM, handle_signal);
- signal_setup (SIGUSR1, handle_signal);
- signal_setup (SIGWINCH, handle_signal);
-
- if (! rc_yesno (getenv ("EINFO_QUIET")))
- interactive = exists (INTERACTIVE);
- rc_plugin_load ();
+ signal_setup(SIGINT, handle_signal);
+ signal_setup(SIGQUIT, handle_signal);
+ signal_setup(SIGTERM, handle_signal);
+ signal_setup(SIGUSR1, handle_signal);
+ signal_setup(SIGWINCH, handle_signal);
+
+ if (! rc_yesno(getenv("EINFO_QUIET")))
+ interactive = exists(INTERACTIVE);
+ rc_plugin_load();
/* Check we're in the runlevel requested, ie from
* rc single
@@ -809,450 +780,417 @@ int main (int argc, char **argv)
* rc reboot
*/
if (newlevel) {
- if (strcmp (newlevel, RC_LEVEL_SYSINIT) == 0
+ if (strcmp(newlevel, RC_LEVEL_SYSINIT) == 0
#ifndef PREFIX
&& RUNLEVEL &&
- (strcmp (RUNLEVEL, "S") == 0 ||
- strcmp (RUNLEVEL, "1") == 0)
+ (strcmp(RUNLEVEL, "S") == 0 ||
+ strcmp(RUNLEVEL, "1") == 0)
#endif
- )
+ )
{
-
- struct utsname uts;
/* OK, we're either in runlevel 1 or single user mode */
-#ifdef __linux__
- char *cmd;
-#endif
/* exec init-early.sh if it exists
* This should just setup the console to use the correct
* font. Maybe it should setup the keyboard too? */
- if (exists (INITEARLYSH))
- run_script (INITEARLYSH);
+ if (exists(INITEARLYSH))
+ run_script(INITEARLYSH);
- uname (&uts);
- printf ("\n %sOpenRC %s" VERSION "%s is starting up %s",
- ecolor (ECOLOR_GOOD), ecolor (ECOLOR_HILITE),
- ecolor (ECOLOR_NORMAL), ecolor (ECOLOR_BRACKET));
+ uname(&uts);
+ printf("\n %sOpenRC %s" VERSION "%s is starting up %s",
+ ecolor(ECOLOR_GOOD), ecolor(ECOLOR_HILITE),
+ ecolor(ECOLOR_NORMAL), ecolor(ECOLOR_BRACKET));
#ifdef BRANDING
- printf (BRANDING " (%s)", uts.machine);
+ printf(BRANDING " (%s)", uts.machine);
#else
- printf ("%s %s (%s)",
- uts.sysname,
- uts.release,
- uts.machine);
+ printf("%s %s (%s)",
+ uts.sysname,
+ uts.release,
+ uts.machine);
#endif
if (sys)
- printf (" [%s]", sys);
+ printf(" [%s]", sys);
- printf ("%s\n\n", ecolor (ECOLOR_NORMAL));
+ printf("%s\n\n", ecolor(ECOLOR_NORMAL));
- if (! rc_yesno (getenv ("EINFO_QUIET")) &&
- rc_conf_yesno ("rc_interactive"))
- printf ("Press %sI%s to enter interactive boot mode\n\n",
- ecolor (ECOLOR_GOOD), ecolor (ECOLOR_NORMAL));
+ if (! rc_yesno(getenv ("EINFO_QUIET")) &&
+ rc_conf_yesno("rc_interactive"))
+ printf("Press %sI%s to enter interactive boot mode\n\n",
+ ecolor(ECOLOR_GOOD), ecolor(ECOLOR_NORMAL));
- setenv ("RC_SOFTLEVEL", newlevel, 1);
- rc_plugin_run (RC_HOOK_RUNLEVEL_START_IN, newlevel);
+ setenv("RC_SOFTLEVEL", newlevel, 1);
+ rc_plugin_run(RC_HOOK_RUNLEVEL_START_IN, newlevel);
hook_out = RC_HOOK_RUNLEVEL_START_OUT;
- run_script (INITSH);
+ run_script(INITSH);
#ifdef __linux__
/* If we requested a softlevel, save it now */
- set_ksoftlevel (NULL);
- if ((cmd = proc_getent ("softlevel"))) {
- set_ksoftlevel (cmd);
- free (cmd);
+ set_ksoftlevel(NULL);
+ if ((cmd = proc_getent("softlevel"))) {
+ set_ksoftlevel(cmd);
+ free(cmd);
}
#endif
/* Setup our coldplugged services now */
- do_coldplug ();
+ do_coldplug();
- rc_plugin_run (RC_HOOK_RUNLEVEL_START_OUT, newlevel);
+ rc_plugin_run(RC_HOOK_RUNLEVEL_START_OUT, newlevel);
hook_out = 0;
- if (want_interactive ())
- mark_interactive ();
+ if (want_interactive())
+ mark_interactive();
- exit (EXIT_SUCCESS);
- } else if (strcmp (newlevel, RC_LEVEL_SINGLE) == 0) {
+ exit(EXIT_SUCCESS);
+ } else if (strcmp(newlevel, RC_LEVEL_SINGLE) == 0) {
#ifndef PREFIX
if (! RUNLEVEL ||
- (strcmp (RUNLEVEL, "S") != 0 &&
- strcmp (RUNLEVEL, "1") != 0))
+ (strcmp(RUNLEVEL, "S") != 0 &&
+ strcmp(RUNLEVEL, "1") != 0))
{
/* Remember the current runlevel for when we come back */
- set_ksoftlevel (runlevel);
- single_user ();
+ set_ksoftlevel(runlevel);
+ single_user();
}
#endif
- } else if (strcmp (newlevel, RC_LEVEL_REBOOT) == 0) {
+ } else if (strcmp(newlevel, RC_LEVEL_REBOOT) == 0) {
if (! RUNLEVEL ||
- strcmp (RUNLEVEL, "6") != 0)
+ strcmp(RUNLEVEL, "6") != 0)
{
- rc_logger_close ();
- execl (SHUTDOWN, SHUTDOWN, "-r", "now", (char *) NULL);
- eerrorx ("%s: unable to exec `" SHUTDOWN "': %s",
- applet, strerror (errno));
+ rc_logger_close();
+ execl(SHUTDOWN, SHUTDOWN, "-r", "now", (char *) NULL);
+ eerrorx("%s: unable to exec `" SHUTDOWN "': %s",
+ applet, strerror(errno));
}
- } else if (strcmp (newlevel, RC_LEVEL_SHUTDOWN) == 0) {
+ } else if (strcmp(newlevel, RC_LEVEL_SHUTDOWN) == 0) {
if (! RUNLEVEL ||
- strcmp (RUNLEVEL, "0") != 0)
+ strcmp(RUNLEVEL, "0") != 0)
{
- rc_logger_close ();
- execl (SHUTDOWN, SHUTDOWN,
+ rc_logger_close();
+ execl(SHUTDOWN, SHUTDOWN,
#ifdef __linux__
- "-h",
+ "-h",
#else
- "-p",
+ "-p",
#endif
- "now", (char *) NULL);
- eerrorx ("%s: unable to exec `" SHUTDOWN "': %s",
- applet, strerror (errno));
+ "now", (char *) NULL);
+ eerrorx("%s: unable to exec `" SHUTDOWN "': %s",
+ applet, strerror(errno));
}
}
}
/* Now we start handling our children */
- signal_setup (SIGCHLD, handle_signal);
+ signal_setup(SIGCHLD, handle_signal);
/* We should only use ksoftlevel if we were in single user mode
* If not, we need to erase ksoftlevel now. */
if (PREVLEVEL &&
- (strcmp (PREVLEVEL, "1") == 0 ||
- strcmp (PREVLEVEL, "S") == 0 ||
- strcmp (PREVLEVEL, "N") == 0))
+ (strcmp(PREVLEVEL, "1") == 0 ||
+ strcmp(PREVLEVEL, "S") == 0 ||
+ strcmp(PREVLEVEL, "N") == 0))
{
/* Try not to join boot and ksoftlevels together */
if (! newlevel ||
- strcmp (newlevel, getenv ("RC_BOOTLEVEL")) != 0)
- if (get_ksoftlevel (ksoftbuffer, sizeof (ksoftbuffer)))
+ strcmp(newlevel, getenv("RC_BOOTLEVEL")) != 0)
+ if (get_ksoftlevel(ksoftbuffer, sizeof(ksoftbuffer)))
newlevel = ksoftbuffer;
} else if (! RUNLEVEL ||
- (strcmp (RUNLEVEL, "1") != 0 &&
- strcmp (RUNLEVEL, "S") != 0 &&
- strcmp (RUNLEVEL, "N") != 0))
+ (strcmp(RUNLEVEL, "1") != 0 &&
+ strcmp(RUNLEVEL, "S") != 0 &&
+ strcmp(RUNLEVEL, "N") != 0))
{
- set_ksoftlevel (NULL);
+ set_ksoftlevel(NULL);
}
if (newlevel &&
- (strcmp (newlevel, RC_LEVEL_REBOOT) == 0 ||
- strcmp (newlevel, RC_LEVEL_SHUTDOWN) == 0 ||
- strcmp (newlevel, RC_LEVEL_SINGLE) == 0))
+ (strcmp(newlevel, RC_LEVEL_REBOOT) == 0 ||
+ strcmp(newlevel, RC_LEVEL_SHUTDOWN) == 0 ||
+ strcmp(newlevel, RC_LEVEL_SINGLE) == 0))
{
going_down = true;
- rc_runlevel_set (newlevel);
- setenv ("RC_SOFTLEVEL", newlevel, 1);
+ rc_runlevel_set(newlevel);
+ setenv("RC_RUNLEVEL", newlevel, 1);
#ifdef __FreeBSD__
/* FIXME: we shouldn't have todo this */
/* For some reason, wait_for_services waits for the logger proccess
* to finish as well, but only on FreeBSD. We cannot allow this so
* we stop logging now. */
- rc_logger_close ();
+ rc_logger_close();
#endif
- rc_plugin_run (RC_HOOK_RUNLEVEL_STOP_IN, newlevel);
+ rc_plugin_run(RC_HOOK_RUNLEVEL_STOP_IN, newlevel);
} else {
- rc_plugin_run (RC_HOOK_RUNLEVEL_STOP_IN, runlevel);
+ rc_plugin_run(RC_HOOK_RUNLEVEL_STOP_IN, runlevel);
}
hook_out = RC_HOOK_RUNLEVEL_STOP_OUT;
/* Check if runlevel is valid if we're changing */
- if (newlevel && strcmp (runlevel, newlevel) != 0 && ! going_down) {
- if (! rc_runlevel_exists (newlevel))
+ if (newlevel && strcmp(runlevel, newlevel) != 0 && ! going_down) {
+ if (! rc_runlevel_exists(newlevel))
eerrorx ("%s: is not a valid runlevel", newlevel);
}
/* Load our deptree */
- if ((deptree = _rc_deptree_load (&regen)) == NULL)
- eerrorx ("failed to load deptree");
+ if ((deptree = _rc_deptree_load(&regen)) == NULL)
+ eerrorx("failed to load deptree");
/* Clean the failed services state dir */
- clean_failed ();
+ clean_failed();
- if (mkdir (RC_STOPPING, 0755) != 0) {
+ if (mkdir(RC_STOPPING, 0755) != 0) {
if (errno == EACCES)
- eerrorx ("%s: superuser access required", applet);
- eerrorx ("%s: failed to create stopping dir: %s",
- applet, strerror (errno));
+ eerrorx("%s: superuser access required", applet);
+ eerrorx("%s: failed to create stopping dir `%s': %s",
+ applet, RC_STOPPING, strerror(errno));
}
/* Build a list of all services to stop and then work out the
* correct order for stopping them */
- stop_services = rc_services_in_state (RC_SERVICE_STARTING);
-
- tmplist = rc_services_in_state (RC_SERVICE_INACTIVE);
- rc_strlist_join (&stop_services, tmplist);
- rc_strlist_free (tmplist);
-
- tmplist = rc_services_in_state (RC_SERVICE_STARTED);
- rc_strlist_join (&stop_services, tmplist);
- rc_strlist_free (tmplist);
-
- deporder = rc_deptree_depends (deptree, types_nua,
- (const char **) stop_services,
- runlevel, depoptions | RC_DEP_STOP);
-
- rc_strlist_free (stop_services);
- stop_services = deporder;
- deporder = NULL;
- rc_strlist_reverse (stop_services);
+ stop_services = rc_services_in_state(RC_SERVICE_STARTED);
+ tmplist = rc_services_in_state(RC_SERVICE_INACTIVE);
+ TAILQ_CONCAT(stop_services, tmplist);
+ free(tmplist);
+ tmplist = rc_services_in_state(RC_SERVICE_STARTING);
+ TAILQ_CONCAT(stop_services, tmplist);
+ free(tmplist);
+ rc_stringlist_sort(&stop_services);
+
+ types_n = rc_stringlist_new();
+ rc_stringlist_add(types_n, "needsme");
+
+ types_nua = rc_stringlist_new();
+ rc_stringlist_add(types_nua, "ineed");
+ rc_stringlist_add(types_nua, "iuse");
+ rc_stringlist_add(types_nua, "iafter");
+
+ tmplist = rc_deptree_depends(deptree, types_nua, stop_services,
+ runlevel, depoptions | RC_DEP_STOP);
+ rc_stringlist_free(stop_services);
+ stop_services = tmplist;
/* Load our list of coldplugged services */
- coldplugged_services = rc_services_in_state (RC_SERVICE_COLDPLUGGED);
- if (strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SINGLE) != 0 &&
- strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_SHUTDOWN) != 0 &&
- strcmp (newlevel ? newlevel : runlevel, RC_LEVEL_REBOOT) != 0)
+ coldplugged_services = rc_services_in_state(RC_SERVICE_COLDPLUGGED);
+ if (strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_SINGLE) != 0 &&
+ strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_SHUTDOWN) != 0 &&
+ strcmp(newlevel ? newlevel : runlevel, RC_LEVEL_REBOOT) != 0)
{
/* We need to include the boot runlevel services if we're not in it */
- start_services = rc_services_in_runlevel (bootlevel);
+ start_services = rc_services_in_runlevel(bootlevel);
if (strcmp (newlevel ? newlevel : runlevel, bootlevel) != 0) {
- tmplist = rc_services_in_runlevel (newlevel ? newlevel : runlevel);
- rc_strlist_join (&start_services, tmplist);
- rc_strlist_free (tmplist);
+ tmplist = rc_services_in_runlevel(newlevel ? newlevel : runlevel);
+ TAILQ_CONCAT(start_services, tmplist);
+ free(tmplist);
}
- STRLIST_FOREACH (coldplugged_services, service, i)
- rc_strlist_add (&start_services, service);
+ TAILQ_FOREACH(service, coldplugged_services, entries)
+ rc_stringlist_addu(start_services, service->value);
}
/* Save our softlevel now */
if (going_down)
- rc_runlevel_set (newlevel);
+ rc_runlevel_set(newlevel);
- parallel = rc_conf_yesno ("rc_parallel");
+ parallel = rc_conf_yesno("rc_parallel");
/* Now stop the services that shouldn't be running */
- STRLIST_FOREACH (stop_services, service, i) {
- bool found = false;
- char *conf = NULL;
- char **stopdeps = NULL;
- char *svc1 = NULL;
- char *svc2 = NULL;
- int k;
-
- if (rc_service_state (service) & RC_SERVICE_STOPPED)
+ TAILQ_FOREACH_REVERSE(service, stop_services, rc_stringlist, entries) {
+ if (rc_service_state(service->value) & RC_SERVICE_STOPPED)
continue;
/* We always stop the service when in these runlevels */
if (going_down) {
- pid = rc_service_stop (service);
+ pid = rc_service_stop(service->value);
if (pid > 0 && ! parallel)
- rc_waitpid (pid);
+ rc_waitpid(pid);
continue;
}
/* If we're in the start list then don't bother stopping us */
- STRLIST_FOREACH (start_services, svc1, j)
- if (strcmp (svc1, service) == 0) {
- found = true;
+ TAILQ_FOREACH(svc1, start_services, entries)
+ if (strcmp (svc1->value, service->value) == 0)
break;
- }
- /* Unless we would use a different config file */
- if (found) {
- size_t len;
- if (! newlevel)
- continue;
-
- len = strlen (service) + strlen (runlevel) + 2;
- tmp = xmalloc (sizeof (char) * len);
- snprintf (tmp, len, "%s.%s", service, runlevel);
- conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL);
- found = exists (conf);
- CHAR_FREE (conf);
- CHAR_FREE (tmp);
- if (! found) {
- len = strlen (service) + strlen (newlevel) + 2;
- tmp = xmalloc (sizeof (char) * len);
- snprintf (tmp, len, "%s.%s", service, newlevel);
- conf = rc_strcatpaths (RC_CONFDIR, tmp, (char *) NULL);
- found = exists (conf);
- CHAR_FREE (conf);
- CHAR_FREE (tmp);
- if (!found)
+ if (svc1) {
+ if (newlevel && strcmp(runlevel, newlevel) != 0) {
+ /* So we're in the start list. But we should
+ * be stopped if we have a runlevel
+ * configuration file for either the current
+ * or next so we use the correct one. */
+ if (! runlevel_config(service->value, runlevel) &&
+ ! runlevel_config(service->value, newlevel))
continue;
}
- } else {
- /* Allow coldplugged services not to be in the runlevels list */
- if (rc_service_state (service) & RC_SERVICE_COLDPLUGGED)
+ else
continue;
}
- /* We got this far! Or last check is to see if any any service that
- * going to be started depends on us */
- rc_strlist_add (&stopdeps, service);
- deporder = rc_deptree_depends (deptree, types_n,
- (const char **) stopdeps,
- runlevel, RC_DEP_STRICT);
- rc_strlist_free (stopdeps);
- stopdeps = NULL;
- found = false;
- STRLIST_FOREACH (deporder, svc1, j) {
- STRLIST_FOREACH (start_services, svc2, k)
- if (strcmp (svc1, svc2) == 0) {
- found = true;
+ /* We got this far! Or last check is to see if any any service
+ * that going to be started depends on us */
+ if (! svc1) {
+ tmplist = rc_stringlist_new();
+ rc_stringlist_add(tmplist, service->value);
+ deporder = rc_deptree_depends(deptree, types_n, tmplist,
+ runlevel, RC_DEP_STRICT);
+ rc_stringlist_free(tmplist);
+ svc2 = NULL;
+ TAILQ_FOREACH (svc1, deporder, entries) {
+ TAILQ_FOREACH(svc2, start_services, entries)
+ if (strcmp (svc1->value, svc2->value) == 0)
+ break;
+ if (svc2)
break;
- }
- if (found)
- break;
+ }
+ rc_stringlist_free(deporder);
+
+ if (svc2)
+ continue;
}
- rc_strlist_free (deporder);
- deporder = NULL;
/* After all that we can finally stop the blighter! */
- if (! found) {
- pid = rc_service_stop (service);
-
- if (pid > 0) {
- add_pid (pid);
- if (! parallel) {
- rc_waitpid (pid);
- remove_pid (pid);
- }
+ pid = rc_service_stop(service->value);
+ if (pid > 0) {
+ add_pid(pid);
+ if (! parallel) {
+ rc_waitpid(pid);
+ remove_pid(pid);
}
}
}
/* Wait for our services to finish */
- wait_for_services ();
+ wait_for_services();
/* Notify the plugins we have finished */
- rc_plugin_run (RC_HOOK_RUNLEVEL_STOP_OUT, runlevel);
+ rc_plugin_run(RC_HOOK_RUNLEVEL_STOP_OUT, runlevel);
hook_out = 0;
- rmdir (RC_STOPPING);
+ rmdir(RC_STOPPING);
/* Store the new runlevel */
if (newlevel) {
- rc_runlevel_set (newlevel);
- free (runlevel);
- runlevel = xstrdup (newlevel);
- setenv ("RC_SOFTLEVEL", runlevel, 1);
+ rc_runlevel_set(newlevel);
+ free(runlevel);
+ runlevel = xstrdup(newlevel);
+ setenv("RC_RUNLEVEL", runlevel, 1);
}
/* Run the halt script if needed */
- if (strcmp (runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
- strcmp (runlevel, RC_LEVEL_REBOOT) == 0)
+ if (strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
+ strcmp(runlevel, RC_LEVEL_REBOOT) == 0)
{
- rc_logger_close ();
- execl (HALTSH, HALTSH, runlevel, (char *) NULL);
- eerrorx ("%s: unable to exec `%s': %s",
- applet, HALTSH, strerror (errno));
+ rc_logger_close();
+ execl(HALTSH, HALTSH, runlevel, (char *) NULL);
+ eerrorx("%s: unable to exec `%s': %s",
+ applet, HALTSH, strerror(errno));
}
/* Single user is done now */
- if (strcmp (runlevel, RC_LEVEL_SINGLE) == 0) {
- if (exists (INTERACTIVE))
- unlink (INTERACTIVE);
- sulogin (false);
+ if (strcmp(runlevel, RC_LEVEL_SINGLE) == 0) {
+ if (exists(INTERACTIVE))
+ unlink(INTERACTIVE);
+ sulogin(false);
}
- mkdir (RC_STARTING, 0755);
- rc_plugin_run (RC_HOOK_RUNLEVEL_START_IN, runlevel);
+ mkdir(RC_STARTING, 0755);
+ rc_plugin_run(RC_HOOK_RUNLEVEL_START_IN, runlevel);
hook_out = RC_HOOK_RUNLEVEL_START_OUT;
/* Re-add our coldplugged services if they stopped */
- STRLIST_FOREACH (coldplugged_services, service, i)
- rc_service_mark (service, RC_SERVICE_COLDPLUGGED);
+ TAILQ_FOREACH(service, coldplugged_services, entries)
+ rc_service_mark(service->value, RC_SERVICE_COLDPLUGGED);
/* Order the services to start */
- deporder = rc_deptree_depends (deptree, types_nua,
- (const char **) start_services,
- runlevel, depoptions | RC_DEP_START);
- rc_strlist_free (start_services);
+ rc_stringlist_sort(&start_services);
+ deporder = rc_deptree_depends(deptree, types_nua, start_services,
+ runlevel, depoptions | RC_DEP_START);
+ rc_stringlist_free(start_services);
start_services = deporder;
- deporder = NULL;
#ifdef __linux__
/* mark any services skipped as started */
- if (PREVLEVEL && strcmp (PREVLEVEL, "N") == 0) {
- if ((service = proc_getent ("noinitd"))) {
- char *p = service;
- char *token;
-
- while ((token = strsep (&p, ",")))
- rc_service_mark (token, RC_SERVICE_STARTED);
- free (service);
+ if (PREVLEVEL && strcmp(PREVLEVEL, "N") == 0) {
+ proc = p = proc_getent("noinitd");
+ if (proc) {
+ while ((token = strsep(&p, ",")))
+ rc_service_mark(token, RC_SERVICE_STARTED);
+ free(proc);
}
}
#endif
- STRLIST_FOREACH (start_services, service, i) {
- if (rc_service_state (service) & RC_SERVICE_STOPPED) {
+ TAILQ_FOREACH(service, start_services, entries) {
+ if (rc_service_state(service->value) & RC_SERVICE_STOPPED) {
if (! interactive)
- interactive = want_interactive ();
+ interactive = want_interactive();
if (interactive) {
interactive_retry:
- printf ("\n");
- einfo ("About to start the service %s", service);
- eindent ();
- einfo ("1) Start the service\t\t2) Skip the service");
- einfo ("3) Continue boot process\t\t4) Exit to shell");
- eoutdent ();
+ printf("\n");
+ einfo("About to start the service %s",
+ service->value);
+ eindent();
+ einfo("1) Start the service\t\t2) Skip the service");
+ einfo("3) Continue boot process\t\t4) Exit to shell");
+ eoutdent();
interactive_option:
- switch (read_key (true)) {
- case '1': break;
- case '2': continue;
- case '3': interactive = false; break;
- case '4': sulogin (true); goto interactive_retry;
- default: goto interactive_option;
+ switch (read_key(true)) {
+ case '1': break;
+ case '2': continue;
+ case '3': interactive = false; break;
+ case '4': sulogin(true); goto interactive_retry;
+ default: goto interactive_option;
}
}
- pid = rc_service_start (service);
+ pid = rc_service_start(service->value);
/* Remember the pid if we're running in parallel */
if (pid > 0) {
- add_pid (pid);
+ add_pid(pid);
if (! parallel) {
- rc_waitpid (pid);
- remove_pid (pid);
+ rc_waitpid(pid);
+ remove_pid(pid);
}
}
}
}
/* Wait for our services to finish */
- wait_for_services ();
+ wait_for_services();
- rc_plugin_run (RC_HOOK_RUNLEVEL_START_OUT, runlevel);
+ rc_plugin_run(RC_HOOK_RUNLEVEL_START_OUT, runlevel);
hook_out = 0;
#ifdef __linux__
/* mark any services skipped as stopped */
- if (PREVLEVEL && strcmp (PREVLEVEL, "N") == 0) {
- if ((service = proc_getent ("noinitd"))) {
- char *p = service;
- char *token;
-
- while ((token = strsep (&p, ",")))
- rc_service_mark (token, RC_SERVICE_STOPPED);
- free (service);
+ if (PREVLEVEL && strcmp(PREVLEVEL, "N") == 0) {
+ proc = p = proc_getent("noinitd");
+ if (proc) {
+ while ((token = strsep(&p, ",")))
+ rc_service_mark(token, RC_SERVICE_STOPPED);
+ free(proc);
}
}
#endif
/* Store our interactive status for boot */
- if (interactive && strcmp (runlevel, bootlevel) == 0)
- mark_interactive ();
+ if (interactive && strcmp(runlevel, bootlevel) == 0)
+ mark_interactive();
else {
- if (exists (INTERACTIVE))
- unlink (INTERACTIVE);
+ if (exists(INTERACTIVE))
+ unlink(INTERACTIVE);
}
/* If we're in the boot runlevel and we regenerated our dependencies
* we need to delete them so that they are regenerated again in the
* default runlevel as they may depend on things that are now available */
- if (regen && strcmp (runlevel, bootlevel) == 0)
- unlink (RC_DEPTREE);
+ if (regen && strcmp(runlevel, bootlevel) == 0)
+ unlink(RC_DEPTREE_CACHE);
- return (EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
diff --git a/src/rc/runscript.c b/src/rc/runscript.c
index ef9a3e2..cfc2611 100644
--- a/src/rc/runscript.c
+++ b/src/rc/runscript.c
@@ -34,6 +34,7 @@
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/stat.h>
+
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
@@ -60,11 +61,10 @@
#include "rc.h"
#include "rc-misc.h"
#include "rc-plugin.h"
-#include "strlist.h"
#define SELINUX_LIB RC_LIBDIR "/runscript_selinux.so"
-#define PREFIX_LOCK RC_SVCDIR "/prefix.lock"
+#define PREFIX_LOCK RC_SVCDIR "/prefix.lock"
/* usecs to wait while we poll the fifo */
#define WAIT_INTERVAL 20000000
@@ -75,192 +75,187 @@
#define ONE_SECOND 1000000000
static const char *applet = NULL;
-static char **applet_list = NULL;
+static RC_STRINGLIST *applet_list = NULL;
+static RC_STRINGLIST *restart_services = NULL;
+static RC_STRINGLIST *need_services = NULL;
+static RC_STRINGLIST *use_services = NULL;
+static RC_STRINGLIST *services = NULL;
+static RC_STRINGLIST *tmplist = NULL;
static char *service = NULL;
static char *exclusive = NULL;
static char *mtime_test = NULL;
-static rc_depinfo_t *deptree = NULL;
-static char **services = NULL;
-static char **tmplist = NULL;
-static char **providelist = NULL;
-static char **restart_services = NULL;
-static char **need_services = NULL;
-static char **use_services = NULL;
-static char **env = NULL;
-static char *tmp = NULL;
-static char *softlevel = NULL;
+static RC_DEPTREE *deptree = NULL;
+static char *runlevel = NULL;
static bool sighup = false;
static char *ibsave = NULL;
static bool in_background = false;
-static rc_hook_t hook_out = 0;
+static RC_HOOK hook_out = 0;
static pid_t service_pid = 0;
static char *prefix = NULL;
static bool prefix_locked = false;
static int signal_pipe[2] = { -1, -1 };
static int master_tty = -1;
-extern char **environ;
-
-static const char *const types_b[] = { "broken", NULL };
-static const char *const types_n[] = { "ineed", NULL };
-static const char *const types_nu[] = { "ineed", "iuse", NULL };
-static const char *const types_nua[] = { "ineed", "iuse", "iafter", NULL };
-
-static const char *const types_m[] = { "needsme", NULL };
-static const char *const types_mua[] = { "needsme", "usesme", "beforeme", NULL };
+static RC_STRINGLIST *types_b = NULL;
+static RC_STRINGLIST *types_n = NULL;
+static RC_STRINGLIST *types_nu = NULL;
+static RC_STRINGLIST *types_nua = NULL;
+static RC_STRINGLIST *types_m = NULL;
+static RC_STRINGLIST *types_mua = NULL;
#ifdef __linux__
-static void (*selinux_run_init_old) (void);
-static void (*selinux_run_init_new) (int argc, char **argv);
+static void (*selinux_run_init_old)(void);
+static void (*selinux_run_init_new)(int argc, char **argv);
-static void setup_selinux (int argc, char **argv);
+static void setup_selinux(int argc, char **argv);
-static void setup_selinux (int argc, char **argv)
+static void setup_selinux(int argc, char **argv)
{
void *lib_handle = NULL;
- if (! exists (SELINUX_LIB))
+ if (! exists(SELINUX_LIB))
return;
- lib_handle = dlopen (SELINUX_LIB, RTLD_NOW | RTLD_GLOBAL);
+ lib_handle = dlopen(SELINUX_LIB, RTLD_NOW | RTLD_GLOBAL);
if (! lib_handle) {
- eerror ("dlopen: %s", dlerror ());
+ eerror("dlopen: %s", dlerror());
return;
}
selinux_run_init_old = (void (*)(void))
- dlfunc (lib_handle, "selinux_runscript");
+ dlfunc(lib_handle, "selinux_runscript");
selinux_run_init_new = (void (*)(int, char **))
- dlfunc (lib_handle, "selinux_runscript2");
+ dlfunc(lib_handle, "selinux_runscript2");
/* Use new run_init if it exists, else fall back to old */
if (selinux_run_init_new)
- selinux_run_init_new (argc, argv);
+ selinux_run_init_new(argc, argv);
else if (selinux_run_init_old)
- selinux_run_init_old ();
+ selinux_run_init_old();
else
/* This shouldnt happen... probably corrupt lib */
- eerrorx ("run_init is missing from runscript_selinux.so!");
+ eerrorx("run_init is missing from runscript_selinux.so!");
- dlclose (lib_handle);
+ dlclose(lib_handle);
}
#endif
-static void handle_signal (int sig)
+static void handle_signal(int sig)
{
int serrno = errno;
char signame[10] = { '\0' };
struct winsize ws;
switch (sig) {
- case SIGHUP:
- sighup = true;
- break;
-
- case SIGCHLD:
- if (signal_pipe[1] > -1) {
- if (write (signal_pipe[1], &sig, sizeof (sig)) == -1)
- eerror ("%s: send: %s", service, strerror (errno));
- } else
- rc_waitpid (-1);
- break;
-
- case SIGWINCH:
- if (master_tty >= 0) {
- ioctl (fileno (stdout), TIOCGWINSZ, &ws);
- ioctl (master_tty, TIOCSWINSZ, &ws);
- }
- break;
+ case SIGHUP:
+ sighup = true;
+ break;
+
+ case SIGCHLD:
+ if (signal_pipe[1] > -1) {
+ if (write(signal_pipe[1], &sig, sizeof(sig)) == -1)
+ eerror("%s: send: %s", service, strerror(errno));
+ } else
+ rc_waitpid (-1);
+ break;
- case SIGINT:
- if (! signame[0])
- snprintf (signame, sizeof (signame), "SIGINT");
- /* FALLTHROUGH */
- case SIGTERM:
- if (! signame[0])
- snprintf (signame, sizeof (signame), "SIGTERM");
- /* FALLTHROUGH */
- case SIGQUIT:
- if (! signame[0])
- snprintf (signame, sizeof (signame), "SIGQUIT");
- /* Send the signal to our children too */
- if (service_pid > 0)
- kill (service_pid, sig);
- eerrorx ("%s: caught %s, aborting", applet, signame);
- /* NOTREACHED */
-
- default:
- eerror ("%s: caught unknown signal %d", applet, sig);
+ case SIGWINCH:
+ if (master_tty >= 0) {
+ ioctl(fileno(stdout), TIOCGWINSZ, &ws);
+ ioctl(master_tty, TIOCSWINSZ, &ws);
+ }
+ break;
+
+ case SIGINT:
+ if (! signame[0])
+ snprintf(signame, sizeof(signame), "SIGINT");
+ /* FALLTHROUGH */
+ case SIGTERM:
+ if (! signame[0])
+ snprintf(signame, sizeof(signame), "SIGTERM");
+ /* FALLTHROUGH */
+ case SIGQUIT:
+ if (! signame[0])
+ snprintf(signame, sizeof(signame), "SIGQUIT");
+ /* Send the signal to our children too */
+ if (service_pid > 0)
+ kill(service_pid, sig);
+ eerrorx("%s: caught %s, aborting", applet, signame);
+ /* NOTREACHED */
+
+ default:
+ eerror("%s: caught unknown signal %d", applet, sig);
}
/* Restore errno */
errno = serrno;
}
-static time_t get_mtime (const char *pathname, bool follow_link)
+static time_t get_mtime(const char *pathname, bool follow_link)
{
struct stat buf;
int retval;
if (! pathname)
- return (0);
+ return 0;
- retval = follow_link ? stat (pathname, &buf) : lstat (pathname, &buf);
+ retval = follow_link ? stat(pathname, &buf) : lstat(pathname, &buf);
if (! retval)
- return (buf.st_mtime);
+ return buf.st_mtime;
errno = 0;
- return (0);
+ return 0;
}
-static bool in_control ()
+static const char *const tests[] = {
+ "starting", "started", "stopping", "inactive", "wasinactive", NULL
+};
+static bool in_control()
{
char *path;
+ time_t m;
time_t mtime;
- const char *tests[] = { "starting", "started", "stopping",
- "inactive", "wasinactive", NULL };
int i = 0;
if (sighup)
- return (false);
+ return false;
- if (! mtime_test || ! exists (mtime_test))
- return (false);
+ if (! mtime_test || ! exists(mtime_test))
+ return false;
- if (rc_service_state (applet) & RC_SERVICE_STOPPED)
- return (false);
+ if (rc_service_state(applet) & RC_SERVICE_STOPPED)
+ return false;
- if (! (mtime = get_mtime (mtime_test, false)))
- return (false);
+ if (! (mtime = get_mtime(mtime_test, false)))
+ return false;
while (tests[i]) {
- path = rc_strcatpaths (RC_SVCDIR, tests[i], applet, (char *) NULL);
- if (exists (path)) {
- time_t m = get_mtime (path, false);
+ path = rc_strcatpaths(RC_SVCDIR, tests[i], applet, (char *) NULL);
+ if (exists(path)) {
+ m = get_mtime(path, false);
if (mtime < m && m != 0) {
- free (path);
- return (false);
+ free(path);
+ return false;
}
}
- free (path);
+ free(path);
i++;
}
- return (true);
+ return true;
}
-static void uncoldplug ()
+static void uncoldplug()
{
- char *cold = rc_strcatpaths (RC_SVCDIR, "coldplugged", applet, (char *) NULL);
- if (exists (cold) && unlink (cold) != 0)
- eerror ("%s: unlink `%s': %s", applet, cold, strerror (errno));
- free (cold);
+ char *cold = rc_strcatpaths(RC_SVCDIR, "coldplugged", applet, (char *) NULL);
+ if (exists(cold) && unlink(cold) != 0)
+ eerror("%s: unlink `%s': %s", applet, cold, strerror(errno));
+ free(cold);
}
-static void start_services (char **list) {
- char *svc;
- int i;
- rc_service_state_t state = rc_service_state (service);
+static void start_services(RC_STRINGLIST *list) {
+ RC_STRING *svc;
+ RC_SERVICE state = rc_service_state (service);
if (! list)
return;
@@ -270,102 +265,107 @@ static void start_services (char **list) {
state & RC_SERVICE_STARTING ||
state & RC_SERVICE_STARTED)
{
- STRLIST_FOREACH (list, svc, i) {
- if (rc_service_state (svc) & RC_SERVICE_STOPPED) {
+ TAILQ_FOREACH(svc, list, entries) {
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED) {
if (state & RC_SERVICE_INACTIVE ||
state & RC_SERVICE_WASINACTIVE)
{
- rc_service_schedule_start (service, svc);
- ewarn ("WARNING: %s is scheduled to started when %s has started",
- svc, applet);
+ rc_service_schedule_start(service, svc->value);
+ ewarn("WARNING: %s is scheduled to started"
+ " when %s has started",
+ svc->value, applet);
} else
- rc_service_start (svc);
+ rc_service_start(svc->value);
}
}
}
}
-static void restore_state (void)
+static void restore_state(void)
{
- rc_service_state_t state;
+ RC_SERVICE state;
- if (rc_in_plugin || ! in_control ())
+ if (rc_in_plugin || ! in_control())
return;
- state = rc_service_state (applet);
+ state = rc_service_state(applet);
if (state & RC_SERVICE_STOPPING) {
-
if (state & RC_SERVICE_WASINACTIVE)
- rc_service_mark (applet, RC_SERVICE_INACTIVE);
+ rc_service_mark(applet, RC_SERVICE_INACTIVE);
else
- rc_service_mark (applet, RC_SERVICE_STARTED);
- if (rc_runlevel_stopping ())
- rc_service_mark (applet, RC_SERVICE_FAILED);
+ rc_service_mark(applet, RC_SERVICE_STARTED);
+ if (rc_runlevel_stopping())
+ rc_service_mark(applet, RC_SERVICE_FAILED);
} else if (state & RC_SERVICE_STARTING) {
if (state & RC_SERVICE_WASINACTIVE)
- rc_service_mark (applet, RC_SERVICE_INACTIVE);
+ rc_service_mark(applet, RC_SERVICE_INACTIVE);
else
- rc_service_mark (applet, RC_SERVICE_STOPPED);
- if (rc_runlevel_starting ())
- rc_service_mark (applet, RC_SERVICE_FAILED);
+ rc_service_mark(applet, RC_SERVICE_STOPPED);
+ if (rc_runlevel_starting())
+ rc_service_mark(applet, RC_SERVICE_FAILED);
}
if (exclusive)
- unlink (exclusive);
- free (exclusive);
+ unlink(exclusive);
+ free(exclusive);
exclusive = NULL;
}
-static void cleanup (void)
+static void cleanup(void)
{
- restore_state ();
+ restore_state();
if (! rc_in_plugin) {
if (prefix_locked)
- unlink (PREFIX_LOCK);
+ unlink(PREFIX_LOCK);
if (hook_out) {
- rc_plugin_run (hook_out, applet);
+ rc_plugin_run(hook_out, applet);
if (hook_out == RC_HOOK_SERVICE_START_DONE)
- rc_plugin_run (RC_HOOK_SERVICE_START_OUT, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_START_OUT, applet);
else if (hook_out == RC_HOOK_SERVICE_STOP_DONE)
- rc_plugin_run (RC_HOOK_SERVICE_STOP_OUT, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT, applet);
}
if (restart_services)
- start_services (restart_services);
+ start_services(restart_services);
}
- rc_plugin_unload ();
- rc_deptree_free (deptree);
- rc_strlist_free (services);
- rc_strlist_free (providelist);
- rc_strlist_free (need_services);
- rc_strlist_free (use_services);
- rc_strlist_free (restart_services);
- rc_strlist_free (applet_list);
- rc_strlist_free (tmplist);
+ rc_stringlist_free(types_b);
+ rc_stringlist_free(types_n);
+ rc_stringlist_free(types_nu);
+ rc_stringlist_free(types_nua);
+ rc_stringlist_free(types_m);
+ rc_stringlist_free(types_mua);
+
+ rc_plugin_unload();
+ rc_deptree_free(deptree);
+
+ rc_stringlist_free(restart_services);
+ rc_stringlist_free(need_services);
+ rc_stringlist_free(use_services);
+ rc_stringlist_free(services);
+ rc_stringlist_free(applet_list);
+ rc_stringlist_free(tmplist);
free (ibsave);
- rc_strlist_free (env);
-
if (mtime_test)
{
if (! rc_in_plugin)
- unlink (mtime_test);
- free (mtime_test);
+ unlink(mtime_test);
+ free(mtime_test);
}
- free (exclusive);
- free (service);
- free (prefix);
- free (softlevel);
+ free(exclusive);
+ free(service);
+ free(prefix);
+ free(runlevel);
}
-static int write_prefix (const char *buffer, size_t bytes, bool *prefixed) {
+static int write_prefix(const char *buffer, size_t bytes, bool *prefixed) {
unsigned int i;
- const char *ec = ecolor (ECOLOR_HILITE);
- const char *ec_normal = ecolor (ECOLOR_NORMAL);
+ const char *ec = ecolor(ECOLOR_HILITE);
+ const char *ec_normal = ecolor(ECOLOR_NORMAL);
ssize_t ret = 0;
- int fd = fileno (stdout);
+ int fd = fileno(stdout);
for (i = 0; i < bytes; i++) {
/* We don't prefix escape codes, like eend */
@@ -373,25 +373,25 @@ static int write_prefix (const char *buffer, size_t bytes, bool *prefixed) {
*prefixed = true;
if (! *prefixed) {
- ret += write (fd, ec, strlen (ec));
- ret += write (fd, prefix, strlen (prefix));
- ret += write (fd, ec_normal, strlen (ec_normal));
- ret += write (fd, "|", 1);
+ ret += write(fd, ec, strlen(ec));
+ ret += write(fd, prefix, strlen(prefix));
+ ret += write(fd, ec_normal, strlen(ec_normal));
+ ret += write(fd, "|", 1);
*prefixed = true;
}
if (buffer[i] == '\n')
*prefixed = false;
- ret += write (fd, buffer + i, 1);
+ ret += write(fd, buffer + i, 1);
}
- return (ret);
+ return ret;
}
-static bool svc_exec (const char *arg1, const char *arg2)
+static bool svc_exec(const char *arg1, const char *arg2)
{
bool execok;
- int fdout = fileno (stdout);
+ int fdout = fileno(stdout);
struct termios tt;
struct winsize ws;
int i;
@@ -405,12 +405,12 @@ static bool svc_exec (const char *arg1, const char *arg2)
int slave_tty;
/* Setup our signal pipe */
- if (pipe (signal_pipe) == -1)
- eerrorx ("%s: pipe: %s", service, applet);
+ if (pipe(signal_pipe) == -1)
+ eerrorx("%s: pipe: %s", service, applet);
for (i = 0; i < 2; i++)
- if ((flags = fcntl (signal_pipe[i], F_GETFD, 0) == -1 ||
- fcntl (signal_pipe[i], F_SETFD, flags | FD_CLOEXEC) == -1))
- eerrorx ("%s: fcntl: %s", service, strerror (errno));
+ if ((flags = fcntl(signal_pipe[i], F_GETFD, 0) == -1 ||
+ fcntl(signal_pipe[i], F_SETFD, flags | FD_CLOEXEC) == -1))
+ eerrorx("%s: fcntl: %s", service, strerror(errno));
/* Open a pty for our prefixed output
* We do this instead of mapping pipes to stdout, stderr so that
@@ -418,127 +418,125 @@ static bool svc_exec (const char *arg1, const char *arg2)
* The only loss is that we can no longer tell the difference
* between the childs stdout or stderr */
master_tty = slave_tty = -1;
- if (prefix && isatty (fdout)) {
- tcgetattr (fdout, &tt);
- ioctl (fdout, TIOCGWINSZ, &ws);
+ if (prefix && isatty(fdout)) {
+ tcgetattr(fdout, &tt);
+ ioctl(fdout, TIOCGWINSZ, &ws);
/* If the below call fails due to not enough ptys then we don't
* prefix the output, but we still work */
- openpty (&master_tty, &slave_tty, NULL, &tt, &ws);
+ openpty(&master_tty, &slave_tty, NULL, &tt, &ws);
if (master_tty >= 0 &&
- (flags = fcntl (master_tty, F_GETFD, 0)) == 0)
- fcntl (master_tty, F_SETFD, flags | FD_CLOEXEC);
+ (flags = fcntl(master_tty, F_GETFD, 0)) == 0)
+ fcntl(master_tty, F_SETFD, flags | FD_CLOEXEC);
if (slave_tty >=0 &&
- (flags = fcntl (slave_tty, F_GETFD, 0)) == 0)
- fcntl (slave_tty, F_SETFD, flags | FD_CLOEXEC);
+ (flags = fcntl(slave_tty, F_GETFD, 0)) == 0)
+ fcntl(slave_tty, F_SETFD, flags | FD_CLOEXEC);
}
service_pid = fork();
if (service_pid == -1)
- eerrorx ("%s: fork: %s", service, strerror (errno));
+ eerrorx("%s: fork: %s", service, strerror(errno));
if (service_pid == 0) {
if (slave_tty >= 0) {
- dup2 (slave_tty, 1);
- dup2 (slave_tty, 2);
+ dup2(slave_tty, 1);
+ dup2(slave_tty, 2);
}
- if (exists (RC_SVCDIR "/runscript.sh")) {
- execl (RC_SVCDIR "/runscript.sh", RC_SVCDIR "/runscript.sh",
- service, arg1, arg2, (char *) NULL);
- eerror ("%s: exec `" RC_SVCDIR "/runscript.sh': %s",
- service, strerror (errno));
- _exit (EXIT_FAILURE);
+ if (exists(RC_SVCDIR "/runscript.sh")) {
+ execl(RC_SVCDIR "/runscript.sh", RC_SVCDIR "/runscript.sh",
+ service, arg1, arg2, (char *) NULL);
+ eerror("%s: exec `" RC_SVCDIR "/runscript.sh': %s",
+ service, strerror(errno));
+ _exit(EXIT_FAILURE);
} else {
- execl (RC_LIBDIR "/sh/runscript.sh", RC_LIBDIR "/sh/runscript.sh",
- service, arg1, arg2, (char *) NULL);
- eerror ("%s: exec `" RC_LIBDIR "/sh/runscript.sh': %s",
- service, strerror (errno));
- _exit (EXIT_FAILURE);
+ execl(RC_LIBDIR "/sh/runscript.sh", RC_LIBDIR "/sh/runscript.sh",
+ service, arg1, arg2, (char *) NULL);
+ eerror("%s: exec `" RC_LIBDIR "/sh/runscript.sh': %s",
+ service, strerror(errno));
+ _exit(EXIT_FAILURE);
}
}
- selfd = MAX (master_tty, signal_pipe[0]) + 1;
- buffer = xmalloc (sizeof (char) * BUFSIZ);
+ selfd = MAX(master_tty, signal_pipe[0]) + 1;
+ buffer = xmalloc(sizeof(char) * BUFSIZ);
for (;;) {
- FD_ZERO (&rset);
- FD_SET (signal_pipe[0], &rset);
+ FD_ZERO(&rset);
+ FD_SET(signal_pipe[0], &rset);
if (master_tty >= 0)
- FD_SET (master_tty, &rset);
+ FD_SET(master_tty, &rset);
- if ((s = select (selfd, &rset, NULL, NULL, NULL)) == -1) {
+ if ((s = select(selfd, &rset, NULL, NULL, NULL)) == -1) {
if (errno != EINTR) {
- eerror ("%s: select: %s", service, strerror (errno));
+ eerror("%s: select: %s", service, strerror(errno));
break;
}
}
if (s > 0) {
- if (master_tty >= 0 && FD_ISSET (master_tty, &rset)) {
- bytes = read (master_tty, buffer, BUFSIZ);
- write_prefix (buffer, bytes, &prefixed);
+ if (master_tty >= 0 && FD_ISSET(master_tty, &rset)) {
+ bytes = read(master_tty, buffer, BUFSIZ);
+ write_prefix(buffer, bytes, &prefixed);
}
/* Only SIGCHLD signals come down this pipe */
- if (FD_ISSET (signal_pipe[0], &rset))
+ if (FD_ISSET(signal_pipe[0], &rset))
break;
}
}
- free (buffer);
- close (signal_pipe[0]);
- close (signal_pipe[1]);
+ free(buffer);
+ close(signal_pipe[0]);
+ close(signal_pipe[1]);
signal_pipe[0] = signal_pipe[1] = -1;
if (master_tty >= 0) {
/* Why did we do this? */
/* signal (SIGWINCH, SIG_IGN); */
- close (master_tty);
+ close(master_tty);
master_tty = -1;
}
- execok = rc_waitpid (service_pid) == 0 ? true : false;
+ execok = rc_waitpid(service_pid) == 0 ? true : false;
service_pid = 0;
- return (execok);
+ return execok;
}
-static bool svc_wait (rc_depinfo_t *depinfo, const char *svc)
+static bool svc_wait(const char *svc)
{
- char *s;
- char *fifo;
+ char fifo[PATH_MAX];
struct timespec ts;
int nloops = WAIT_MAX * (ONE_SECOND / WAIT_INTERVAL);
bool retval = false;
bool forever = false;
- char **keywords = NULL;
- int i;
-
- if (! service)
- return (false);
+ RC_STRINGLIST *keywords;
+ RC_STRING *s;
/* Some services don't have a timeout, like fsck */
- keywords = rc_deptree_depend (depinfo, svc, "keyword");
- STRLIST_FOREACH (keywords, s, i) {
- if (strcmp (s, "notimeout") == 0) {
- forever = true;
- break;
+ keywords = rc_deptree_depend(deptree, svc, "keyword");
+ if (keywords) {
+ TAILQ_FOREACH(s, keywords, entries) {
+ if (strcmp (s->value, "notimeout") == 0) {
+ forever = true;
+ break;
+ }
}
+ rc_stringlist_free (keywords);
}
- rc_strlist_free (keywords);
- fifo = rc_strcatpaths (RC_SVCDIR, "exclusive", basename_c (svc), (char *) NULL);
+ snprintf(fifo, sizeof(fifo), RC_SVCDIR "/exclusive/%s", basename_c(svc));
ts.tv_sec = 0;
ts.tv_nsec = WAIT_INTERVAL;
while (nloops) {
- if (! exists (fifo)) {
+ if (! exists(fifo)) {
retval = true;
break;
}
- if (nanosleep (&ts, NULL) == -1) {
+ if (nanosleep(&ts, NULL) == -1) {
if (errno != EINTR)
break;
}
@@ -547,190 +545,211 @@ static bool svc_wait (rc_depinfo_t *depinfo, const char *svc)
nloops --;
}
- if (! exists (fifo))
+ if (! exists(fifo))
retval = true;
- free (fifo);
- return (retval);
+ return retval;
}
-static rc_service_state_t svc_status ()
+static RC_SERVICE svc_status(void)
{
char status[10];
int (*e) (const char *fmt, ...) = &einfo;
-
- rc_service_state_t state = rc_service_state (service);
+ RC_SERVICE state = rc_service_state(service);
if (state & RC_SERVICE_STOPPING) {
- snprintf (status, sizeof (status), "stopping");
+ snprintf(status, sizeof(status), "stopping");
e = &ewarn;
} else if (state & RC_SERVICE_STARTING) {
- snprintf (status, sizeof (status), "starting");
+ snprintf(status, sizeof(status), "starting");
e = &ewarn;
} else if (state & RC_SERVICE_INACTIVE) {
- snprintf (status, sizeof (status), "inactive");
+ snprintf(status, sizeof(status), "inactive");
e = &ewarn;
} else if (state & RC_SERVICE_STARTED) {
- if (geteuid () == 0 && rc_service_daemons_crashed (service)) {
- snprintf (status, sizeof (status), "crashed");
+ if (rc_service_daemons_crashed(service)) {
+ snprintf(status, sizeof (status), "crashed");
e = &eerror;
} else
- snprintf (status, sizeof (status), "started");
+ snprintf(status, sizeof(status), "started");
} else
- snprintf (status, sizeof (status), "stopped");
+ snprintf(status, sizeof(status), "stopped");
- e ("status: %s", status);
- return (state);
+ e("status: %s", status);
+ return state;
}
-static void make_exclusive ()
+static void make_exclusive(void)
{
char *path;
size_t l;
/* We create a fifo so that other services can wait until we complete */
if (! exclusive)
- exclusive = rc_strcatpaths (RC_SVCDIR, "exclusive", applet, (char *) NULL);
+ exclusive = rc_strcatpaths(RC_SVCDIR, "exclusive", applet, (char *) NULL);
- if (mkfifo (exclusive, 0600) != 0 && errno != EEXIST &&
+ if (mkfifo(exclusive, 0600) != 0 && errno != EEXIST &&
(errno != EACCES || geteuid () == 0))
eerrorx ("%s: unable to create fifo `%s': %s",
- applet, exclusive, strerror (errno));
+ applet, exclusive, strerror(errno));
- path = rc_strcatpaths (RC_SVCDIR, "exclusive", applet, (char *) NULL);
+ path = rc_strcatpaths(RC_SVCDIR, "exclusive", applet, (char *) NULL);
l = strlen (path) + 16;
- mtime_test = xmalloc (sizeof (char) * l);
- snprintf (mtime_test, l, "%s.%d", path, getpid ());
- free (path);
-
- if (exists (mtime_test) && unlink (mtime_test) != 0) {
- eerror ("%s: unlink `%s': %s",
- applet, mtime_test, strerror (errno));
- free (mtime_test);
+ mtime_test = xmalloc(sizeof (char) * l);
+ snprintf(mtime_test, l, "%s.%d", path, getpid());
+ free(path);
+
+ if (exists(mtime_test) && unlink(mtime_test) != 0) {
+ eerror("%s: unlink `%s': %s",
+ applet, mtime_test, strerror(errno));
+ free(mtime_test);
mtime_test = NULL;
return;
}
- if (symlink (service, mtime_test) != 0) {
- eerror ("%s: symlink `%s' to `%s': %s",
- applet, service, mtime_test, strerror (errno));
- free (mtime_test);
+ if (symlink(service, mtime_test) != 0) {
+ eerror("%s: symlink `%s' to `%s': %s",
+ applet, service, mtime_test, strerror(errno));
+ free(mtime_test);
mtime_test = NULL;
}
}
-static void unlink_mtime_test ()
+static void unlink_mtime_test(void)
{
- if (unlink (mtime_test) != 0)
- eerror ("%s: unlink `%s': %s", applet, mtime_test, strerror (errno));
- free (mtime_test);
+ if (unlink(mtime_test) != 0)
+ eerror("%s: unlink `%s': %s", applet, mtime_test, strerror(errno));
+ free(mtime_test);
mtime_test = NULL;
}
-static void get_started_services ()
+static void get_started_services(void)
+{
+ RC_STRINGLIST *tmp = rc_services_in_state(RC_SERVICE_INACTIVE);
+ rc_stringlist_free(restart_services);
+ restart_services = rc_services_in_state(RC_SERVICE_STARTED);
+ TAILQ_CONCAT(restart_services, tmp);
+ free(tmp);
+}
+
+static void setup_types(void)
{
- rc_strlist_free (tmplist);
- tmplist = rc_services_in_state (RC_SERVICE_INACTIVE);
- rc_strlist_free (restart_services);
- restart_services = rc_services_in_state (RC_SERVICE_STARTED);
- rc_strlist_join (&restart_services, tmplist);
- rc_strlist_free (tmplist);
- tmplist = NULL;
+ types_b = rc_stringlist_new();
+ rc_stringlist_add(types_b, "broken");
+
+ types_n = rc_stringlist_new();
+ rc_stringlist_add(types_n, "ineed");
+
+ types_nu = rc_stringlist_new();
+ rc_stringlist_add(types_nu, "ineed");
+ rc_stringlist_add(types_nu, "iuse");
+
+ types_nua = rc_stringlist_new();
+ rc_stringlist_add(types_nua, "ineed");
+ rc_stringlist_add(types_nua, "iuse");
+ rc_stringlist_add(types_nua, "iafter");
+
+ types_m = rc_stringlist_new();
+ rc_stringlist_add(types_m, "needsme");
+
+ types_mua = rc_stringlist_new();
+ rc_stringlist_add(types_mua, "needsme");
+ rc_stringlist_add(types_mua, "usesme");
+ rc_stringlist_add(types_mua, "beforeme");
}
-static void svc_start (bool deps)
+static void svc_start(bool deps)
{
bool started;
bool background = false;
- char *svc;
- char *svc2;
- int i;
- int j;
+ RC_STRING *svc;
+ RC_STRING *svc2;
int depoptions = RC_DEP_TRACE;
- rc_service_state_t state;
+ RC_SERVICE state;
+ bool first;
+ int n;
+ size_t len;
+ char *p;
+ char *tmp;
- state = rc_service_state (service);
+ state = rc_service_state(service);
- if (rc_yesno (getenv ("IN_HOTPLUG")) || in_background) {
+ if (rc_yesno(getenv("IN_HOTPLUG")) || in_background) {
if (! state & RC_SERVICE_INACTIVE &&
! state & RC_SERVICE_STOPPED)
- exit (EXIT_FAILURE);
+ exit(EXIT_FAILURE);
background = true;
}
if (state & RC_SERVICE_STARTED) {
- ewarn ("WARNING: %s has already been started", applet);
+ ewarn("WARNING: %s has already been started", applet);
return;
} else if (state & RC_SERVICE_STARTING)
- ewarnx ("WARNING: %s is already starting", applet);
+ ewarnx("WARNING: %s is already starting", applet);
else if (state & RC_SERVICE_STOPPING)
- ewarnx ("WARNING: %s is stopping", applet);
+ ewarnx("WARNING: %s is stopping", applet);
else if (state & RC_SERVICE_INACTIVE && ! background)
- ewarnx ("WARNING: %s has already started, but is inactive", applet);
+ ewarnx("WARNING: %s has already started, but is inactive", applet);
- if (! rc_service_mark (service, RC_SERVICE_STARTING)) {
+ if (! rc_service_mark(service, RC_SERVICE_STARTING)) {
if (errno == EACCES)
- eerrorx ("%s: superuser access required", applet);
- eerrorx ("ERROR: %s has been started by something else", applet);
+ eerrorx("%s: superuser access required", applet);
+ eerrorx("ERROR: %s has been started by something else", applet);
}
- make_exclusive (service);
+ make_exclusive();
hook_out = RC_HOOK_SERVICE_START_OUT;
- rc_plugin_run (RC_HOOK_SERVICE_START_IN, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_START_IN, applet);
- if (rc_conf_yesno ("rc_depend_strict"))
+ if (rc_conf_yesno("rc_depend_strict"))
depoptions |= RC_DEP_STRICT;
if (deps) {
if (! deptree && ((deptree = _rc_deptree_load (NULL)) == NULL))
- eerrorx ("failed to load deptree");
+ eerrorx("failed to load deptree");
- rc_strlist_free (services);
- services = rc_deptree_depends (deptree, types_b,
- (const char * const *) applet_list,
- softlevel, 0);
- if (services) {
+ if (! types_b)
+ setup_types();
+
+ services = rc_deptree_depends(deptree, types_b, applet_list,
+ runlevel, 0);
+ if (TAILQ_FIRST(services)) {
eerrorn ("ERROR: `%s' needs ", applet);
- STRLIST_FOREACH (services, svc, i) {
- if (i > 0)
- fprintf (stderr, ", ");
- fprintf (stderr, "%s", svc);
+ first = true;
+ TAILQ_FOREACH(svc, services, entries) {
+ if (first)
+ first = false;
+ else
+ fprintf(stderr, ", ");
+ fprintf(stderr, "%s", svc->value);
}
- exit (EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
- rc_strlist_free (services);
+ rc_stringlist_free(services);
services = NULL;
- rc_strlist_free (need_services);
- need_services = rc_deptree_depends (deptree, types_n,
- (const char * const *) applet_list,
- softlevel, depoptions);
-
- rc_strlist_free (use_services);
- use_services = rc_deptree_depends (deptree, types_nu,
- (const char * const *) applet_list,
- softlevel, depoptions);
-
- if (! rc_runlevel_starting ()) {
- STRLIST_FOREACH (use_services, svc, i)
- if (rc_service_state (svc) & RC_SERVICE_STOPPED) {
- pid_t pid = rc_service_start (svc);
- if (! rc_conf_yesno ("rc_parallel"))
- rc_waitpid (pid);
+ need_services = rc_deptree_depends(deptree, types_n, applet_list,
+ runlevel, depoptions);
+ use_services = rc_deptree_depends(deptree, types_nu, applet_list,
+ runlevel, depoptions);
+
+ if (! rc_runlevel_starting())
+ TAILQ_FOREACH(svc, use_services, entries)
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED) {
+ pid_t pid = rc_service_start(svc->value);
+ if (! rc_conf_yesno("rc_parallel"))
+ rc_waitpid(pid);
}
- }
/* Now wait for them to start */
- services = rc_deptree_depends (deptree, types_nua,
- (const char * const *) applet_list,
- softlevel, depoptions);
+ services = rc_deptree_depends(deptree, types_nua, applet_list,
+ runlevel, depoptions);
/* We use tmplist to hold our scheduled by list */
- rc_strlist_free (tmplist);
- tmplist = NULL;
+ tmplist = rc_stringlist_new();
- STRLIST_FOREACH (services, svc, i) {
- rc_service_state_t svcs = rc_service_state (svc);
+ TAILQ_FOREACH(svc, services, entries) {
+ RC_SERVICE svcs = rc_service_state(svc->value);
if (svcs & RC_SERVICE_STARTED)
continue;
@@ -738,270 +757,272 @@ static void svc_start (bool deps)
* starting state which we are after */
if (svcs & RC_SERVICE_STARTING &&
svcs & RC_SERVICE_WASINACTIVE) {
- bool use = false;
- STRLIST_FOREACH (use_services, svc2, j)
- if (strcmp (svc, svc2) == 0) {
- use = true;
+ TAILQ_FOREACH(svc2, use_services, entries) {
+ if (strcmp (svc->value, svc2->value) == 0)
break;
}
- if (! use)
+ if (! svc2)
continue;
}
- if (! svc_wait (deptree, svc))
- eerror ("%s: timed out waiting for %s", applet, svc);
- if ((svcs = rc_service_state (svc)) & RC_SERVICE_STARTED)
+ if (! svc_wait(svc->value))
+ eerror ("%s: timed out waiting for %s",
+ applet, svc->value);
+ if ((svcs = rc_service_state(svc->value)) & RC_SERVICE_STARTED)
continue;
-
- STRLIST_FOREACH (need_services, svc2, j)
- if (strcmp (svc, svc2) == 0) {
+ TAILQ_FOREACH(svc2, need_services, entries) {
+ if (strcmp (svc->value, svc2->value) == 0) {
if (svcs & RC_SERVICE_INACTIVE ||
svcs & RC_SERVICE_WASINACTIVE)
- rc_strlist_add (&tmplist, svc);
+ rc_stringlist_add(tmplist, svc->value);
else
- eerrorx ("ERROR: cannot start %s as %s would not start",
- applet, svc);
+ eerrorx("ERROR: cannot start %s as"
+ " %s would not start",
+ applet, svc->value);
}
+ }
}
- if (tmplist) {
- int n = 0;
- size_t len = 0;
- char *p;
-
+ if (TAILQ_FIRST(tmplist)) {
/* Set the state now, then unlink our exclusive so that
our scheduled list is preserved */
- rc_service_mark (service, RC_SERVICE_STOPPED);
- unlink_mtime_test ();
-
- STRLIST_FOREACH (tmplist, svc, i) {
- rc_service_schedule_start (svc, service);
- rc_strlist_free (providelist);
- providelist = rc_deptree_depend (deptree, "iprovide", svc);
- STRLIST_FOREACH (providelist, svc2, j)
- rc_service_schedule_start (svc2, service);
-
- len += strlen (svc) + 2;
+ rc_service_mark(service, RC_SERVICE_STOPPED);
+ unlink_mtime_test();
+
+ rc_stringlist_free(use_services);
+ use_services = NULL;
+ len = 0;
+ n = 0;
+ TAILQ_FOREACH(svc, tmplist, entries) {
+ rc_service_schedule_start(svc->value, service);
+ use_services = rc_deptree_depend(deptree, "iprovide",
+ svc->value);
+ TAILQ_FOREACH (svc2, use_services, entries)
+ rc_service_schedule_start(svc2->value, service);
+ rc_stringlist_free(use_services);
+ use_services = NULL;
+ len += strlen(svc->value) + 2;
n++;
}
len += 5;
- tmp = xmalloc (sizeof (char) * len);
- p = tmp;
- STRLIST_FOREACH (tmplist, svc, i) {
- if (i > 1) {
- if (i == n)
- p += snprintf (p, len, " or ");
- else
- p += snprintf (p, len, ", ");
- }
- p += snprintf (p, len, "%s", svc);
+ tmp = p = xmalloc(sizeof(char) * len);
+ TAILQ_FOREACH(svc, tmplist, entries) {
+ if (p != tmp)
+ p += snprintf(p, len, ", ");
+ p += snprintf(p, len, "%s", svc->value);
}
- ewarnx ("WARNING: %s is scheduled to start when %s has started",
- applet, tmp);
+ free(tmp);
+ ewarnx("WARNING: %s is scheduled to start when %s has started",
+ applet, tmp);
}
- rc_strlist_free (services);
+ rc_stringlist_free(services);
services = NULL;
+ rc_stringlist_free(tmplist);
+ tmplist = NULL;
}
if (ibsave)
- setenv ("IN_BACKGROUND", ibsave, 1);
+ setenv("IN_BACKGROUND", ibsave, 1);
hook_out = RC_HOOK_SERVICE_START_DONE;
- rc_plugin_run (RC_HOOK_SERVICE_START_NOW, applet);
- started = svc_exec ("start", NULL);
+ rc_plugin_run(RC_HOOK_SERVICE_START_NOW, applet);
+ started = svc_exec("start", NULL);
if (ibsave)
- unsetenv ("IN_BACKGROUND");
+ unsetenv("IN_BACKGROUND");
- if (in_control ()) {
+ if (in_control()) {
if (! started)
- eerrorx ("ERROR: %s failed to start", applet);
+ eerrorx("ERROR: %s failed to start", applet);
} else {
- if (rc_service_state (service) & RC_SERVICE_INACTIVE)
- ewarnx ("WARNING: %s has started, but is inactive", applet);
+ if (rc_service_state(service) & RC_SERVICE_INACTIVE)
+ ewarnx("WARNING: %s has started, but is inactive", applet);
else
- ewarnx ("WARNING: %s not under our control, aborting", applet);
+ ewarnx("WARNING: %s not under our control, aborting", applet);
}
- rc_service_mark (service, RC_SERVICE_STARTED);
- unlink_mtime_test ();
+ rc_service_mark(service, RC_SERVICE_STARTED);
+ unlink_mtime_test();
hook_out = RC_HOOK_SERVICE_START_OUT;
- rc_plugin_run (RC_HOOK_SERVICE_START_DONE, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_START_DONE, applet);
if (exclusive)
- unlink (exclusive);
+ unlink(exclusive);
/* Now start any scheduled services */
- rc_strlist_free (services);
- services = rc_services_scheduled (service);
- STRLIST_FOREACH (services, svc, i)
- if (rc_service_state (svc) & RC_SERVICE_STOPPED)
- rc_service_start (svc);
- rc_strlist_free (services);
- services = NULL;
+ services = rc_services_scheduled(service);
+ if (services) {
+ TAILQ_FOREACH(svc, services, entries)
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
+ rc_service_start(svc->value);
+ rc_stringlist_free(services);
+ services = NULL;
+ }
/* Do the same for any services we provide */
- rc_strlist_free (tmplist);
- tmplist = rc_deptree_depend (deptree, "iprovide", applet);
-
- STRLIST_FOREACH (tmplist, svc2, j) {
- rc_strlist_free (services);
- services = rc_services_scheduled (svc2);
- STRLIST_FOREACH (services, svc, i)
- if (rc_service_state (svc) & RC_SERVICE_STOPPED)
- rc_service_start (svc);
+ tmplist = rc_deptree_depend(deptree, "iprovide", applet);
+ if (tmplist) {
+ TAILQ_FOREACH(svc, tmplist, entries) {
+ services = rc_services_scheduled(svc->value);
+ if (services) {
+ TAILQ_FOREACH(svc2, services, entries)
+ if (rc_service_state(svc2->value) & RC_SERVICE_STOPPED)
+ rc_service_start(svc2->value);
+ rc_stringlist_free(services);
+ services = NULL;
+ }
+ }
+ rc_stringlist_free(tmplist);
+ tmplist = NULL;
}
hook_out = 0;
- rc_plugin_run (RC_HOOK_SERVICE_START_OUT, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_START_OUT, applet);
}
-static void svc_stop (bool deps)
+static void svc_stop(bool deps)
{
bool stopped;
- rc_service_state_t state = rc_service_state (service);
+ RC_SERVICE state = rc_service_state(service);
+ int depoptions = RC_DEP_TRACE;
+ RC_STRING *svc;
- if (rc_runlevel_stopping () &&
+ if (rc_runlevel_stopping() &&
state & RC_SERVICE_FAILED)
exit (EXIT_FAILURE);
- if (rc_yesno (getenv ("IN_HOTPLUG")) || in_background)
+ if (rc_yesno(getenv("IN_HOTPLUG")) || in_background)
if (! (state & RC_SERVICE_STARTED) &&
! (state & RC_SERVICE_INACTIVE))
exit (EXIT_FAILURE);
if (state & RC_SERVICE_STOPPED) {
- ewarn ("WARNING: %s is already stopped", applet);
+ ewarn("WARNING: %s is already stopped", applet);
return;
} else if (state & RC_SERVICE_STOPPING)
- ewarnx ("WARNING: %s is already stopping", applet);
+ ewarnx("WARNING: %s is already stopping", applet);
- if (! rc_service_mark (service, RC_SERVICE_STOPPING)) {
+ if (! rc_service_mark(service, RC_SERVICE_STOPPING)) {
if (errno == EACCES)
- eerrorx ("%s: superuser access required", applet);
- eerrorx ("ERROR: %s has been stopped by something else", applet);
+ eerrorx("%s: superuser access required", applet);
+ eerrorx("ERROR: %s has been stopped by something else", applet);
}
- make_exclusive (service);
+ make_exclusive();
hook_out = RC_HOOK_SERVICE_STOP_OUT;
- rc_plugin_run (RC_HOOK_SERVICE_STOP_IN, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_STOP_IN, applet);
- if (! rc_runlevel_stopping () &&
- rc_service_in_runlevel (service, RC_LEVEL_BOOT))
+ if (! rc_runlevel_stopping() &&
+ rc_service_in_runlevel(service, RC_LEVEL_BOOT))
ewarn ("WARNING: you are stopping a boot service");
if (deps && ! (state & RC_SERVICE_WASINACTIVE)) {
- int depoptions = RC_DEP_TRACE;
- char *svc;
- int i;
- if (rc_conf_yesno ("rc_depend_strict"))
+ if (rc_conf_yesno("rc_depend_strict"))
depoptions |= RC_DEP_STRICT;
- if (! deptree && ((deptree = _rc_deptree_load (NULL)) == NULL))
+ if (! deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))
eerrorx ("failed to load deptree");
- rc_strlist_free (tmplist);
- tmplist = NULL;
- rc_strlist_free (services);
- services = rc_deptree_depends (deptree, types_m,
- (const char * const *) applet_list,
- softlevel, depoptions);
- rc_strlist_reverse (services);
- STRLIST_FOREACH (services, svc, i) {
- rc_service_state_t svcs = rc_service_state (svc);
+ if (! types_m)
+ setup_types();
+
+ tmplist = rc_stringlist_new();
+ services = rc_deptree_depends(deptree, types_m, applet_list,
+ runlevel, depoptions);
+ TAILQ_FOREACH_REVERSE(svc, services, rc_stringlist, entries) {
+ RC_SERVICE svcs = rc_service_state(svc->value);
if (svcs & RC_SERVICE_STARTED ||
svcs & RC_SERVICE_INACTIVE)
{
- svc_wait (deptree, svc);
- svcs = rc_service_state (svc);
+ svc_wait(svc->value);
+ svcs = rc_service_state(svc->value);
if (svcs & RC_SERVICE_STARTED ||
svcs & RC_SERVICE_INACTIVE)
{
- pid_t pid = rc_service_stop (svc);
- if (! rc_conf_yesno ("rc_parallel"))
- rc_waitpid (pid);
- rc_strlist_add (&tmplist, svc);
+ pid_t pid = rc_service_stop(svc->value);
+ if (! rc_conf_yesno("rc_parallel"))
+ rc_waitpid(pid);
+ rc_stringlist_add(tmplist, svc->value);
}
}
}
- rc_strlist_free (services);
+ rc_stringlist_free(services);
services = NULL;
- STRLIST_FOREACH (tmplist, svc, i) {
- if (rc_service_state (svc) & RC_SERVICE_STOPPED)
+ TAILQ_FOREACH(svc, tmplist, entries) {
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
continue;
/* We used to loop 3 times here - maybe re-do this if needed */
- svc_wait (deptree, svc);
- if (! (rc_service_state (svc) & RC_SERVICE_STOPPED)) {
- if (rc_runlevel_stopping ()) {
- /* If shutting down, we should stop even if a dependant failed */
- if (softlevel &&
- (strcmp (softlevel, RC_LEVEL_SHUTDOWN) == 0 ||
- strcmp (softlevel, RC_LEVEL_REBOOT) == 0 ||
- strcmp (softlevel, RC_LEVEL_SINGLE) == 0))
+ svc_wait(svc->value);
+ if (! (rc_service_state(svc->value) & RC_SERVICE_STOPPED)) {
+ if (rc_runlevel_stopping()) {
+ /* If shutting down, we should stop even
+ * if a dependant failed */
+ if (runlevel &&
+ (strcmp(runlevel, RC_LEVEL_SHUTDOWN) == 0 ||
+ strcmp(runlevel, RC_LEVEL_REBOOT) == 0 ||
+ strcmp(runlevel, RC_LEVEL_SINGLE) == 0))
continue;
- rc_service_mark (service, RC_SERVICE_FAILED);
+ rc_service_mark(service, RC_SERVICE_FAILED);
}
- eerrorx ("ERROR: cannot stop %s as %s is still up",
- applet, svc);
+ eerrorx("ERROR: cannot stop %s as %s is still up",
+ applet, svc->value);
}
}
- rc_strlist_free (tmplist);
+ rc_stringlist_free(tmplist);
tmplist = NULL;
/* We now wait for other services that may use us and are stopping
This is important when a runlevel stops */
- services = rc_deptree_depends (deptree, types_mua,
- (const char * const *) applet_list,
- softlevel, depoptions);
- STRLIST_FOREACH (services, svc, i) {
- if (rc_service_state (svc) & RC_SERVICE_STOPPED)
+ services = rc_deptree_depends(deptree, types_mua, applet_list,
+ runlevel, depoptions);
+ TAILQ_FOREACH(svc, services, entries) {
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
continue;
- svc_wait (deptree, svc);
+ svc_wait(svc->value);
}
-
- rc_strlist_free (services);
+ rc_stringlist_free (services);
services = NULL;
}
/* If we're stopping localmount, set LC_ALL=C so that
* bash doesn't load anything blocking the unmounting of /usr */
- if (strcmp (applet, "localmount") == 0)
- setenv ("LC_ALL", "C", 1);
+ if (strcmp(applet, "localmount") == 0)
+ setenv("LC_ALL", "C", 1);
if (ibsave)
- setenv ("IN_BACKGROUND", ibsave, 1);
+ setenv("IN_BACKGROUND", ibsave, 1);
hook_out = RC_HOOK_SERVICE_STOP_DONE;
- rc_plugin_run (RC_HOOK_SERVICE_STOP_NOW, applet);
- stopped = svc_exec ("stop", NULL);
+ rc_plugin_run(RC_HOOK_SERVICE_STOP_NOW, applet);
+ stopped = svc_exec("stop", NULL);
if (ibsave)
- unsetenv ("IN_BACKGROUND");
+ unsetenv("IN_BACKGROUND");
- if (! in_control ())
- ewarnx ("WARNING: %s not under our control, aborting", applet);
+ if (! in_control())
+ ewarnx("WARNING: %s not under our control, aborting", applet);
if (! stopped)
- eerrorx ("ERROR: %s failed to stop", applet);
+ eerrorx("ERROR: %s failed to stop", applet);
if (in_background)
- rc_service_mark (service, RC_SERVICE_INACTIVE);
+ rc_service_mark(service, RC_SERVICE_INACTIVE);
else
- rc_service_mark (service, RC_SERVICE_STOPPED);
+ rc_service_mark(service, RC_SERVICE_STOPPED);
- unlink_mtime_test ();
+ unlink_mtime_test();
hook_out = RC_HOOK_SERVICE_STOP_OUT;
- rc_plugin_run (RC_HOOK_SERVICE_STOP_DONE, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_STOP_DONE, applet);
if (exclusive)
- unlink (exclusive);
+ unlink(exclusive);
hook_out = 0;
- rc_plugin_run (RC_HOOK_SERVICE_STOP_OUT, applet);
+ rc_plugin_run(RC_HOOK_SERVICE_STOP_OUT, applet);
}
-static void svc_restart (bool deps)
+static void svc_restart(bool deps)
{
/* This is hairly and a better way needs to be found I think!
The issue is this - openvpn need net and dns. net can restart
@@ -1012,22 +1033,22 @@ static void svc_restart (bool deps)
our status is invalid.
One workaround would be to introduce a new status, or status locking. */
if (! deps) {
- rc_service_state_t state = rc_service_state (service);
+ RC_SERVICE state = rc_service_state(service);
if (state & RC_SERVICE_STARTED || state & RC_SERVICE_INACTIVE)
- svc_exec ("stop", "start");
+ svc_exec("stop", "start");
else
- svc_exec ("start", NULL);
+ svc_exec("start", NULL);
return;
}
- if (! (rc_service_state (service) & RC_SERVICE_STOPPED)) {
- get_started_services ();
- svc_stop (deps);
+ if (! (rc_service_state(service) & RC_SERVICE_STOPPED)) {
+ get_started_services();
+ svc_stop(deps);
}
- svc_start (deps);
- start_services (restart_services);
- rc_strlist_free (restart_services);
+ svc_start(deps);
+ start_services(restart_services);
+ rc_stringlist_free(restart_services);
restart_services = NULL;
}
@@ -1048,128 +1069,94 @@ static const char * const longopts_help[] = {
};
#include "_usage.c"
-int runscript (int argc, char **argv)
+int runscript(int argc, char **argv)
{
- size_t i;
bool deps = true;
bool doneone = false;
char pid[16];
int retval;
int opt;
- char *svc;
+ RC_STRING *svc;
+ char dir[PATH_MAX];
+ size_t l = 0;
+ size_t ll;
+ char *save;
+ int depoptions = RC_DEP_TRACE;
/* Show help if insufficient args */
- if (argc < 2 || ! exists (argv[1])) {
- fprintf (stderr, "runscript is not meant to be to run directly\n");
- exit (EXIT_FAILURE);
+ if (argc < 2 || ! exists(argv[1])) {
+ fprintf(stderr, "runscript is not meant to be to run directly\n");
+ exit(EXIT_FAILURE);
}
- applet = basename_c (argv[1]);
+ applet = basename_c(argv[1]);
if (argc < 3)
- usage (EXIT_FAILURE);
+ usage(EXIT_FAILURE);
if (*argv[1] == '/')
- service = xstrdup (argv[1]);
+ service = xstrdup(argv[1]);
else {
- char d[PATH_MAX];
- getcwd (d, sizeof (d));
- i = strlen (d) + strlen (argv[1]) + 2;
- service = xmalloc (sizeof (char) * i);
- snprintf (service, i, "%s/%s", d, argv[1]);
+ getcwd(dir, sizeof(dir));
+ l = strlen(dir) + strlen(argv[1]) + 2;
+ service = xmalloc(sizeof (char) * l);
+ snprintf(service, l, "%s/%s", dir, argv[1]);
}
- atexit (cleanup);
+ atexit(cleanup);
/* Change dir to / to ensure all init scripts don't use stuff in pwd */
- chdir ("/");
+ chdir("/");
#ifdef __linux__
/* coldplug events can trigger init scripts, but we don't want to run them
until after rc sysinit has completed so we punt them to the boot runlevel */
- if (exists ("/dev/.rcsysinit")) {
- eerror ("%s: cannot run until sysvinit completes", applet);
- if (mkdir ("/dev/.rcboot", 0755) != 0 && errno != EEXIST)
- eerrorx ("%s: mkdir `/dev/.rcboot': %s", applet, strerror (errno));
- tmp = rc_strcatpaths ("/dev/.rcboot", applet, (char *) NULL);
- symlink (service, tmp);
+ if (exists("/dev/.rcsysinit")) {
+ eerror("%s: cannot run until sysvinit completes", applet);
+ if (mkdir("/dev/.rcboot", 0755) != 0 && errno != EEXIST)
+ eerrorx("%s: mkdir `/dev/.rcboot': %s", applet, strerror(errno));
+ prefix = rc_strcatpaths("/dev/.rcboot", applet, (char *) NULL);
+ symlink(service, prefix);
exit (EXIT_FAILURE);
}
#endif
- if ((softlevel = xstrdup (getenv ("RC_SOFTLEVEL"))) == NULL) {
- /* Ensure our environment is pure
- Also, add our configuration to it */
- char *p;
- env = env_filter ();
-
- if (env) {
-
-#ifdef __linux__
- /* clearenv isn't portable, but there's no harm in using it
- if we have it */
- clearenv ();
-#else
- char *var;
- /* No clearenv present here then.
- We could manipulate environ directly ourselves, but it seems that
- some kernels bitch about this according to the environ man pages
- so we walk though environ and call unsetenv for each value. */
- while (environ[0]) {
- tmp = xstrdup (environ[0]);
- p = tmp;
- var = strsep (&p, "=");
- unsetenv (var);
- free (tmp);
- }
- tmp = NULL;
-#endif
- }
-
- tmplist = env_config ();
- rc_strlist_join (&env, tmplist);
- rc_strlist_free (tmplist);
- tmplist = NULL;
- STRLIST_FOREACH (env, p, i)
- putenv (p);
- /* We don't free our list as that would be null in environ */
-
- softlevel = rc_runlevel_get ();
+ if ((runlevel = xstrdup (getenv ("RC_RUNLEVEL"))) == NULL) {
+ env_filter();
+ env_config();
+ runlevel = rc_runlevel_get();
}
- setenv ("EINFO_LOG", service, 1);
- setenv ("SVCNAME", applet, 1);
+ setenv("EINFO_LOG", service, 1);
+ setenv("SVCNAME", applet, 1);
/* Set an env var so that we always know our pid regardless of any
subshells the init script may create so that our mark_service_*
functions can always instruct us of this change */
- snprintf (pid, sizeof (pid), "%d", (int) getpid ());
- setenv ("RC_RUNSCRIPT_PID", pid, 1);
+ snprintf(pid, sizeof(pid), "%d", (int) getpid());
+ setenv("RC_RUNSCRIPT_PID", pid, 1);
/* eprefix is kinda klunky, but it works for our purposes */
- if (rc_conf_yesno ("rc_parallel")) {
- size_t l = 0;
- size_t ll;
-
+ if (rc_conf_yesno("rc_parallel")) {
/* Get the longest service name */
- services = rc_services_in_runlevel (NULL);
- STRLIST_FOREACH (services, svc, i) {
- ll = strlen (svc);
+ services = rc_services_in_runlevel(NULL);
+ TAILQ_FOREACH(svc, services, entries) {
+ ll = strlen(svc->value);
if (ll > l)
l = ll;
}
/* Make our prefix string */
- prefix = xmalloc (sizeof (char) * l + 1);
- ll = strlen (applet);
- memcpy (prefix, applet, ll);
- memset (prefix + ll, ' ', l - ll);
- memset (prefix + l, 0, 1);
- eprefix (prefix);
+ prefix = xmalloc(sizeof(char) * l + 1);
+ ll = strlen(applet);
+ memcpy(prefix, applet, ll);
+ memset(prefix + ll, ' ', l - ll);
+ memset(prefix + l, 0, 1);
+ eprefix(prefix);
}
#ifdef __linux__
/* Ok, we are ready to go, so setup selinux if applicable */
- setup_selinux (argc, argv);
+ setup_selinux(argc, argv);
#endif
/* Punt the first arg as it's our service name */
@@ -1177,44 +1164,46 @@ int runscript (int argc, char **argv)
argv++;
/* Right then, parse any options there may be */
- while ((opt = getopt_long (argc, argv, getoptstring,
- longopts, (int *) 0)) != -1)
+ while ((opt = getopt_long(argc, argv, getoptstring, longopts, (int *) 0)) != -1)
switch (opt) {
- case 'd':
- setenv ("RC_DEBUG", "yes", 1);
- break;
- case 's':
- if (! (rc_service_state (service) & RC_SERVICE_STARTED))
- exit (EXIT_FAILURE);
- break;
- case 'D':
- deps = false;
- break;
- case_RC_COMMON_GETOPT
- }
+ case 'd':
+ setenv("RC_DEBUG", "yes", 1);
+ break;
+ case 's':
+ if (! (rc_service_state(service) & RC_SERVICE_STARTED))
+ exit(EXIT_FAILURE);
+ break;
+ case 'D':
+ deps = false;
+ break;
+ case_RC_COMMON_GETOPT
+ }
/* Save the IN_BACKGROUND env flag so it's ONLY passed to the service
that is being called and not any dependents */
- if (getenv ("IN_BACKGROUND")) {
- ibsave = xstrdup (getenv ("IN_BACKGROUND"));
- in_background = rc_yesno (ibsave);
- unsetenv ("IN_BACKGROUND");
+ if (getenv("IN_BACKGROUND")) {
+ ibsave = xstrdup(getenv("IN_BACKGROUND"));
+ in_background = rc_yesno(ibsave);
+ unsetenv("IN_BACKGROUND");
}
- if (rc_yesno (getenv ("IN_HOTPLUG"))) {
- if (! rc_conf_yesno ("rc_hotplug") || ! service_plugable (applet))
- eerrorx ("%s: not allowed to be hotplugged", applet);
+ if (rc_yesno(getenv("IN_HOTPLUG"))) {
+ if (! rc_conf_yesno("rc_hotplug") || ! service_plugable(applet))
+ eerrorx("%s: not allowed to be hotplugged", applet);
}
/* Setup a signal handler */
- signal_setup (SIGHUP, handle_signal);
- signal_setup (SIGINT, handle_signal);
- signal_setup (SIGQUIT, handle_signal);
- signal_setup (SIGTERM, handle_signal);
- signal_setup (SIGCHLD, handle_signal);
+ signal_setup(SIGHUP, handle_signal);
+ signal_setup(SIGINT, handle_signal);
+ signal_setup(SIGQUIT, handle_signal);
+ signal_setup(SIGTERM, handle_signal);
+ signal_setup(SIGCHLD, handle_signal);
/* Load our plugins */
- rc_plugin_load ();
+ rc_plugin_load();
+
+ applet_list = rc_stringlist_new();
+ rc_stringlist_add(applet_list, applet);
/* Now run each option */
retval = EXIT_SUCCESS;
@@ -1229,99 +1218,95 @@ int runscript (int argc, char **argv)
This is important as we stamp on the restart function now but
some start/stop routines still need to behave differently if
restarting. */
- unsetenv ("RC_CMD");
- setenv ("RC_CMD", optarg, 1);
+ unsetenv("RC_CMD");
+ setenv("RC_CMD", optarg, 1);
doneone = true;
- rc_strlist_add (&applet_list, applet);
if (strcmp (optarg, "describe") == 0 ||
strcmp (optarg, "help") == 0)
{
- char *save = prefix;
-
- eprefix (NULL);
+ save = prefix;
+ eprefix(NULL);
prefix = NULL;
- svc_exec (optarg, NULL);
- eprefix (save);
- } else if (strcmp (optarg, "ineed") == 0 ||
- strcmp (optarg, "iuse") == 0 ||
- strcmp (optarg, "needsme") == 0 ||
- strcmp (optarg, "usesme") == 0 ||
- strcmp (optarg, "iafter") == 0 ||
- strcmp (optarg, "ibefore") == 0 ||
- strcmp (optarg, "iprovide") == 0)
+ svc_exec(optarg, NULL);
+ eprefix(save);
+ } else if (strcmp(optarg, "ineed") == 0 ||
+ strcmp(optarg, "iuse") == 0 ||
+ strcmp(optarg, "needsme") == 0 ||
+ strcmp(optarg, "usesme") == 0 ||
+ strcmp(optarg, "iafter") == 0 ||
+ strcmp(optarg, "ibefore") == 0 ||
+ strcmp(optarg, "iprovide") == 0)
{
- int depoptions = RC_DEP_TRACE;
-
- if (rc_conf_yesno ("rc_depend_strict"))
+ if (rc_conf_yesno("rc_depend_strict"))
depoptions |= RC_DEP_STRICT;
- if (! deptree && ((deptree = _rc_deptree_load (NULL)) == NULL))
- eerrorx ("failed to load deptree");
-
- rc_strlist_free (services);
- rc_strlist_free (tmplist);
- rc_strlist_add (&tmplist, optarg);
- services = rc_deptree_depends (deptree,
- (const char * const *) tmplist,
- (const char * const *) applet_list,
- softlevel, depoptions);
- STRLIST_FOREACH (services, svc, i)
- printf ("%s%s", i == 1 ? "" : " ", svc);
- if (services)
+ if (! deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))
+ eerrorx("failed to load deptree");
+
+ tmplist = rc_stringlist_new();
+ rc_stringlist_add(tmplist, optarg);
+ services = rc_deptree_depends(deptree, tmplist, applet_list,
+ runlevel, depoptions);
+ rc_stringlist_free(tmplist);
+ tmplist = NULL;
+ TAILQ_FOREACH(svc, services, entries)
+ printf("%s ", svc->value);
+ if (TAILQ_FIRST(services))
printf ("\n");
+ rc_stringlist_free(services);
+ services = NULL;
} else if (strcmp (optarg, "status") == 0) {
- rc_service_state_t r = svc_status (service);
+ RC_SERVICE r = svc_status();
retval = (int) r;
if (retval & RC_SERVICE_STARTED)
retval = 0;
} else {
- if (strcmp (optarg, "conditionalrestart") == 0 ||
- strcmp (optarg, "condrestart") == 0)
+ if (strcmp(optarg, "conditionalrestart") == 0 ||
+ strcmp(optarg, "condrestart") == 0)
{
- if (rc_service_state (service) & RC_SERVICE_STARTED)
- svc_restart (deps);
- } else if (strcmp (optarg, "restart") == 0) {
+ if (rc_service_state(service) & RC_SERVICE_STARTED)
+ svc_restart(deps);
+ } else if (strcmp(optarg, "restart") == 0) {
svc_restart (deps);
- } else if (strcmp (optarg, "start") == 0) {
- svc_start (deps);
- } else if (strcmp (optarg, "stop") == 0) {
+ } else if (strcmp(optarg, "start") == 0) {
+ svc_start(deps);
+ } else if (strcmp(optarg, "stop") == 0) {
if (deps && in_background)
- get_started_services ();
+ get_started_services();
- svc_stop (deps);
+ svc_stop(deps);
if (deps) {
if (! in_background &&
- ! rc_runlevel_stopping () &&
- rc_service_state (service) & RC_SERVICE_STOPPED)
- uncoldplug ();
+ ! rc_runlevel_stopping() &&
+ rc_service_state(service) & RC_SERVICE_STOPPED)
+ uncoldplug();
if (in_background &&
- rc_service_state (service) & RC_SERVICE_INACTIVE)
+ rc_service_state(service) & RC_SERVICE_INACTIVE)
{
- int j;
- STRLIST_FOREACH (restart_services, svc, j)
- if (rc_service_state (svc) & RC_SERVICE_STOPPED)
- rc_service_schedule_start (service, svc);
+ TAILQ_FOREACH(svc, restart_services, entries)
+ if (rc_service_state(svc->value) & RC_SERVICE_STOPPED)
+ rc_service_schedule_start(service, svc->value);
}
}
- } else if (strcmp (optarg, "zap") == 0) {
- einfo ("Manually resetting %s to stopped state", applet);
- rc_service_mark (applet, RC_SERVICE_STOPPED);
- uncoldplug ();
+ } else if (strcmp(optarg, "zap") == 0) {
+ einfo("Manually resetting %s to stopped state", applet);
+ rc_service_mark(applet, RC_SERVICE_STOPPED);
+ uncoldplug();
} else
- svc_exec (optarg, NULL);
+ svc_exec(optarg, NULL);
/* We should ensure this list is empty after an action is done */
- rc_strlist_free (restart_services);
+ rc_stringlist_free(restart_services);
restart_services = NULL;
}
if (! doneone)
- usage (EXIT_FAILURE);
+ usage(EXIT_FAILURE);
}
- return (retval);
+ return retval;
}
diff --git a/src/rc/start-stop-daemon.c b/src/rc/start-stop-daemon.c
index 9ffeba0..bfb737a 100644
--- a/src/rc/start-stop-daemon.c
+++ b/src/rc/start-stop-daemon.c
@@ -46,6 +46,7 @@
#include <sys/termios.h>
#include <sys/time.h>
#include <sys/wait.h>
+
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@@ -71,63 +72,57 @@ static struct pam_conv conv = { NULL, NULL};
#include "einfo.h"
#include "rc.h"
#include "rc-misc.h"
-#include "strlist.h"
-typedef struct schedulelist
+typedef struct scheduleitem
{
enum
{
- schedule_timeout,
- schedule_signal,
- schedule_goto,
- schedule_forever
+ SC_TIMEOUT,
+ SC_SIGNAL,
+ SC_GOTO,
+ SC_FOREVER
} type;
int value;
- struct schedulelist *gotolist;
- struct schedulelist *next;
-} schedulelist_t;
-static schedulelist_t *schedule;
+ struct scheduleitem *gotoitem;
+ STAILQ_ENTRY(scheduleitem) entries;
+} SCHEDULEITEM;
+STAILQ_HEAD(, scheduleitem) schedule;
extern const char *applet;
static char *changeuser;
-static char **newenv;
extern char **environ;
-static void free_schedulelist (schedulelist_t **list)
+static void free_schedulelist(void)
{
- schedulelist_t *here;
- schedulelist_t *next;
+ SCHEDULEITEM *s1 = STAILQ_FIRST(&schedule);
+ SCHEDULEITEM *s2;
- for (here = *list; here; here = next) {
- next = here->next;
- free (here);
+ while (s1) {
+ s2 = STAILQ_NEXT(s1, entries);
+ free(s1);
+ s1 = s2;
}
-
- *list = NULL;
+ STAILQ_INIT(&schedule);
}
-static void cleanup (void)
+static void cleanup(void)
{
if (changeuser)
- free (changeuser);
-
- if (schedule)
- free_schedulelist (&schedule);
+ free(changeuser);
- if (newenv)
- rc_strlist_free (newenv);
+ free_schedulelist();
}
-static int parse_signal (const char *sig)
+static int parse_signal(const char *sig)
{
typedef struct signalpair
{
const char *name;
int signal;
- } signalpair_t;
+ } SIGNALPAIR;
- static const signalpair_t signallist[] = {
+ static const SIGNALPAIR signallist[] = {
{ "ABRT", SIGABRT },
{ "ALRM", SIGALRM },
{ "FPE", SIGFPE },
@@ -153,161 +148,158 @@ static int parse_signal (const char *sig)
const char *s;
if (! sig || *sig == '\0')
- return (-1);
+ return -1;
- if (sscanf (sig, "%u", &i) == 1) {
- if (i > 0 && i < sizeof (signallist) / sizeof (signallist[0]))
- return (i);
- eerrorx ("%s: `%s' is not a valid signal", applet, sig);
+ if (sscanf(sig, "%u", &i) == 1) {
+ if (i > 0 && i < sizeof(signallist) / sizeof(signallist[0]))
+ return i;
+ eerrorx("%s: `%s' is not a valid signal", applet, sig);
}
- if (strncmp (sig, "SIG", 3) == 0)
+ if (strncmp(sig, "SIG", 3) == 0)
s = sig + 3;
else
s = NULL;
- for (i = 0; i < sizeof (signallist) / sizeof (signallist[0]); i++)
- if (strcmp (sig, signallist[i].name) == 0 ||
- (s && strcmp (s, signallist[i].name) == 0))
- return (signallist[i].signal);
+ for (i = 0; i < sizeof(signallist) / sizeof(signallist[0]); i++)
+ if (strcmp(sig, signallist[i].name) == 0 ||
+ (s && strcmp(s, signallist[i].name) == 0))
+ return signallist[i].signal;
- eerrorx ("%s: `%s' is not a valid signal", applet, sig);
+ eerrorx("%s: `%s' is not a valid signal", applet, sig);
/* NOTREACHED */
}
-static void parse_schedule_item (schedulelist_t *item, const char *string)
+static SCHEDULEITEM *parse_schedule_item(const char *string)
{
const char *after_hyph;
int sig;
-
- if (strcmp (string,"forever") == 0)
- item->type = schedule_forever;
- else if (isdigit ((int) string[0])) {
- item->type = schedule_timeout;
+ SCHEDULEITEM *item = xmalloc(sizeof(*item));
+
+ item->value = 0;
+ item->gotoitem = NULL;
+ if (strcmp(string,"forever") == 0)
+ item->type = SC_FOREVER;
+ else if (isdigit((int) string[0])) {
+ item->type = SC_TIMEOUT;
errno = 0;
- if (sscanf (string, "%d", &item->value) != 1)
- eerrorx ("%s: invalid timeout value in schedule `%s'", applet,
- string);
+ if (sscanf(string, "%d", &item->value) != 1)
+ eerrorx("%s: invalid timeout value in schedule `%s'", applet,
+ string);
} else if ((after_hyph = string + (string[0] == '-')) &&
- ((sig = parse_signal (after_hyph)) != -1))
+ ((sig = parse_signal(after_hyph)) != -1))
{
- item->type = schedule_signal;
- item->value = (int) sig;
+ item->type = SC_SIGNAL;
+ item->value = (int)sig;
}
else
- eerrorx ("%s: invalid schedule item `%s'", applet, string);
+ eerrorx("%s: invalid schedule item `%s'", applet, string);
+
+ return item;
}
-static void parse_schedule (const char *string, int default_signal)
+static void parse_schedule(const char *string, int timeout)
{
char buffer[20];
const char *slash;
int count = 0;
- schedulelist_t *repeatat = NULL;
+ SCHEDULEITEM *repeatat = NULL;
size_t len;
- schedulelist_t *next;
+ SCHEDULEITEM *item;
if (string)
for (slash = string; *slash; slash++)
if (*slash == '/')
count++;
- if (schedule)
- free_schedulelist (&schedule);
-
- schedule = xmalloc (sizeof (*schedule));
- schedule->gotolist = NULL;
+ free_schedulelist();
if (count == 0) {
- schedule->type = schedule_signal;
- schedule->value = default_signal;
- schedule->next = xmalloc (sizeof (*schedule->next));
- next = schedule->next;
- next->type = schedule_timeout;
- next->gotolist = NULL;
+ item = xmalloc(sizeof(*item));
+ item->type = SC_SIGNAL;
+ item->value = timeout;
+ item->gotoitem = NULL;
+ STAILQ_INSERT_TAIL(&schedule, item, entries);
+
+ item = xmalloc(sizeof(*item));
+ item->type = SC_TIMEOUT;
+ item->gotoitem = NULL;
+ STAILQ_INSERT_TAIL(&schedule, item, entries);
if (string) {
- if (sscanf (string, "%d", &next->value) != 1)
- eerrorx ("%s: invalid timeout value in schedule", applet);
- }
- else
- next->value = 5;
- next->next = NULL;
+ if (sscanf(string, "%d", &item->value) != 1)
+ eerrorx("%s: invalid timeout value in schedule", applet);
+ } else
+ item->value = 5;
return;
}
- next = schedule;
while (string != NULL) {
- if ((slash = strchr (string, '/')))
+ if ((slash = strchr(string, '/')))
len = slash - string;
else
- len = strlen (string);
+ len = strlen(string);
- if (len >= (ptrdiff_t) sizeof (buffer))
- eerrorx ("%s: invalid schedule item, far too long", applet);
+ if (len >= (ptrdiff_t) sizeof(buffer))
+ eerrorx("%s: invalid schedule item, far too long", applet);
- memcpy (buffer, string, len);
+ memcpy(buffer, string, len);
buffer[len] = 0;
string = slash ? slash + 1 : NULL;
- parse_schedule_item (next, buffer);
- if (next->type == schedule_forever) {
+ item = parse_schedule_item(buffer);
+ STAILQ_INSERT_TAIL(&schedule, item, entries);
+ if (item->type == SC_FOREVER) {
if (repeatat)
- eerrorx ("%s: invalid schedule, `forever' appears more than once",
- applet);
+ eerrorx("%s: invalid schedule, `forever' "
+ "appears more than once", applet);
- repeatat = next;
+ repeatat = item;
continue;
}
-
- if (string) {
- next->next = xmalloc (sizeof (*next->next));
- next = next->next;
- next->gotolist = NULL;
- }
}
if (repeatat) {
- next->next = xmalloc (sizeof (*next->next));
- next = next->next;
- next->type = schedule_goto;
- next->value = 0;
- next->gotolist = repeatat;
+ item = xmalloc(sizeof(*item));
+ item->type = SC_GOTO;
+ item->value = 0;
+ item->gotoitem = repeatat;
+ STAILQ_INSERT_TAIL(&schedule, item, entries);
}
- next->next = NULL;
return;
}
-static pid_t get_pid (const char *pidfile, bool quiet)
+static pid_t get_pid(const char *pidfile, bool quiet)
{
FILE *fp;
pid_t pid;
if (! pidfile)
- return (-1);
+ return -1;
- if ((fp = fopen (pidfile, "r")) == NULL) {
+ if ((fp = fopen(pidfile, "r")) == NULL) {
if (! quiet)
- eerror ("%s: fopen `%s': %s", applet, pidfile, strerror (errno));
- return (-1);
+ eerror("%s: fopen `%s': %s", applet, pidfile, strerror(errno));
+ return -1;
}
- if (fscanf (fp, "%d", &pid) != 1) {
+ if (fscanf(fp, "%d", &pid) != 1) {
if (! quiet)
- eerror ("%s: no pid found in `%s'", applet, pidfile);
- fclose (fp);
- return (-1);
+ eerror("%s: no pid found in `%s'", applet, pidfile);
+ fclose(fp);
+ return -1;
}
- fclose (fp);
+
+ fclose(fp);
- return (pid);
+ return pid;
}
/* return number of processed killed, -1 on error */
-static int do_stop (const char *const *argv, const char *cmd,
- const char *pidfile, uid_t uid,int sig,
- bool quiet, bool verbose, bool test)
+static int do_stop(const char *const *argv, const char *cmd,
+ const char *pidfile, uid_t uid,int sig,
+ bool quiet, bool verbose, bool test)
{
pid_t *pids;
bool killed;
@@ -316,30 +308,30 @@ static int do_stop (const char *const *argv, const char *cmd,
int i;
if (pidfile) {
- if ((pid = get_pid (pidfile, quiet)) == -1)
- return (quiet ? 0 : -1);
- pids = rc_find_pids (NULL, NULL, 0, pid);
+ if ((pid = get_pid(pidfile, quiet)) == -1)
+ return quiet ? 0 : -1;
+ pids = rc_find_pids(NULL, NULL, 0, pid);
} else
- pids = rc_find_pids (argv, cmd, uid, pid);
+ pids = rc_find_pids(argv, cmd, uid, pid);
if (! pids)
- return (0);
+ return 0;
for (i = 0; pids[i]; i++) {
if (test) {
if (! quiet)
- einfo ("Would send signal %d to PID %d", sig, pids[i]);
+ einfo("Would send signal %d to PID %d", sig, pids[i]);
nkilled++;
continue;
}
if (verbose)
- ebegin ("Sending signal %d to PID %d", sig, pids[i]);
+ ebegin("Sending signal %d to PID %d", sig, pids[i]);
errno = 0;
- killed = (kill (pids[i], sig) == 0 || errno == ESRCH ? true : false);
+ killed = (kill(pids[i], sig) == 0 || errno == ESRCH ? true : false);
if (verbose)
- eend (killed ? 0 : 1, "%s: failed to send signal %d to PID %d: %s",
- applet, sig, pids[i], strerror (errno));
+ eend(killed ? 0 : 1, "%s: failed to send signal %d to PID %d: %s",
+ applet, sig, pids[i], strerror(errno));
if (! killed) {
nkilled = -1;
} else {
@@ -348,15 +340,15 @@ static int do_stop (const char *const *argv, const char *cmd,
}
}
- free (pids);
- return (nkilled);
+ free(pids);
+ return nkilled;
}
-static int run_stop_schedule (const char *const *argv, const char *cmd,
- const char *pidfile, uid_t uid,
- bool quiet, bool verbose, bool test)
+static int run_stop_schedule(const char *const *argv, const char *cmd,
+ const char *pidfile, uid_t uid,
+ bool quiet, bool verbose, bool test)
{
- schedulelist_t *item = schedule;
+ SCHEDULEITEM *item = STAILQ_FIRST(&schedule);
int nkilled = 0;
int tkilled = 0;
int nrunning = 0;
@@ -365,119 +357,121 @@ static int run_stop_schedule (const char *const *argv, const char *cmd,
if (verbose) {
if (pidfile)
- einfo ("Will stop PID in pidfile `%s'", pidfile);
+ einfo("Will stop PID in pidfile `%s'", pidfile);
if (uid)
- einfo ("Will stop processes owned by UID %d", uid);
+ einfo("Will stop processes owned by UID %d", uid);
if (argv && *argv)
- einfo ("Will stop processes of `%s'", *argv);
+ einfo("Will stop processes of `%s'", *argv);
if (cmd)
- einfo ("Will stop processes called `%s'", cmd);
+ einfo("Will stop processes called `%s'", cmd);
}
while (item) {
- switch (item->type) {
- case schedule_goto:
- item = item->gotolist;
- continue;
+ switch (item->type) {
+ case SC_GOTO:
+ item = item->gotoitem;
+ continue;
- case schedule_signal:
- nrunning = 0;
- nkilled = do_stop (argv, cmd, pidfile, uid, item->value,
- quiet, verbose, test);
- if (nkilled == 0) {
- if (tkilled == 0) {
- if (! quiet)
- eerror ("%s: no matching processes found", applet);
- }
- return (tkilled);
+ case SC_SIGNAL:
+ nrunning = 0;
+ nkilled = do_stop(argv, cmd, pidfile, uid, item->value,
+ quiet, verbose, test);
+ if (nkilled == 0) {
+ if (tkilled == 0) {
+ if (! quiet)
+ eerror("%s: no matching "
+ "processes found", applet);
}
- else if (nkilled == -1)
- return (0);
+ return tkilled;
+ }
+ else if (nkilled == -1)
+ return 0;
- tkilled += nkilled;
+ tkilled += nkilled;
+ break;
+ case SC_TIMEOUT:
+ if (item->value < 1) {
+ item = NULL;
break;
- case schedule_timeout:
- if (item->value < 1) {
- item = NULL;
- break;
- }
+ }
- nloops = (ONE_SECOND / POLL_INTERVAL) * item->value;
- ts.tv_sec = 0;
- ts.tv_nsec = POLL_INTERVAL;
-
- while (nloops) {
- if ((nrunning = do_stop (argv, cmd, pidfile,
- uid, 0, true, false, true)) == 0)
- return (true);
-
- if (nanosleep (&ts, NULL) == -1) {
- if (errno == EINTR)
- eerror ("%s: caught an interrupt", applet);
- else {
- eerror ("%s: nanosleep: %s", applet, strerror (errno));
- return (0);
- }
+ nloops = (ONE_SECOND / POLL_INTERVAL) * item->value;
+ ts.tv_sec = 0;
+ ts.tv_nsec = POLL_INTERVAL;
+
+ while (nloops) {
+ if ((nrunning = do_stop(argv, cmd, pidfile,
+ uid, 0, true, false, true)) == 0)
+ return true;
+
+ if (nanosleep(&ts, NULL) == -1) {
+ if (errno == EINTR)
+ eerror("%s: caught an interrupt", applet);
+ else {
+ eerror("%s: nanosleep: %s",
+ applet, strerror(errno));
+ return 0;
}
- nloops --;
}
- break;
+ nloops --;
+ }
+ break;
- default:
- eerror ("%s: invalid schedule item `%d'", applet, item->type);
- return (0);
+ default:
+ eerror("%s: invalid schedule item `%d'", applet, item->type);
+ return 0;
}
if (item)
- item = item->next;
+ item = STAILQ_NEXT(item, entries);
}
if (test || (tkilled > 0 && nrunning == 0))
- return (nkilled);
+ return nkilled;
if (! quiet) {
if (nrunning == 1)
- eerror ("%s: %d process refused to stop", applet, nrunning);
+ eerror("%s: %d process refused to stop", applet, nrunning);
else
- eerror ("%s: %d process(es) refused to stop", applet, nrunning);
+ eerror("%s: %d process(es) refused to stop", applet, nrunning);
}
- return (-nrunning);
+ return -nrunning;
}
-static void handle_signal (int sig)
+static void handle_signal(int sig)
{
int status;
int serrno = errno;
char signame[10] = { '\0' };
switch (sig) {
- case SIGINT:
- if (! signame[0])
- snprintf (signame, sizeof (signame), "SIGINT");
- /* FALLTHROUGH */
- case SIGTERM:
- if (! signame[0])
- snprintf (signame, sizeof (signame), "SIGTERM");
- /* FALLTHROUGH */
- case SIGQUIT:
- if (! signame[0])
- snprintf (signame, sizeof (signame), "SIGQUIT");
- eerrorx ("%s: caught %s, aborting", applet, signame);
- /* NOTREACHED */
-
- case SIGCHLD:
- for (;;) {
- if (waitpid (-1, &status, WNOHANG) < 0) {
- if (errno != ECHILD)
- eerror ("%s: waitpid: %s", applet, strerror (errno));
- break;
- }
+ case SIGINT:
+ if (! signame[0])
+ snprintf(signame, sizeof(signame), "SIGINT");
+ /* FALLTHROUGH */
+ case SIGTERM:
+ if (! signame[0])
+ snprintf(signame, sizeof(signame), "SIGTERM");
+ /* FALLTHROUGH */
+ case SIGQUIT:
+ if (! signame[0])
+ snprintf(signame, sizeof(signame), "SIGQUIT");
+ eerrorx("%s: caught %s, aborting", applet, signame);
+ /* NOTREACHED */
+
+ case SIGCHLD:
+ for (;;) {
+ if (waitpid(-1, &status, WNOHANG) < 0) {
+ if (errno != ECHILD)
+ eerror("%s: waitpid: %s", applet, strerror(errno));
+ break;
}
- break;
+ }
+ break;
- default:
- eerror ("%s: caught unknown signal %d", applet, sig);
+ default:
+ eerror("%s: caught unknown signal %d", applet, sig);
}
/* Restore errno */
@@ -537,7 +531,7 @@ static const char * const longopts_help[] = {
};
#include "_usage.c"
-int start_stop_daemon (int argc, char **argv)
+int start_stop_daemon(int argc, char **argv)
{
int devnull_fd = -1;
#ifdef TIOCNOTTY
@@ -574,154 +568,160 @@ int start_stop_daemon (int argc, char **argv)
int stderr_fd;
pid_t pid;
int i;
- char *svcname = getenv ("SVCNAME");
- char *env;
+ char *svcname = getenv("SVCNAME");
+ RC_STRINGLIST *env_list;
+ RC_STRING *env;
+ char *path;
bool sethome = false;
bool setuser = false;
+ char *p;
+ char *tmp;
+ struct passwd *pw;
+ struct group *gr;
+ char line[130];
+ FILE *fp;
+ size_t len;
- atexit (cleanup);
+ STAILQ_INIT(&schedule);
+ atexit(cleanup);
- signal_setup (SIGINT, handle_signal);
- signal_setup (SIGQUIT, handle_signal);
- signal_setup (SIGTERM, handle_signal);
+ signal_setup(SIGINT, handle_signal);
+ signal_setup(SIGQUIT, handle_signal);
+ signal_setup(SIGTERM, handle_signal);
- if ((env = getenv ("SSD_NICELEVEL")))
- if (sscanf (env, "%d", &nicelevel) != 1)
- eerror ("%s: invalid nice level `%s' (SSD_NICELEVEL)", applet, env);
+ if ((path = getenv("SSD_NICELEVEL")))
+ if (sscanf(path, "%d", &nicelevel) != 1)
+ eerror("%s: invalid nice level `%s' (SSD_NICELEVEL)",
+ applet, path);
- while ((opt = getopt_long (argc, argv, "e:" getoptstring, longopts,
- (int *) 0)) != -1)
+ while ((opt = getopt_long(argc, argv, "e:" getoptstring, longopts,
+ (int *) 0)) != -1)
switch (opt) {
- case 'K': /* --stop */
- stop = true;
- break;
-
- case 'N': /* --nice */
- if (sscanf (optarg, "%d", &nicelevel) != 1)
- eerrorx ("%s: invalid nice level `%s'", applet, optarg);
- break;
+ case 'K': /* --stop */
+ stop = true;
+ break;
- case 'R': /* --retry <schedule>|<timeout> */
- parse_schedule (optarg, sig);
- break;
+ case 'N': /* --nice */
+ if (sscanf(optarg, "%d", &nicelevel) != 1)
+ eerrorx("%s: invalid nice level `%s'", applet, optarg);
+ break;
- case 'S': /* --start */
- start = true;
- break;
+ case 'R': /* --retry <schedule>|<timeout> */
+ parse_schedule(optarg, sig);
+ break;
- case 'b': /* --background */
- background = true;
- break;
+ case 'S': /* --start */
+ start = true;
+ break;
- case 'u': /* --user <username>|<uid> */
- case 'c': /* --chuid <username>|<uid> */
- {
- char *p = optarg;
- char *cu = strsep (&p, ":");
- struct passwd *pw = NULL;
+ case 'b': /* --background */
+ background = true;
+ break;
- changeuser = xstrdup (cu);
- if (sscanf (cu, "%d", &tid) != 1)
- pw = getpwnam (cu);
+ case 'u': /* --user <username>|<uid> */
+ case 'c': /* --chuid <username>|<uid> */
+ {
+ p = optarg;
+ tmp = strsep(&p, ":");
+ changeuser = xstrdup(tmp);
+ if (sscanf(tmp, "%d", &tid) != 1)
+ pw = getpwnam(tmp);
+ else
+ pw = getpwuid((uid_t) tid);
+
+ if (! pw)
+ eerrorx("%s: user `%s' not found", applet, tmp);
+ uid = pw->pw_uid;
+ if (! gid)
+ gid = pw->pw_gid;
+
+ if (p) {
+ tmp = strsep (&p, ":");
+ if (sscanf(tmp, "%d", &tid) != 1)
+ gr = getgrnam(tmp);
else
- pw = getpwuid ((uid_t) tid);
-
- if (! pw)
- eerrorx ("%s: user `%s' not found", applet, cu);
- uid = pw->pw_uid;
- if (! gid)
- gid = pw->pw_gid;
-
- if (p) {
- struct group *gr = NULL;
- char *cg = strsep (&p, ":");
-
- if (sscanf (cg, "%d", &tid) != 1)
- gr = getgrnam (cg);
- else
- gr = getgrgid ((gid_t) tid);
-
- if (! gr)
- eerrorx ("%s: group `%s' not found", applet, cg);
- gid = gr->gr_gid;
- }
- }
- break;
+ gr = getgrgid((gid_t) tid);
- case 'd': /* --chdir /new/dir */
- ch_dir = optarg;
- break;
-
- case 'e': /* --env */
- if (putenv (optarg) == 0) {
- if (strncmp ("HOME=", optarg, 5) == 0)
- sethome = true;
- else if (strncmp ("USER=", optarg, 5) == 0)
- setuser = true;
+ if (! gr)
+ eerrorx("%s: group `%s' not found",
+ applet, tmp);
+ gid = gr->gr_gid;
}
- break;
+ }
+ break;
- case 'g': /* --group <group>|<gid> */
- {
- struct group *gr = getgrnam (optarg);
+ case 'd': /* --chdir /new/dir */
+ ch_dir = optarg;
+ break;
- if (sscanf (optarg, "%d", &tid) != 1)
- gr = getgrnam (optarg);
- else
- gr = getgrgid ((gid_t) tid);
+ case 'e': /* --env */
+ if (putenv(optarg) == 0) {
+ if (strncmp("HOME=", optarg, 5) == 0)
+ sethome = true;
+ else if (strncmp("USER=", optarg, 5) == 0)
+ setuser = true;
+ }
+ break;
- if (! gr)
- eerrorx ("%s: group `%s' not found", applet, optarg);
- gid = gr->gr_gid;
- }
- break;
+ case 'g': /* --group <group>|<gid> */
+ {
+ if (sscanf(optarg, "%d", &tid) != 1)
+ gr = getgrnam(optarg);
+ else
+ gr = getgrgid((gid_t) tid);
- case 'm': /* --make-pidfile */
- makepidfile = true;
- break;
+ if (! gr)
+ eerrorx("%s: group `%s' not found", applet, optarg);
+ gid = gr->gr_gid;
+ }
+ break;
- case 'n': /* --name <process-name> */
- cmd = optarg;
- break;
+ case 'm': /* --make-pidfile */
+ makepidfile = true;
+ break;
- case 'o': /* --oknodo */
- oknodo = true;
- break;
+ case 'n': /* --name <process-name> */
+ cmd = optarg;
+ break;
- case 'p': /* --pidfile <pid-file> */
- pidfile = optarg;
- break;
+ case 'o': /* --oknodo */
+ oknodo = true;
+ break;
- case 's': /* --signal <signal> */
- sig = parse_signal (optarg);
- break;
+ case 'p': /* --pidfile <pid-file> */
+ pidfile = optarg;
+ break;
- case 't': /* --test */
- test = true;
- break;
+ case 's': /* --signal <signal> */
+ sig = parse_signal(optarg);
+ break;
- case 'r': /* --chroot /new/root */
- ch_root = optarg;
- break;
+ case 't': /* --test */
+ test = true;
+ break;
- case 'a':
- case 'x': /* --exec <executable> */
- exec = optarg;
- break;
+ case 'r': /* --chroot /new/root */
+ ch_root = optarg;
+ break;
- case '1': /* --stdout /path/to/stdout.lgfile */
- redirect_stdout = optarg;
- break;
+ case 'a':
+ case 'x': /* --exec <executable> */
+ exec = optarg;
+ break;
- case '2': /* --stderr /path/to/stderr.logfile */
- redirect_stderr = optarg;
- break;
+ case '1': /* --stdout /path/to/stdout.lgfile */
+ redirect_stdout = optarg;
+ break;
+
+ case '2': /* --stderr /path/to/stderr.logfile */
+ redirect_stderr = optarg;
+ break;
- case_RC_COMMON_GETOPT
+ case_RC_COMMON_GETOPT
}
- quiet = rc_yesno (getenv ("EINFO_QUIET"));
- verbose = rc_yesno (getenv ("EINFO_VERBOSE"));
+ quiet = rc_yesno(getenv("EINFO_QUIET"));
+ verbose = rc_yesno(getenv("EINFO_VERBOSE"));
/* Allow start-stop-daemon --signal HUP --exec /usr/sbin/dnsmasq
* instead of forcing --stop --oknodo as well */
@@ -736,22 +736,22 @@ int start_stop_daemon (int argc, char **argv)
}
if (start == stop)
- eerrorx ("%s: need one of --start or --stop", applet);
+ eerrorx("%s: need one of --start or --stop", applet);
if (start && ! exec)
- eerrorx ("%s: --start needs --exec", applet);
+ eerrorx("%s: --start needs --exec", applet);
if (stop && ! exec && ! pidfile && ! cmd && ! uid)
- eerrorx ("%s: --stop needs --exec, --pidfile, --name or --user", applet);
+ eerrorx("%s: --stop needs --exec, --pidfile, --name or --user", applet);
if (makepidfile && ! pidfile)
- eerrorx ("%s: --make-pidfile is only relevant with --pidfile", applet);
+ eerrorx("%s: --make-pidfile is only relevant with --pidfile", applet);
if (background && ! start)
- eerrorx ("%s: --background is only relevant with --start", applet);
+ eerrorx("%s: --background is only relevant with --start", applet);
if ((redirect_stdout || redirect_stderr) && ! background)
- eerrorx ("%s: --stdout and --stderr are only relevant with --background",
+ eerrorx("%s: --stdout and --stderr are only relevant with --background",
applet);
argc -= optind;
@@ -759,52 +759,49 @@ int start_stop_daemon (int argc, char **argv)
/* Validate that the binary exists if we are starting */
if (exec) {
- char *tmp;
if (ch_root)
- tmp = rc_strcatpaths (ch_root, exec, (char *) NULL);
+ tmp = rc_strcatpaths(ch_root, exec, (char *) NULL);
else
tmp = exec;
- if (start && ! exists (tmp)) {
- eerror ("%s: %s does not exist", applet, tmp);
+ if (start && ! exists(tmp)) {
+ eerror("%s: %s does not exist", applet, tmp);
if (ch_root)
- free (tmp);
- exit (EXIT_FAILURE);
+ free(tmp);
+ exit(EXIT_FAILURE);
}
/* If we don't have a pidfile or name, check it's not
* interpreted, otherwise we should fail */
if (! pidfile && ! cmd) {
- char line[130];
- FILE *fp = fopen (tmp, "r");
-
+ fp = fopen (tmp, "r");
if (fp) {
- fgets (line, sizeof (line), fp);
- fclose (fp);
+ fgets(line, sizeof(line), fp);
+ fclose(fp);
if (line[0] == '#' && line[1] == '!') {
- size_t len = strlen (line) - 1;
+ len = strlen (line) - 1;
/* Remove the trailing newline */
if (line[len] == '\n')
line[len] = '\0';
- eerror ("%s: %s is a script",
+ eerror("%s: %s is a script",
applet, exec);
- eerror ("%s: and should be started, stopped or signalled with ",
- applet);
- eerror ("%s: --exec %s %s",
+ eerror("%s: and should be started, stopped"
+ " or signalled with ", applet);
+ eerror("%s: --exec %s %s",
applet, line + 2, exec);
- eerror ("%s: or you should specify a pidfile or process name",
- applet);
+ eerror("%s: or you should specify a pidfile"
+ " or process name", applet);
if (ch_root)
- free (tmp);
- exit (EXIT_FAILURE);
+ free(tmp);
+ exit(EXIT_FAILURE);
}
}
}
if (ch_root)
- free (tmp);
+ free(tmp);
}
/* Add exec to our arguments */
@@ -813,83 +810,79 @@ int start_stop_daemon (int argc, char **argv)
if (stop) {
int result;
- if (! schedule) {
+ if (! STAILQ_FIRST(&schedule)) {
if (test || oknodo)
- parse_schedule ("0", sig);
+ parse_schedule("0", sig);
else
- parse_schedule (NULL, sig);
+ parse_schedule(NULL, sig);
}
- result = run_stop_schedule ((const char *const *)argv, cmd,
- pidfile, uid, quiet, verbose, test);
+ result = run_stop_schedule((const char *const *)argv, cmd,
+ pidfile, uid, quiet, verbose, test);
if (result < 0)
/* We failed to stop something */
- exit (EXIT_FAILURE);
+ exit(EXIT_FAILURE);
if (test || oknodo)
- return (result > 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+ return result > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
/* Even if we have not actually killed anything, we should
* remove information about it as it may have unexpectedly
* crashed out. We should also return success as the end
* result would be the same. */
- if (pidfile && exists (pidfile))
- unlink (pidfile);
+ if (pidfile && exists(pidfile))
+ unlink(pidfile);
if (svcname)
- rc_service_daemon_set (svcname,
- (const char *const *)argv,
- cmd, pidfile, false);
+ rc_service_daemon_set(svcname,
+ (const char *const *)argv,
+ cmd, pidfile, false);
- exit (EXIT_SUCCESS);
+ exit(EXIT_SUCCESS);
}
- if (do_stop ((const char * const *)argv, cmd, pidfile, uid,
- 0, true, false, true) > 0)
- eerrorx ("%s: %s is already running", applet, exec);
+ if (do_stop((const char * const *)argv, cmd, pidfile, uid,
+ 0, true, false, true) > 0)
+ eerrorx("%s: %s is already running", applet, exec);
if (test) {
if (quiet)
exit (EXIT_SUCCESS);
- einfon ("Would start");
+ einfon("Would start");
while (argc-- >= 0)
printf(" %s", *argv++);
- printf ("\n");
- eindent ();
+ printf("\n");
+ eindent();
if (uid != 0)
- einfo ("as user id %d", uid);
+ einfo("as user id %d", uid);
if (gid != 0)
- einfo ("as group id %d", gid);
+ einfo("as group id %d", gid);
if (ch_root)
- einfo ("in root `%s'", ch_root);
+ einfo("in root `%s'", ch_root);
if (ch_dir)
- einfo ("in dir `%s'", ch_dir);
+ einfo("in dir `%s'", ch_dir);
if (nicelevel != 0)
- einfo ("with a priority of %d", nicelevel);
- eoutdent ();
- exit (EXIT_SUCCESS);
+ einfo("with a priority of %d", nicelevel);
+ eoutdent();
+ exit(EXIT_SUCCESS);
}
- /* Ensure this is unset, so if the daemon does /etc/init.d/foo
- Then we filter the environment accordingly */
- unsetenv ("RC_SOFTLEVEL");
-
if (verbose) {
- ebegin ("Detaching to start `%s'", exec);
- eindent ();
+ ebegin("Detaching to start `%s'", exec);
+ eindent();
}
if (background)
- signal_setup (SIGCHLD, handle_signal);
+ signal_setup(SIGCHLD, handle_signal);
- if ((pid = fork ()) == -1)
- eerrorx ("%s: fork: %s", applet, strerror (errno));
+ if ((pid = fork()) == -1)
+ eerrorx("%s: fork: %s", applet, strerror(errno));
/* Child process - lets go! */
if (pid == 0) {
- pid_t mypid = getpid ();
+ pid_t mypid = getpid();
#ifdef TIOCNOTTY
tty_fd = open("/dev/tty", O_RDWR);
@@ -898,66 +891,66 @@ int start_stop_daemon (int argc, char **argv)
devnull_fd = open("/dev/null", O_RDWR);
if (nicelevel) {
- if (setpriority (PRIO_PROCESS, mypid, nicelevel) == -1)
- eerrorx ("%s: setpritory %d: %s", applet, nicelevel,
+ if (setpriority(PRIO_PROCESS, mypid, nicelevel) == -1)
+ eerrorx("%s: setpritory %d: %s", applet, nicelevel,
strerror(errno));
}
- if (ch_root && chroot (ch_root) < 0)
- eerrorx ("%s: chroot `%s': %s", applet, ch_root, strerror (errno));
+ if (ch_root && chroot(ch_root) < 0)
+ eerrorx("%s: chroot `%s': %s", applet, ch_root, strerror(errno));
if (ch_dir && chdir (ch_dir) < 0)
- eerrorx ("%s: chdir `%s': %s", applet, ch_dir, strerror (errno));
+ eerrorx("%s: chdir `%s': %s", applet, ch_dir, strerror(errno));
if (makepidfile && pidfile) {
- FILE *fp = fopen (pidfile, "w");
+ fp = fopen(pidfile, "w");
if (! fp)
- eerrorx ("%s: fopen `%s': %s", applet, pidfile, strerror
- (errno));
- fprintf (fp, "%d\n", mypid);
- fclose (fp);
+ eerrorx("%s: fopen `%s': %s", applet, pidfile,
+ strerror(errno));
+ fprintf(fp, "%d\n", mypid);
+ fclose(fp);
}
#ifdef HAVE_PAM
if (changeuser != NULL)
- pamr = pam_start ("start-stop-daemon", changeuser, &conv, &pamh);
+ pamr = pam_start("start-stop-daemon", changeuser, &conv, &pamh);
else
- pamr = pam_start ("start-stop-daemon", "nobody", &conv, &pamh);
+ pamr = pam_start("start-stop-daemon", "nobody", &conv, &pamh);
if (pamr == PAM_SUCCESS)
- pamr = pam_authenticate (pamh, PAM_SILENT);
+ pamr = pam_authenticate(pamh, PAM_SILENT);
if (pamr == PAM_SUCCESS)
- pamr = pam_acct_mgmt (pamh, PAM_SILENT);
+ pamr = pam_acct_mgmt(pamh, PAM_SILENT);
if (pamr == PAM_SUCCESS)
- pamr = pam_open_session (pamh, PAM_SILENT);
+ pamr = pam_open_session(pamh, PAM_SILENT);
if (pamr != PAM_SUCCESS)
- eerrorx ("%s: pam error: %s", applet, pam_strerror(pamh, pamr));
+ eerrorx("%s: pam error: %s", applet, pam_strerror(pamh, pamr));
#endif
- if (gid && setgid (gid))
- eerrorx ("%s: unable to set groupid to %d", applet, gid);
- if (changeuser && initgroups (changeuser, gid))
- eerrorx ("%s: initgroups (%s, %d)", applet, changeuser, gid);
- if (uid && setuid (uid))
+ if (gid && setgid(gid))
+ eerrorx("%s: unable to set groupid to %d", applet, gid);
+ if (changeuser && initgroups(changeuser, gid))
+ eerrorx("%s: initgroups (%s, %d)", applet, changeuser, gid);
+ if (uid && setuid(uid))
eerrorx ("%s: unable to set userid to %d", applet, uid);
else {
- struct passwd *passwd = getpwuid (uid);
- if (passwd) {
+ pw = getpwuid(uid);
+ if (pw) {
if (! sethome) {
- unsetenv ("HOME");
- if (passwd->pw_dir)
- setenv ("HOME", passwd->pw_dir, 1);
+ unsetenv("HOME");
+ if (pw->pw_dir)
+ setenv("HOME", pw->pw_dir, 1);
}
if (! setuser) {
- unsetenv ("USER");
- if (passwd->pw_name)
- setenv ("USER", passwd->pw_name, 1);
+ unsetenv("USER");
+ if (pw->pw_name)
+ setenv("USER", pw->pw_name, 1);
}
}
}
/* Close any fd's to the passwd database */
- endpwent ();
+ endpwent();
#ifdef TIOCNOTTY
ioctl(tty_fd, TIOCNOTTY, 0);
@@ -965,84 +958,81 @@ int start_stop_daemon (int argc, char **argv)
#endif
/* Clean the environment of any RC_ variables */
- STRLIST_FOREACH (environ, env, i) {
- if ((strncmp (env, "RC_", 3) == 0 &&
- strncmp (env, "RC_SERVICE=", strlen ("RC_SERVICE=")) != 0) ||
- strncmp (env, "SSD_NICELEVEL=", strlen ("SSD_NICELEVEL=")) == 0)
+ env_list = rc_stringlist_new();
+ i = 0;
+ while(environ[i])
+ rc_stringlist_add(env_list, environ[i++]);
+ TAILQ_FOREACH(env, env_list, entries) {
+ if ((strncmp(env->value, "RC_", 3) == 0 &&
+ strncmp(env->value, "RC_SERVICE=", strlen("RC_SERVICE=")) != 0) ||
+ strncmp(env->value, "SSD_NICELEVEL=", strlen("SSD_NICELEVEL=")) == 0)
+ {
+ p = strchr(env->value, '=');
+ *p = '\0';
+ unsetenv(env->value);
continue;
-
- /* For the path, remove the rcscript bin dir from it */
- if (strncmp (env, "PATH=", 5) == 0) {
- char *path = xstrdup (env);
- char *newpath = NULL;
- char *p = path;
- char *token;
- char *np;
- size_t l;
- int t;
-
- p += 5;
- while ((token = strsep (&p, ":"))) {
- if (strcmp (token, RC_LIBDIR "/bin") == 0 ||
- strcmp (token, RC_LIBDIR "/sbin") == 0)
- continue;
-
- t = strlen (token);
- if (newpath) {
- l = strlen (newpath);
- newpath = xrealloc (newpath, sizeof (char) * (l + t + 2));
- np = newpath + l;
- *np++ = ':';
- memcpy (np, token, sizeof (char) * strlen (token));
- np += t;
- *np = '\0';
- } else {
- l = strlen ("PATH=") + t + 1;
- newpath = xmalloc (sizeof (char) * l);
- snprintf (newpath, l, "PATH=%s", token);
- }
- }
- rc_strlist_add (&newenv, newpath);
- free (path);
- free (newpath);
- } else
- rc_strlist_add (&newenv, env);
+ }
+ }
+ rc_stringlist_free(env_list);
+
+ /* For the path, remove the rcscript bin dir from it */
+ if ((path = getenv("PATH"))) {
+ size_t mx = strlen(path);
+ char *newpath = xmalloc(mx);
+ char *token;
+ char *np = newpath;
+ size_t l;
+
+ p = path;
+ while ((token = strsep (&p, ":"))) {
+ if (strcmp (token, RC_LIBDIR "/bin") == 0 ||
+ strcmp (token, RC_LIBDIR "/sbin") == 0)
+ continue;
+
+ l = strlen (token);
+ if (np != newpath)
+ *np++ = ':';
+ memcpy (np, token, l);
+ np += l;
+ *np = '\0';
+ }
+ unsetenv("PATH");
+ setenv("PATH", newpath, 1);
}
- umask (022);
+ umask(022);
stdout_fd = devnull_fd;
stderr_fd = devnull_fd;
if (redirect_stdout) {
- if ((stdout_fd = open (redirect_stdout, O_WRONLY | O_CREAT | O_APPEND,
- S_IRUSR | S_IWUSR)) == -1)
- eerrorx ("%s: unable to open the logfile for stdout `%s': %s",
- applet, redirect_stdout, strerror (errno));
+ if ((stdout_fd = open(redirect_stdout, O_WRONLY | O_CREAT | O_APPEND,
+ S_IRUSR | S_IWUSR)) == -1)
+ eerrorx("%s: unable to open the logfile for stdout `%s': %s",
+ applet, redirect_stdout, strerror(errno));
}
if (redirect_stderr) {
- if ((stderr_fd = open (redirect_stderr, O_WRONLY | O_CREAT | O_APPEND,
- S_IRUSR | S_IWUSR)) == -1)
- eerrorx ("%s: unable to open the logfile for stderr `%s': %s",
- applet, redirect_stderr, strerror (errno));
+ if ((stderr_fd = open(redirect_stderr, O_WRONLY | O_CREAT | O_APPEND,
+ S_IRUSR | S_IWUSR)) == -1)
+ eerrorx("%s: unable to open the logfile for stderr `%s': %s",
+ applet, redirect_stderr, strerror(errno));
}
/* We don't redirect stdin as some daemons may need it */
if (background || quiet || redirect_stdout)
- dup2 (stdout_fd, STDOUT_FILENO);
+ dup2(stdout_fd, STDOUT_FILENO);
if (background || quiet || redirect_stderr)
- dup2 (stderr_fd, STDERR_FILENO);
+ dup2(stderr_fd, STDERR_FILENO);
- for (i = getdtablesize () - 1; i >= 3; --i)
+ for (i = getdtablesize() - 1; i >= 3; --i)
close(i);
- setsid ();
-
- execve (exec, argv, newenv);
+ setsid();
+ execv(exec, argv);
#ifdef HAVE_PAM
if (pamr == PAM_SUCCESS)
- pam_close_session (pamh, PAM_SILENT);
+ pam_close_session(pamh, PAM_SILENT);
#endif
- eerrorx ("%s: failed to exec `%s': %s", applet, exec, strerror (errno));
+ eerrorx("%s: failed to exec `%s': %s", applet, exec, strerror(errno));
}
/* Parent process */
@@ -1053,17 +1043,17 @@ int start_stop_daemon (int argc, char **argv)
errno = 0;
do {
- pid = waitpid (savepid, &status, 0);
+ pid = waitpid(savepid, &status, 0);
if (pid < 1) {
- eerror ("waitpid %d: %s", savepid, strerror (errno));
- return (-1);
+ eerror("waitpid %d: %s", savepid, strerror(errno));
+ return -1;
}
- } while (! WIFEXITED (status) && ! WIFSIGNALED (status));
+ } while (! WIFEXITED(status) && ! WIFSIGNALED(status));
- if (! WIFEXITED (status) || WEXITSTATUS (status) != 0) {
+ if (! WIFEXITED(status) || WEXITSTATUS(status) != 0) {
if (! quiet)
- eerrorx ("%s: failed to start `%s'", applet, exec);
- exit (EXIT_FAILURE);
+ eerrorx("%s: failed to start `%s'", applet, exec);
+ exit(EXIT_FAILURE);
}
pid = savepid;
@@ -1081,12 +1071,12 @@ int start_stop_daemon (int argc, char **argv)
ts.tv_nsec = POLL_INTERVAL;
while (nloops) {
- if (nanosleep (&ts, NULL) == -1) {
+ if (nanosleep(&ts, NULL) == -1) {
if (errno == EINTR)
- eerror ("%s: caught an interrupt", applet);
+ eerror("%s: caught an interrupt", applet);
else {
- eerror ("%s: nanosleep: %s", applet, strerror (errno));
- return (0);
+ eerror("%s: nanosleep: %s", applet, strerror(errno));
+ return 0;
}
}
@@ -1111,27 +1101,28 @@ int start_stop_daemon (int argc, char **argv)
} else {
if (pidfile) {
/* The pidfile may not have been written yet - give it some time */
- if (get_pid (pidfile, true) == -1) {
+ if (get_pid(pidfile, true) == -1) {
if (! nloopsp)
- eerrorx ("%s: did not create a valid pid in `%s'",
- applet, pidfile);
+ eerrorx("%s: did not create a valid pid in `%s'",
+ applet, pidfile);
alive = true;
} else
nloopsp = 0;
}
- if (do_stop ((const char *const *)argv, cmd,
- pidfile, uid, 0, true, false, true) > 0)
+ if (do_stop((const char *const *)argv, cmd,
+ pidfile, uid, 0, true, false, true) > 0)
alive = true;
}
if (! alive)
- eerrorx ("%s: %s died", applet, exec);
+ eerrorx("%s: %s died", applet, exec);
}
}
if (svcname)
- rc_service_daemon_set (svcname, (const char *const *)argv, cmd, pidfile, true);
+ rc_service_daemon_set(svcname, (const char *const *)argv,
+ cmd, pidfile, true);
- exit (EXIT_SUCCESS);
+ exit(EXIT_SUCCESS);
/* NOTREACHED */
}