diff options
author | Christian Heim <phreak@gentoo.org> | 2006-06-05 19:46:54 +0000 |
---|---|---|
committer | Christian Heim <phreak@gentoo.org> | 2006-06-05 19:46:54 +0000 |
commit | ae0bbf3ae39e23600345b42edfe2ac1babcb4dc0 (patch) | |
tree | a7b020f26114e96c9949a4a4cb38f1f9d77ebd8c /src/core/librccore/runlevels.c | |
parent | Merging r2046 (diff) | |
download | baselayout-vserver-ae0bbf3ae39e23600345b42edfe2ac1babcb4dc0.tar.gz baselayout-vserver-ae0bbf3ae39e23600345b42edfe2ac1babcb4dc0.tar.bz2 baselayout-vserver-ae0bbf3ae39e23600345b42edfe2ac1babcb4dc0.zip |
Merging r2079
svn path=/baselayout-vserver/trunk/; revision=372
Diffstat (limited to 'src/core/librccore/runlevels.c')
-rw-r--r-- | src/core/librccore/runlevels.c | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/src/core/librccore/runlevels.c b/src/core/librccore/runlevels.c new file mode 100644 index 0000000..8062912 --- /dev/null +++ b/src/core/librccore/runlevels.c @@ -0,0 +1,218 @@ +/* + * runlevels.c + * + * Functions dealing with runlevels. + * + * Copyright (C) 2004,2005 Martin Schlemmer <azarah@nosferatu.za.org> + * + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Header$ + */ + +#include <errno.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +#include "internal/rccore.h" + +static char **get_runlevel_dirs (void); + +LIST_HEAD (runlevel_list); + +char ** +get_runlevel_dirs (void) +{ + char **dir_list = NULL; + char **runlvl_list = NULL; + char *dir_item; + int count; + + dir_list = rc_ls_dir (RUNLEVELS_DIR, 0); + if (NULL == dir_list) + { + errno = ENOENT; + DBG_MSG ("Failed to get any entries in '%' !\n", RUNLEVELS_DIR); + + return NULL; + } + + str_list_for_each_item (dir_list, dir_item, count) + { + if (rc_is_dir (dir_item, 0)) + { + char *tmp_str; + + tmp_str = xstrndup (dir_item, strlen (dir_item)); + if (NULL == tmp_str) + goto error; + + str_list_add_item (runlvl_list, tmp_str, error); + } + } + + str_list_free (dir_list); + + if (!check_strv (runlvl_list)) + { + if (NULL != runlvl_list) + str_list_free (runlvl_list); + } + + return runlvl_list; + +error: + if (NULL != dir_list) + str_list_free (dir_list); + if (NULL != runlvl_list) + str_list_free (runlvl_list); + + return NULL; +} + +int +get_runlevels (void) +{ + char **runlvl_list = NULL; + char *runlevel; + int count; + + runlvl_list = get_runlevel_dirs (); + if (NULL == runlvl_list) + { + DBG_MSG ("Failed to get any runlevels\n"); + + return -1; + } + + str_list_for_each_item (runlvl_list, runlevel, count) + { + runlevel_info_t *runlevel_info; + char **dir_list = NULL; + char *dir_item; + int dir_count; + + DBG_MSG ("Adding runlevel '%s'\n", rc_basename (runlevel)); + + runlevel_info = xmalloc (sizeof (runlevel_info_t)); + if (NULL == runlevel_info) + goto error; + + runlevel_info->dirname = xstrndup (runlevel, strlen (runlevel)); + if (NULL == runlevel_info->dirname) + goto error; + + INIT_LIST_HEAD (&runlevel_info->entries); + + dir_list = rc_ls_dir (runlevel, 0); + if (NULL == dir_list) + { + if (0 != errno) + goto error; + + goto no_entries; + } + + str_list_for_each_item (dir_list, dir_item, dir_count) + { + rcscript_info_t *script_info; + rcscript_info_t *new_script_info = NULL; + + if (!rc_is_link (dir_item)) + { + DBG_MSG ("Skipping non symlink '%s' !\n", dir_item); + continue; + } + + script_info = get_rcscript_info (rc_basename (dir_item)); + if (NULL == script_info) + { + DBG_MSG ("Skipping invalid entry '%s' !\n", dir_item); + continue; + } + + new_script_info = xmalloc (sizeof (rcscript_info_t)); + if (NULL == new_script_info) + { + str_list_free (dir_list); + goto error; + } + + DBG_MSG ("Adding '%s' to runlevel '%s'\n", + rc_basename (script_info->filename), + rc_basename (runlevel)); + + /* Add a copy, as the next and prev pointers will be changed */ + memcpy (new_script_info, script_info, sizeof (rcscript_info_t)); + list_add_tail (&new_script_info->node, &runlevel_info->entries); + } + + str_list_free (dir_list); + +no_entries: + list_add_tail (&runlevel_info->node, &runlevel_list); + } + + str_list_free (runlvl_list); + + return 0; + +error: + if (NULL != runlvl_list) + str_list_free (runlvl_list); + + return -1; +} + +runlevel_info_t * +get_runlevel_info (const char *runlevel) +{ + runlevel_info_t *info; + + if (!check_arg_str (runlevel)) + return NULL; + + list_for_each_entry (info, &runlevel_list, node) + { + if ((strlen (runlevel) == strlen (rc_basename (info->dirname))) + && (0 == strncmp (runlevel, rc_basename (info->dirname), + strlen (runlevel)))) + return info; + } + + return NULL; +} + +bool +is_runlevel (const char *runlevel) +{ + char *runlevel_dir = NULL; + int len; + + /* strlen (RUNLEVELS_DIR) + strlen (runlevel) + "/" + '\0' */ + len = strlen (RUNLEVELS_DIR) + strlen (runlevel) + 2; + runlevel_dir = xmalloc (sizeof (char) * len); + if (NULL == runlevel_dir) + return FALSE; + + snprintf (runlevel_dir, len, "%s/%s", RUNLEVELS_DIR, runlevel); + + if (rc_is_dir (runlevel_dir, 0)) + return TRUE; + + return FALSE; +} + |