diff options
Diffstat (limited to 'src/core/depscan.c')
-rw-r--r-- | src/core/depscan.c | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/src/core/depscan.c b/src/core/depscan.c new file mode 100644 index 0000000..5030eb4 --- /dev/null +++ b/src/core/depscan.c @@ -0,0 +1,297 @@ +/* + * depscan.c + * + * Basic frontend for updating the dependency cache. + * + * 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> +#ifndef __KLIBC__ +# include <locale.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#include "debug.h" +#include "depend.h" +#include "misc.h" +#include "parse.h" + +char* svcdir_subdirs[] = { + "softscripts", + "snapshot", + "options", + "started", + "starting", + "inactive", + "stopping", + NULL +}; + +char *svcdir_volatile_subdirs[] = { + "snapshot", + "broken", + NULL +}; + +int create_directory(const char *name); +int create_var_dirs(const char *svcdir); +int delete_var_dirs(const char *svcdir); + +int create_directory(const char *name) { + if ((NULL == name) || (0 == strlen(name))) { + DBG_MSG("Invalid argument passed!\n"); + errno = EINVAL; + return -1; + } + + /* Check if directory exist, and is not a symlink */ + if (!is_dir(name, 0)) { + if (exists(name)) { + /* Remove it if not a directory */ + if (-1 == unlink(name)) { + DBG_MSG("Failed to remove '%s'!\n", name); + return -1; + } + } + /* Now try to create the directory */ + if (-1 == mktree(name, 0755)) { + DBG_MSG("Failed to create '%s'!\n", name); + return -1; + } + } + + return 0; +} + +int create_var_dirs(const char *svcdir) { + char *tmp_path = NULL; + int i = 0; + + if ((NULL == svcdir) || (0 == strlen(svcdir))) { + DBG_MSG("Invalid argument passed!\n"); + errno = EINVAL; + return -1; + } + + /* Check and create svcdir if needed */ + if (-1 == create_directory(svcdir)) { + DBG_MSG("Failed to create '%s'!\n", svcdir); + return -1; + } + + while (NULL != svcdir_subdirs[i]) { + tmp_path = strcatpaths(svcdir, svcdir_subdirs[i]); + if (NULL == tmp_path) { + DBG_MSG("Failed to allocate buffer!\n"); + return -1; + } + + /* Check and create all the subdirs if needed */ + if (-1 == create_directory(tmp_path)) { + DBG_MSG("Failed to create '%s'!\n", tmp_path); + free(tmp_path); + return -1; + } + + free(tmp_path); + i++; + } + + return 0; +} + +int delete_var_dirs(const char *svcdir) { + char *tmp_path = NULL; + int i = 0; + + if ((NULL == svcdir) || (0 == strlen(svcdir))) { + DBG_MSG("Invalid argument passed!\n"); + errno = EINVAL; + return -1; + } + + /* Just quit if svcdir do not exist */ + if (!exists(svcdir)) { + DBG_MSG("'%s' does not exist!\n", svcdir); + return 0; + } + + while (NULL != svcdir_volatile_subdirs[i]) { + tmp_path = strcatpaths(svcdir, svcdir_volatile_subdirs[i]); + if (NULL == tmp_path) { + DBG_MSG("Failed to allocate buffer!\n"); + return -1; + } + + /* Skip the directory if it does not exist */ + if (!exists(tmp_path)) + goto _continue; + + /* Check and delete all files and sub directories if needed */ + if (-1 == rmtree(tmp_path)) { + DBG_MSG("Failed to delete '%s'!\n", tmp_path); + free(tmp_path); + return -1; + } + +_continue: + free(tmp_path); + i++; + } + + return 0; +} + +#if defined(LEGACY_DEPSCAN) + +int main() { + FILE *cachefile_fd = NULL; + char *data = NULL; + char *svcdir = NULL; + char *cachefile = NULL; + char *tmp_cachefile = NULL; + int tmp_cachefile_fd = 0; + int datasize = 0; + + /* Make sure we do not run into locale issues */ +#ifndef __KLIBC__ + setlocale (LC_ALL, "C"); +#endif + + if (0 != getuid()) { + EERROR("Must be root!\n"); + exit(EXIT_FAILURE); + } + + svcdir = get_cnf_entry(RC_CONFD_FILE_NAME, SVCDIR_CONFIG_ENTRY); + if (NULL == svcdir) { + EERROR("Failed to get config entry '%s'!\n", + SVCDIR_CONFIG_ENTRY); + exit(EXIT_FAILURE); + } + + /* Delete (if needed) volatile directories in svcdir */ + if (-1 == delete_var_dirs(svcdir)) { + /* XXX: Not 100% accurate below message ... */ + EERROR("Failed to delete '%s', %s", svcdir, + "or one of its sub directories!\n"); + exit(EXIT_FAILURE); + } + + /* Create all needed directories in svcdir */ + if (-1 == create_var_dirs(svcdir)) { + EERROR("Failed to create '%s', %s", svcdir, + "or one of its sub directories!\n"); + exit(EXIT_FAILURE); + } + + cachefile = strcatpaths(svcdir, LEGACY_CACHE_FILE_NAME); + if (NULL == cachefile) { + DBG_MSG("Failed to allocate buffer!\n"); + exit(EXIT_FAILURE); + } + + tmp_cachefile = strcatpaths(cachefile, "XXXXXX"); + if (NULL == tmp_cachefile) { + DBG_MSG("Failed to allocate buffer!\n"); + exit(EXIT_FAILURE); + } + /* Replace the "/XXXXXX" with ".XXXXXX" + * Yes, I am lazy. */ + tmp_cachefile[strlen(tmp_cachefile) - strlen(".XXXXXX")] = '.'; + + if (-1 == get_rcscripts()) { + EERROR("Failed to get rc-scripts list!\n"); + exit(EXIT_FAILURE); + } + + if (-1 == check_rcscripts_mtime(cachefile)) { + EINFO("Caching service dependencies ...\n"); + DBG_MSG("Regenerating cache file '%s'.\n", cachefile); + + datasize = generate_stage2(&data); + if (-1 == datasize) { + EERROR("Failed to generate stage2!\n"); + exit(EXIT_FAILURE); + } + + if (-1 == parse_cache(data, datasize)) { + EERROR("Failed to parse stage2 output!\n"); + free(data); + exit(EXIT_FAILURE); + } + +#if 0 + tmp_cachefile_fd = open("foo", O_CREAT | O_TRUNC | O_RDWR, 0600); + write(tmp_cachefile_fd, data, datasize); + close(tmp_cachefile_fd); +#endif + + free(data); + + if (-1 == service_resolve_dependencies()) { + EERROR("Failed to resolve dependencies!\n"); + exit(EXIT_FAILURE); + } + +#ifndef __KLIBC__ + tmp_cachefile_fd = mkstemp(tmp_cachefile); +#else + /* FIXME: Need to add a mkstemp implementation for klibc */ + tmp_cachefile_fd = open(tmp_cachefile, O_CREAT | O_TRUNC | O_RDWR, 0600); +#endif + if (-1 == tmp_cachefile_fd) { + EERROR("Could not open temporary file for writing!\n"); + exit(EXIT_FAILURE); + } + cachefile_fd = fdopen(tmp_cachefile_fd, "w"); + if (NULL == cachefile_fd) { + EERROR("Could not open temporary file for writing!\n"); + exit(EXIT_FAILURE); + } + + write_legacy_stage3(cachefile_fd); + fclose(cachefile_fd); + + if ((-1 == unlink(cachefile)) && (exists(cachefile))) { + EERROR("Could not remove '%s'!\n", cachefile); + unlink(tmp_cachefile); + exit(EXIT_FAILURE); + } + + if (-1 == rename(tmp_cachefile, cachefile)) { + EERROR("Could not move temporary file to '%s'!\n", + cachefile); + unlink(tmp_cachefile); + exit(EXIT_FAILURE); + } + } + + exit(EXIT_SUCCESS); +} + +#endif + |