summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/librcscripts')
-rw-r--r--src/core/librcscripts/Makefile.am27
-rw-r--r--src/core/librcscripts/api/debug.h136
-rw-r--r--src/core/librcscripts/api/depend.h76
-rw-r--r--src/core/librcscripts/api/dynbuf.h66
-rw-r--r--src/core/librcscripts/api/list.h446
-rw-r--r--src/core/librcscripts/api/misc.h107
-rw-r--r--src/core/librcscripts/api/parse.h84
-rw-r--r--src/core/librcscripts/api/rctypes.h43
-rw-r--r--src/core/librcscripts/api/runlevels.h44
-rw-r--r--src/core/librcscripts/api/scripts.h43
-rw-r--r--src/core/librcscripts/api/simple-regex.h87
-rw-r--r--src/core/librcscripts/api/str_list.h212
-rw-r--r--src/core/librcscripts/debug.c297
-rw-r--r--src/core/librcscripts/depend.c672
-rw-r--r--src/core/librcscripts/dynbuf.c407
-rw-r--r--src/core/librcscripts/misc.c721
-rw-r--r--src/core/librcscripts/parse.c828
-rw-r--r--src/core/librcscripts/rcscripts.h72
-rw-r--r--src/core/librcscripts/runlevels.c218
-rw-r--r--src/core/librcscripts/scripts.c254
-rw-r--r--src/core/librcscripts/simple-regex.c869
21 files changed, 0 insertions, 5709 deletions
diff --git a/src/core/librcscripts/Makefile.am b/src/core/librcscripts/Makefile.am
deleted file mode 100644
index 27da323..0000000
--- a/src/core/librcscripts/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-AUTOMAKE_OPTIONS = foreign
-
-INCLUDES = $(RCSCRIPTS_DEFINES)
-
-lib_LTLIBRARIES = librcscripts.la
-
-librcscripts_la_SOURCES = \
- rcscripts.h \
- api/rctypes.h \
- debug.c \
- api/debug.h \
- misc.c \
- api/misc.h \
- api/list.h \
- api/str_list.h \
- dynbuf.c \
- api/dynbuf.h \
- simple-regex.c \
- api/simple-regex.h \
- scripts.c \
- api/scripts.h \
- runlevels.c \
- api/runlevels.h \
- parse.c \
- api/parse.h \
- depend.c \
- api/depend.h
diff --git a/src/core/librcscripts/api/debug.h b/src/core/librcscripts/api/debug.h
deleted file mode 100644
index 14e3dc6..0000000
--- a/src/core/librcscripts/api/debug.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * debug.h
- *
- * Simle debugging/logging macro's and functions.
- *
- * 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$
- */
-
-#ifndef __DEBUG_H__
-#define __DEBUG_H__
-
-#include <errno.h>
-#include <stdio.h>
-
-#define save_errno() int old_errno = errno;
-#define restore_errno() errno = old_errno;
-#define saved_errno old_errno
-
-void
-debug_message (const char *file, const char *func, int line,
- const char *format, ...);
-
-#define DBG_MSG(_format, _arg...) \
- do { \
- debug_message (__FILE__, __FUNCTION__, __LINE__, _format, ## _arg); \
- } while (0)
-
-#define FATAL_ERROR() \
- do { \
- save_errno (); \
- fprintf(stderr, "ERROR: file '%s', function '%s', line %i.\n", \
- __FILE__, __FUNCTION__, __LINE__); \
- restore_errno (); \
- if (0 != errno) \
- { \
- perror("ERROR"); \
- } \
- exit(EXIT_FAILURE); \
- } while (0)
-
-#define NEG_FATAL_ERROR(_x) \
- do { \
- if (-1 == _x) \
- { \
- FATAL_ERROR(); \
- } \
- } while (0)
-
-#define NULL_FATAL_ERROR(_x) \
- do { \
- if (NULL == _x) \
- { \
- FATAL_ERROR(); \
- } \
- } while (0)
-
-/*
- * Functions to check validity of some types.
- * They do not set errno.
- */
-
-inline bool check_ptr (const void *ptr);
-inline bool check_str (const char *str);
-inline bool check_strv (char **str);
-inline bool check_fd (int fd);
-inline bool check_fp (FILE * fp);
-
-/*
- * Functions and macro's to check validity of some types.
- * They DO set errno to EINVAL.
- */
-
-inline bool __check_arg_ptr (const void *ptr, const char *file, const char *func,
- size_t line);
-inline bool __check_arg_str (const char *str, const char *file, const char *func,
- size_t line);
-inline bool __check_arg_strv (char **str, const char *file, const char *func,
- size_t line);
-inline bool __check_arg_fd (int fd, const char *file, const char *func,
- size_t line);
-inline bool __check_arg_fp (FILE * fp, const char *file, const char *func,
- size_t line);
-
-#define check_arg_ptr(_ptr) \
- __check_arg_ptr (_ptr, __FILE__, __FUNCTION__, __LINE__)
-#define check_arg_str(_str) \
- __check_arg_str (_str, __FILE__, __FUNCTION__, __LINE__)
-#define check_arg_strv(_str) \
- __check_arg_strv (_str, __FILE__, __FUNCTION__, __LINE__)
-#define check_arg_fd(_fd) \
- __check_arg_fd (_fd, __FILE__, __FUNCTION__, __LINE__)
-#define check_arg_fp(_fp) \
- __check_arg_fp (_fp, __FILE__, __FUNCTION__, __LINE__)
-
-/*
- * Various memory allocation functions and macro's.
- * They set errno to ENOMEM and print debug info.
- */
-
-inline void *__xcalloc (size_t nmemb, size_t size, const char *file,
- const char *func, size_t line);
-inline void *__xmalloc (size_t size, const char *file, const char *func,
- size_t line);
-inline void *__xrealloc (void *ptr, size_t size, const char *file,
- const char *func, size_t line);
-
-#define xcalloc(_nmemb, _size) \
- __xcalloc (_nmemb, _size, __FILE__, __FUNCTION__, __LINE__)
-#define xmalloc(_size) \
- __xmalloc (_size, __FILE__, __FUNCTION__, __LINE__)
-#define xrealloc(_ptr, _size) \
- __xrealloc (_ptr, _size, __FILE__, __FUNCTION__, __LINE__)
-
-inline char *__xstrndup (const char *str, size_t size, const char *file,
- const char *func, size_t line);
-
-#define xstrndup(_str, _size) \
- __xstrndup (_str, _size, __FILE__, __FUNCTION__, __LINE__)
-
-#endif /* __DEBUG_H__ */
diff --git a/src/core/librcscripts/api/depend.h b/src/core/librcscripts/api/depend.h
deleted file mode 100644
index d6662c6..0000000
--- a/src/core/librcscripts/api/depend.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * depend.h
- *
- * Dependancy engine for Gentoo style rc-scripts.
- *
- * 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$
- */
-
-#ifndef __DEPEND_H__
-#define __DEPEND_H__
-
-/* Dependency types supported or still to be implemented */
-typedef enum
-{
- NEED, /* All dependencies needed by specified service */
- NEED_ME, /* All dependencies that need specified service */
- USE, /* All dependencies used by specified service */
- USE_ME, /* All dependencies that use specified service */
- BEFORE, /* All services started before specified service */
- AFTER, /* All services started after specified service */
- BROKEN, /* All dependencies of type NEED missing for
- specified service */
- PROVIDE, /* All virtual services provided by specified service */
- ALL_SERVICE_TYPE_T
-} service_type_t;
-
-/* Names for above service types (service_type_t).
- * Note that this should sync with above service_type_t */
-extern char *service_type_names[];
-
-typedef struct
-{
- struct list_head node;
-
- char *name; /* Name of service */
- char **depend_info[ALL_SERVICE_TYPE_T]; /* String lists for each service
- type */
- char *provide; /* Name of virtual service it
- provides. This is only valid
- after we resolving - thus after
- service_resolve_dependencies() */
- time_t mtime; /* Modification time of script */
-} service_info_t;
-
-struct list_head service_info_list;
-
-service_info_t *service_get_info (char *servicename);
-int service_add (char *servicename);
-int service_is_dependency (char *servicename, char *dependency,
- service_type_t type);
-int service_add_dependency (char *servicename, char *dependency,
- service_type_t type);
-int service_del_dependency (char *servicename, char *dependency,
- service_type_t type);
-service_info_t *service_get_virtual (char *virtual);
-int service_add_virtual (char *servicename, char *virtual);
-int service_set_mtime (char *servicename, time_t mtime);
-int service_resolve_dependencies (void);
-
-#endif /* __DEPEND_H__ */
diff --git a/src/core/librcscripts/api/dynbuf.h b/src/core/librcscripts/api/dynbuf.h
deleted file mode 100644
index 5c937b6..0000000
--- a/src/core/librcscripts/api/dynbuf.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * dynbuf.h
- *
- * Dynamic allocated buffers.
- *
- * 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$
- */
-
-#ifndef __DYNBUF_H__
-#define __DYNBUF_H__
-
-#define DYNAMIC_BUFFER_SIZE (sizeof (char) * 2 * 1024)
-
-typedef struct
-{
- char *data; /* Actual data */
- size_t length; /* Length of data block */
- size_t rd_index; /* Current read index */
- size_t wr_index; /* Current write index */
- bool file_map; /* File mapped as dynbuf */
-} dyn_buf_t;
-
-dyn_buf_t *new_dyn_buf (void);
-
-dyn_buf_t *new_dyn_buf_mmap_file (const char *name);
-
-void free_dyn_buf (dyn_buf_t *dynbuf);
-
-int write_dyn_buf (dyn_buf_t *dynbuf, const char *buf, size_t length);
-
-int write_dyn_buf_from_fd (int fd, dyn_buf_t *dynbuf, size_t length);
-
-int sprintf_dyn_buf (dyn_buf_t *dynbuf, const char *format, ...);
-
-int read_dyn_buf (dyn_buf_t *dynbuf, char *buf, size_t length);
-
-int read_dyn_buf_to_fd (int fd, dyn_buf_t *dynbuf, size_t length);
-
-char *read_line_dyn_buf (dyn_buf_t *dynbuf);
-
-bool dyn_buf_rd_eof (dyn_buf_t *dynbuf);
-
-inline bool check_dyn_buf (dyn_buf_t *dynbuf);
-inline bool __check_arg_dyn_buf (dyn_buf_t *dynbuf, const char *file,
- const char *func, size_t line);
-
-#define check_arg_dyn_buf(_dynbuf) \
- __check_arg_dyn_buf (_dynbuf, __FILE__, __FUNCTION__, __LINE__)
-
-#endif /* __DYNBUF_H__ */
diff --git a/src/core/librcscripts/api/list.h b/src/core/librcscripts/api/list.h
deleted file mode 100644
index e4c7a74..0000000
--- a/src/core/librcscripts/api/list.h
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copied from the Linux kernel source tree, version 2.6.0-test1.
- *
- * Licensed under the GPL v2 as per the whole kernel source tree.
- *
- * Ripped out the rcu stuff, as it's not needed.
- *
- * $Header$
- */
-
-#ifndef __LINUX_LIST_H__
-#define __LINUX_LIST_H__
-
-//#include <linux/stddef.h>
-/**
- * container_of - cast a member of a structure out to the containing structure
- *
- * @ptr: the pointer to the member.
- * @type: the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({ \
- const typeof( ((type *)0)->member ) *__mptr = (ptr); \
- (type *)( (char *)__mptr - offsetof(type,member) );})
-
-//#include <linux/prefetch.h>
-static inline void prefetch(const void *x) {;}
-
-//#include <asm/system.h>
-
-/*
- * These are non-NULL pointers that will result in page faults
- * under normal circumstances, used to verify that nobody uses
- * non-initialized list entries.
- */
-#define LIST_POISON1 ((void *) 0x00100100)
-#define LIST_POISON2 ((void *) 0x00200200)
-
-/*
- * Simple doubly linked list implementation.
- *
- * Some of the internal functions ("__xxx") are useful when
- * manipulating whole lists rather than single entries, as
- * sometimes we already know the next/prev entries and we can
- * generate better code by using them directly rather than
- * using the generic single-entry routines.
- */
-
-struct list_head {
- struct list_head *next, *prev;
-};
-
-#define LIST_HEAD_INIT(name) { &(name), &(name) }
-
-#define LIST_HEAD(name) \
- struct list_head name = LIST_HEAD_INIT(name)
-
-#define INIT_LIST_HEAD(ptr) do { \
- (ptr)->next = (ptr); (ptr)->prev = (ptr); \
-} while (0)
-
-/*
- * Insert a new entry between two known consecutive entries.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_add(struct list_head *new,
- struct list_head *prev,
- struct list_head *next)
-{
- next->prev = new;
- new->next = next;
- new->prev = prev;
- prev->next = new;
-}
-
-/**
- * list_add - add a new entry
- * @new: new entry to be added
- * @head: list head to add it after
- *
- * Insert a new entry after the specified head.
- * This is good for implementing stacks.
- */
-static inline void list_add(struct list_head *new, struct list_head *head)
-{
- __list_add(new, head, head->next);
-}
-
-/**
- * list_add_tail - add a new entry
- * @new: new entry to be added
- * @head: list head to add it before
- *
- * Insert a new entry before the specified head.
- * This is useful for implementing queues.
- */
-static inline void list_add_tail(struct list_head *new, struct list_head *head)
-{
- __list_add(new, head->prev, head);
-}
-
-/*
- * Delete a list entry by making the prev/next entries
- * point to each other.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_del(struct list_head * prev, struct list_head * next)
-{
- next->prev = prev;
- prev->next = next;
-}
-
-/**
- * list_del - deletes entry from list.
- * @entry: the element to delete from the list.
- * Note: list_empty on entry does not return true after this, the entry is
- * in an undefined state.
- */
-static inline void list_del(struct list_head *entry)
-{
- __list_del(entry->prev, entry->next);
- entry->next = LIST_POISON1;
- entry->prev = LIST_POISON2;
-}
-
-/**
- * list_del_init - deletes entry from list and reinitialize it.
- * @entry: the element to delete from the list.
- */
-static inline void list_del_init(struct list_head *entry)
-{
- __list_del(entry->prev, entry->next);
- INIT_LIST_HEAD(entry);
-}
-
-/**
- * list_move - delete from one list and add as another's head
- * @list: the entry to move
- * @head: the head that will precede our entry
- */
-static inline void list_move(struct list_head *list, struct list_head *head)
-{
- __list_del(list->prev, list->next);
- list_add(list, head);
-}
-
-/**
- * list_move_tail - delete from one list and add as another's tail
- * @list: the entry to move
- * @head: the head that will follow our entry
- */
-static inline void list_move_tail(struct list_head *list,
- struct list_head *head)
-{
- __list_del(list->prev, list->next);
- list_add_tail(list, head);
-}
-
-/**
- * list_empty - tests whether a list is empty
- * @head: the list to test.
- */
-static inline int list_empty(struct list_head *head)
-{
- return head->next == head;
-}
-
-static inline void __list_splice(struct list_head *list,
- struct list_head *head)
-{
- struct list_head *first = list->next;
- struct list_head *last = list->prev;
- struct list_head *at = head->next;
-
- first->prev = head;
- head->next = first;
-
- last->next = at;
- at->prev = last;
-}
-
-/**
- * list_splice - join two lists
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- */
-static inline void list_splice(struct list_head *list, struct list_head *head)
-{
- if (!list_empty(list))
- __list_splice(list, head);
-}
-
-/**
- * list_splice_init - join two lists and reinitialise the emptied list.
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- *
- * The list at @list is reinitialised
- */
-static inline void list_splice_init(struct list_head *list,
- struct list_head *head)
-{
- if (!list_empty(list)) {
- __list_splice(list, head);
- INIT_LIST_HEAD(list);
- }
-}
-
-/**
- * list_entry - get the struct for this entry
- * @ptr: the &struct list_head pointer.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_struct within the struct.
- */
-#define list_entry(ptr, type, member) \
- container_of(ptr, type, member)
-
-/**
- * list_for_each - iterate over a list
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- */
-#define list_for_each(pos, head) \
- for (pos = (head)->next, prefetch(pos->next); pos != (head); \
- pos = pos->next, prefetch(pos->next))
-
-/**
- * __list_for_each - iterate over a list
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- *
- * This variant differs from list_for_each() in that it's the
- * simplest possible list iteration code, no prefetching is done.
- * Use this for code that knows the list to be very short (empty
- * or 1 entry) most of the time.
- */
-#define __list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * list_for_each_prev - iterate over a list backwards
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- */
-#define list_for_each_prev(pos, head) \
- for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
- pos = pos->prev, prefetch(pos->prev))
-
-/**
- * list_for_each_safe - iterate over a list safe against removal of list entry
- * @pos: the &struct list_head to use as a loop counter.
- * @n: another &struct list_head to use as temporary storage
- * @head: the head for your list.
- */
-#define list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
-
-/**
- * list_for_each_entry - iterate over list of given type
- * @pos: the type * to use as a loop counter.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry(pos, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member), \
- prefetch(pos->member.next); \
- &pos->member != (head); \
- pos = list_entry(pos->member.next, typeof(*pos), member), \
- prefetch(pos->member.next))
-
-/**
- * list_for_each_entry_reverse - iterate backwards over list of given type.
- * @pos: the type * to use as a loop counter.
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_reverse(pos, head, member) \
- for (pos = list_entry((head)->prev, typeof(*pos), member), \
- prefetch(pos->member.prev); \
- &pos->member != (head); \
- pos = list_entry(pos->member.prev, typeof(*pos), member), \
- prefetch(pos->member.prev))
-
-
-/**
- * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @pos: the type * to use as a loop counter.
- * @n: another type * to use as temporary storage
- * @head: the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_safe(pos, n, head, member) \
- for (pos = list_entry((head)->next, typeof(*pos), member), \
- n = list_entry(pos->member.next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-/*
- * Double linked lists with a single pointer list head.
- * Mostly useful for hash tables where the two pointer list head is
- * too wasteful.
- * You lose the ability to access the tail in O(1).
- */
-
-struct hlist_head {
- struct hlist_node *first;
-};
-
-struct hlist_node {
- struct hlist_node *next, **pprev;
-};
-
-#define HLIST_HEAD_INIT { .first = NULL }
-#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
-#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
-#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)
-
-static __inline__ int hlist_unhashed(struct hlist_node *h)
-{
- return !h->pprev;
-}
-
-static __inline__ int hlist_empty(struct hlist_head *h)
-{
- return !h->first;
-}
-
-static __inline__ void __hlist_del(struct hlist_node *n)
-{
- struct hlist_node *next = n->next;
- struct hlist_node **pprev = n->pprev;
- *pprev = next;
- if (next)
- next->pprev = pprev;
-}
-
-static __inline__ void hlist_del(struct hlist_node *n)
-{
- __hlist_del(n);
- n->next = LIST_POISON1;
- n->pprev = LIST_POISON2;
-}
-
-static __inline__ void hlist_del_init(struct hlist_node *n)
-{
- if (n->pprev) {
- __hlist_del(n);
- INIT_HLIST_NODE(n);
- }
-}
-
-static __inline__ void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
-{
- struct hlist_node *first = h->first;
- n->next = first;
- if (first)
- first->pprev = &n->next;
- h->first = n;
- n->pprev = &h->first;
-}
-
-/* next must be != NULL */
-static __inline__ void hlist_add_before(struct hlist_node *n, struct hlist_node *next)
-{
- n->pprev = next->pprev;
- n->next = next;
- next->pprev = &n->next;
- *(n->pprev) = n;
-}
-
-static __inline__ void hlist_add_after(struct hlist_node *n,
- struct hlist_node *next)
-{
- next->next = n->next;
- *(next->pprev) = n;
- n->next = next;
-}
-
-#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
-
-/* Cannot easily do prefetch unfortunately */
-#define hlist_for_each(pos, head) \
- for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
- pos = pos->next)
-
-#define hlist_for_each_safe(pos, n, head) \
- for (pos = (head)->first; n = pos ? pos->next : 0, pos; \
- pos = n)
-
-/**
- * hlist_for_each_entry - iterate over list of given type
- * @tpos: the type * to use as a loop counter.
- * @pos: the &struct hlist_node to use as a loop counter.
- * @head: the head for your list.
- * @member: the name of the hlist_node within the struct.
- */
-#define hlist_for_each_entry(tpos, pos, head, member) \
- for (pos = (head)->first; \
- pos && ({ prefetch(pos->next); 1;}) && \
- ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
- pos = pos->next)
-
-/**
- * hlist_for_each_entry_continue - iterate over a hlist continuing after existing point
- * @tpos: the type * to use as a loop counter.
- * @pos: the &struct hlist_node to use as a loop counter.
- * @member: the name of the hlist_node within the struct.
- */
-#define hlist_for_each_entry_continue(tpos, pos, member) \
- for (pos = (pos)->next; \
- pos && ({ prefetch(pos->next); 1;}) && \
- ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
- pos = pos->next)
-
-/**
- * hlist_for_each_entry_from - iterate over a hlist continuing from existing point
- * @tpos: the type * to use as a loop counter.
- * @pos: the &struct hlist_node to use as a loop counter.
- * @member: the name of the hlist_node within the struct.
- */
-#define hlist_for_each_entry_from(tpos, pos, member) \
- for (; pos && ({ prefetch(pos->next); 1;}) && \
- ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
- pos = pos->next)
-
-/**
- * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @tpos: the type * to use as a loop counter.
- * @pos: the &struct hlist_node to use as a loop counter.
- * @n: another &struct hlist_node to use as temporary storage
- * @head: the head for your list.
- * @member: the name of the hlist_node within the struct.
- */
-#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
- for (pos = (head)->first; \
- pos && ({ n = pos->next; 1; }) && \
- ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
- pos = n)
-
-#endif
diff --git a/src/core/librcscripts/api/misc.h b/src/core/librcscripts/api/misc.h
deleted file mode 100644
index 67eb214..0000000
--- a/src/core/librcscripts/api/misc.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * misc.h
- *
- * Miscellaneous macro's and functions.
- *
- * 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$
- */
-
-#ifndef __MISC_H__
-#define __MISC_H__
-
-#include <stdio.h>
-
-#include "config.h"
-
-/* Gentoo style e* printing macro's */
-#define EINFO(_args...) \
- do { \
- save_errno (); \
- printf (" \033[32;01m*\033[0m " _args); \
- restore_errno (); \
- } while (0)
-
-#define EWARN(_args...) \
- do { \
- save_errno (); \
- printf (" \033[33;01m*\033[0m " _args); \
- restore_errno (); \
- } while (0)
-
-#define EERROR(_args...) \
- do { \
- save_errno (); \
- fprintf (stderr, " \033[31;01m*\033[0m " _args); \
- restore_errno (); \
- } while (0)
-
-/* Return true if filename '_name' ends in '_ext' */
-#define CHECK_FILE_EXTENSION(_name, _ext) \
- ((check_str (_name)) && (check_str (_ext)) \
- && (strlen (_name) > strlen (_ext)) \
- && (0 == strncmp (&(_name[strlen(_name) - strlen(_ext)]), \
- _ext, strlen(_ext))))
-
-/* String functions. Return a string on success, or NULL on error
- * or no action taken. On error errno will be set.*/
-char *memrepchr (char **str, char old, char _new, size_t size);
-/* Concat two paths adding '/' if needed. Memory will be allocated
- * with the malloc() call. */
-char *strcatpaths (const char *pathname1, const char *pathname2);
-
-/* Compat functions for GNU extensions */
-char *strndup (const char *str, size_t size);
-/* Same as basename(3), but do not modify path */
-char *gbasename (const char *path);
-
-/* The following functions do not care about errors - they only return
- * 1 if 'pathname' exist, and is the type requested, or else 0.
- * This is only if pathname is valid ... They also might clear errno */
-int exists (const char *pathname);
-int is_file (const char *pathname, int follow_link);
-int is_link (const char *pathname);
-int is_dir (const char *pathname, int follow_link);
-
-/* The following function do not care about errors - it only returns
- * the mtime of 'pathname' if it exists, and is the type requested,
- * or else 0. It also might clear errno */
-time_t get_mtime (const char *pathname, int follow_link);
-
-/* The following functions return 0 on success, or -1 with errno set on error. */
-#if !defined(HAVE_REMOVE)
-int remove (const char *pathname);
-#endif
-int mktree (const char *pathname, mode_t mode);
-int rmtree (const char *pathname);
-
-/* The following return a pointer on success, or NULL with errno set on error.
- * If it returned NULL, but errno is not set, then there was no error, but
- * there is nothing to return. */
-char **ls_dir (const char *pathname, int hidden);
-char *get_cnf_entry (const char *pathname, const char *entry);
-char ** get_list_file (char **list, char *filename);
-
-/* Below three functions (file_map, file_unmap and buf_get_line) are from
- * udev-050 (udev_utils.c). Please see misc.c for copyright info.
- * (Some are slightly modified, please check udev for originals.) */
-int file_map (const char *filename, char **buf, size_t * bufsize);
-void file_unmap (char *buf, size_t bufsize);
-size_t buf_get_line (char *buf, size_t buflen, size_t cur);
-
-#endif /* __MISC_H__ */
diff --git a/src/core/librcscripts/api/parse.h b/src/core/librcscripts/api/parse.h
deleted file mode 100644
index b5e07fa..0000000
--- a/src/core/librcscripts/api/parse.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * parse.h
- *
- * Parser for Gentoo style rc-scripts.
- *
- * 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$
- */
-
-#ifndef __PARSE_H__
-#define __PARSE_H__
-
-#define LEGACY_CACHE_FILE_NAME "deptree"
-
-#define FIELD_RCSCRIPT "RCSCRIPT"
-#define FIELD_NEED "NEED"
-#define FIELD_USE "USE"
-#define FIELD_BEFORE "BEFORE"
-#define FIELD_AFTER "AFTER"
-#define FIELD_PROVIDE "PROVIDE"
-#define FIELD_FAILED "FAILED"
-
-size_t generate_stage1 (dyn_buf_t *data);
-size_t generate_stage2 (dyn_buf_t *data);
-size_t read_stage2 (char **data);
-int write_stage2 (FILE * outfile);
-size_t generate_stage3 (char **data);
-size_t read_stage3 (char **data);
-int write_stage3 (FILE * outfile);
-int write_legacy_stage3 (FILE * output);
-int parse_cache (const dyn_buf_t *data);
-
-/*
- * get_rcscripts()
- * |
- * V
- * check_rcscripts_mtime() ------------------------------> read_stage3()
- * | |
- * | |
- * V V
- * generate_stage1() (Called by generate_stage2()) parse_cache()
- * | |
- * | |
- * V |
- * generate_stage2() ----> write_stage2() (Debugging) |
- * | |
- * | |
- * | === parse_cache() |
- * V | | |
- * generate_stage3() ==| | |
- * | | | |
- * | | V |
- * | === service_resolve_dependencies() |
- * | |
- * | |
- * |-------> write_legacy_stage3() (Proof of Concept |
- * | or Debugging) |
- * | |
- * V |
- * write_stage3() |
- * | |
- * | V
- * |<-------------------------------------------------------
- * |
- * V
- *
- */
-
-#endif /* __PARSE_H__ */
diff --git a/src/core/librcscripts/api/rctypes.h b/src/core/librcscripts/api/rctypes.h
deleted file mode 100644
index 6efab4a..0000000
--- a/src/core/librcscripts/api/rctypes.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * rctypes.h
- *
- * Misc types and macro's.
- *
- * 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$
- */
-
-#ifndef __RCTYPES_H__
-#define __RCTYPES_H__
-
-/* Min/Max macro's */
-#ifdef MAX
-# undef MAX
-#endif
-#define MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
-#ifdef MIN
-# undef MIN
-#endif
-#define MIN(_a, _b) ((_a) > (_b) ? (_b) : (_a))
-
-typedef enum {
- FALSE,
- TRUE
-} bool;
-
-#endif /* __RCTYPES_H__ */
diff --git a/src/core/librcscripts/api/runlevels.h b/src/core/librcscripts/api/runlevels.h
deleted file mode 100644
index ccc9ed0..0000000
--- a/src/core/librcscripts/api/runlevels.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * runlevels.h
- *
- * 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$
- */
-
-#ifndef __RUNLEVELS_H__
-#define __RUNLEVELS_H__
-
-typedef struct
-{
- struct list_head node;
-
- char *dirname; /* Name of this runlevel */
- struct list_head entries; /* rcscript_info_t list of rc-scripts */
-} runlevel_info_t;
-
-struct list_head runlevel_list;
-
-int get_runlevels (void);
-
-runlevel_info_t *get_runlevel_info (const char *runlevel);
-
-bool is_runlevel (const char *runlevel);
-
-#endif /* __RUNLEVELS_H__ */
diff --git a/src/core/librcscripts/api/scripts.h b/src/core/librcscripts/api/scripts.h
deleted file mode 100644
index 75003b4..0000000
--- a/src/core/librcscripts/api/scripts.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * scripts.h
- *
- * Get info etc for Gentoo style rc-scripts.
- *
- * 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$
- */
-
-#ifndef __SCRIPTS_H__
-#define __SCRIPTS_H__
-
-typedef struct
-{
- struct list_head node;
-
- char *filename;
- time_t mtime;
- time_t confd_mtime;
-} rcscript_info_t;
-
-struct list_head rcscript_list;
-
-int get_rcscripts (void);
-int check_rcscripts_mtime (const char *cachefile);
-rcscript_info_t *get_rcscript_info (const char *scriptname);
-
-#endif /* __SCRIPTS_H__ */
diff --git a/src/core/librcscripts/api/simple-regex.h b/src/core/librcscripts/api/simple-regex.h
deleted file mode 100644
index 1ae746f..0000000
--- a/src/core/librcscripts/api/simple-regex.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * simple_regex.h
- *
- * Simle regex library.
- *
- * 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$
- */
-
-#ifndef __SIMPLE_REGEX_H__
-#define __SIMPLE_REGEX_H__
-
-#define REGEX_NO_MATCH 0 /* We have no match */
-#define REGEX_PARTIAL_MATCH 1 /* Some of the string matches the regex */
-#define REGEX_FULL_MATCH 2 /* The whole string matches the regex */
-
-/* Macro to fill in .data and .regex */
-#define FILL_REGEX_DATA(_regex_data, _string, _regex) \
- do { \
- _regex_data.data = _string; \
- _regex_data.regex = _regex; \
- } while (0)
-
-/* Fill in _regex_data with _data and _regex, on failure goto _error */
-#define DO_REGEX(_regex_data, _data, _regex, _error) \
- do { \
- FILL_REGEX_DATA(_regex_data, _data, _regex); \
- if (-1 == match(&_regex_data)) \
- { \
- DBG_MSG("Could not do regex match!\n"); \
- goto _error; \
- } \
- } while (0)
-
-/* Evaluate to true if we have some kind of match */
-#define REGEX_MATCH(_regex_data) \
- ((REGEX_FULL_MATCH == _regex_data.match) \
- || (REGEX_PARTIAL_MATCH == _regex_data.match))
-
-/* Same as above, but for use when _regex_data is a pointer */
-#define REGEX_MATCH_P(_regex_data) \
- ((REGEX_FULL_MATCH == _regex_data->match) \
- || (REGEX_PARTIAL_MATCH == _regex_data->match))
-
-typedef struct
-{
- char *data; /* String to perform regex operation on */
- char *regex; /* String containing regex to use */
- int match; /* Will be set if there was a match. Check
- * REGEX_*_MATCH above for possible values */
- char *where; /* Pointer to where match starts in data */
- size_t count; /* Count characters from data matched by regex */
- size_t r_count; /* Count characters of regex used for match. This
- * should normally be the lenght of regex, but might
- * not be for some internal functions ... */
-} regex_data_t;
-
-/*
- * Return:
- *
- * 0 - There was no error. If there was a match, regex_data->match
- * - will be > 0 (this is the definitive check - if not true, the
- * - other values of the struct may be bogus), regex_data->count
- * - will be the amount of data that was matched (might be 0 for
- * - some wildcards), and regex_data->r_count will be > 0.
- *
- * -1 - An error occured. Check errno for more info.
- *
- */
-int match (regex_data_t * regex_data);
-
-#endif /* __SIMPLE_REGEX_H__ */
diff --git a/src/core/librcscripts/api/str_list.h b/src/core/librcscripts/api/str_list.h
deleted file mode 100644
index 538ab82..0000000
--- a/src/core/librcscripts/api/str_list.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * str_list.h
- *
- * String list macros.
- *
- * 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$
- */
-
-#ifndef __STR_LIST_H__
-#define __STR_LIST_H__
-
-/* Add a new item to a string list. If the pointer to the list is NULL,
- * allocate enough memory for the amount of entries needed. Ditto for
- * when it already exists, but we add one more entry than it can
- * contain. The list is NULL terminated.
- * NOTE: _only_ memory for the list are allocated, and not for the items - that
- * should be done by relevant code (unlike str_list_del_item() that will
- * free the memory) */
-#define str_list_add_item(_string_list, _item, _error) \
- do { \
- char **_tmp_p; \
- int _i = 0; \
- if (!check_str (_item)) \
- { \
- goto _error; \
- } \
- while ((NULL != _string_list) && (NULL != _string_list[_i])) \
- { \
- _i++; \
- } \
- /* Amount of entries + new + terminator */ \
- _tmp_p = xrealloc (_string_list, sizeof (char *) * (_i + 2)); \
- if (NULL == _tmp_p) \
- { \
- goto _error; \
- } \
- _string_list = _tmp_p; \
- _string_list[_i] = _item; \
- /* Terminator */ \
- _string_list[_i+1] = NULL; \
- } while (0)
-
-/* Add a new item to a string list (foundamental the same as above), but make
- * sure we have all the items alphabetically sorted. */
-#define str_list_add_item_sorted(_string_list, _item, _error) \
- do { \
- char **_tmp_p; \
- char *_str_p1; \
- char *_str_p2; \
- int _i = 0; \
- if (!check_str (_item)) \
- { \
- goto _error; \
- } \
- while ((NULL != _string_list) && (NULL != _string_list[_i])) \
- { \
- _i++; \
- } \
- /* Amount of entries + new + terminator */ \
- _tmp_p = xrealloc (_string_list, sizeof (char *) * (_i + 2)); \
- if (NULL == _tmp_p) \
- { \
- goto _error; \
- } \
- _string_list = _tmp_p; \
- if (0 == _i) \
- { \
- /* Needed so that the end NULL will propagate
- * (iow, make sure our 'NULL != _str_p1' test below
- * do not fail) */ \
- _string_list[_i] = NULL; \
- } \
- /* Actual terminator that needs adding */ \
- _string_list[_i+1] = NULL; \
- _i = 0; \
- /* See where we should insert the new item to have it all \
- * alphabetically sorted */ \
- while (NULL != _string_list[_i]) \
- { \
- if (strcmp (_string_list[_i], _item) > 0) \
- { \
- break; \
- } \
- _i++; \
- } \
- /* Now just insert the new item, and shift the rest one over.
- * '_str_p2' is temporary storage to swap the indexes in a loop,
- * and 'str_p1' is used to store the old value across the loop */ \
- _str_p1 = _string_list[_i]; \
- _string_list[_i] = _item; \
- do { \
- _i++;\
- _str_p2 = _string_list[_i]; \
- _string_list[_i] = _str_p1; \
- _str_p1 = _str_p2; \
- } while (NULL != _str_p1); \
- } while (0)
-
-/* Delete one entry from the string list, and shift the rest down if the entry
- * was not at the end. For now we do not resize the amount of entries the
- * string list can contain, and free the memory for the matching item */
-#define str_list_del_item(_string_list, _item, _error) \
- do { \
- int _i = 0; \
- if (!check_str (_item)) \
- { \
- goto _error; \
- } \
- if (NULL == _string_list) \
- { \
- errno = EINVAL; \
- DBG_MSG ("Invalid string list passed!\n"); \
- goto _error; \
- } \
- while (NULL != _string_list[_i]) \
- { \
- if (0 == strcmp (_item, _string_list[_i])) \
- { \
- break; \
- } \
- else \
- { \
- _i++; \
- } \
- } \
- if (NULL == _string_list[_i]) \
- { \
- errno = EINVAL; \
- DBG_MSG ("Invalid string list item passed!\n"); \
- goto _error; \
- } \
- free (_string_list[_i]); \
- /* Shift all the following items one forward */ \
- do { \
- _string_list[_i] = _string_list[_i+1]; \
- /* This stupidity is to shutup gcc */ \
- _i++; \
- } while (NULL != _string_list[_i]); \
- } while (0)
-
-/* 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 str_list_for_each_item(_string_list, _pos, _counter) \
- if ((NULL != _string_list) && (0 == (_counter = 0))) \
- while (NULL != (_pos = _string_list[_counter++]))
-
-/* Same as above (with the same warning about '_counter'). Now we just
- * have '_next' that are also used for indexing. Once again rather refrain
- * from using it if not absolutely needed. The major difference to above,
- * is that it should be safe from having the item removed from under you. */
-#define str_list_for_each_item_safe(_string_list, _pos, _next, _counter) \
- if ((NULL != _string_list) && (0 == (_counter = 0))) \
- /* First part of the while checks if this is the
- * first loop, and if so setup _pos and _next
- * and increment _counter */ \
- while ((((0 == _counter) \
- && (NULL != (_pos = _string_list[_counter])) \
- && (_pos != (_next = _string_list[++_counter]))) \
- /* Second part is when it is not the first loop
- * and _pos was not removed from under us. We
- * just increment _counter, and setup _pos and
- * _next */ \
- || ((0 != _counter) \
- && (_pos == _string_list[_counter-1]) \
- && (_next == _string_list[_counter]) \
- && (NULL != (_pos = _string_list[_counter])) \
- && (_pos != (_next = _string_list[++_counter]))) \
- /* Last part is when _pos was removed from under
- * us. We basically just setup _pos and _next,
- * but leave _counter alone */ \
- || ((0 != _counter) \
- && (_pos != _string_list[_counter-1]) \
- && (_next == _string_list[_counter-1]) \
- && (NULL != (_pos = _string_list[_counter-1])) \
- && (_pos != (_next = _string_list[_counter])))))
-
-/* Just free the whole string list */
-#define str_list_free(_string_list) \
- do { \
- if (NULL != _string_list) \
- { \
- int _i = 0; \
- while (NULL != _string_list[_i]) \
- { \
- free (_string_list[_i]); \
- _string_list[_i++] = NULL; \
- } \
- free (_string_list); \
- _string_list = NULL; \
- } \
- } while (0)
-
-#endif /* __STR_LIST_H__ */
diff --git a/src/core/librcscripts/debug.c b/src/core/librcscripts/debug.c
deleted file mode 100644
index 959ddf9..0000000
--- a/src/core/librcscripts/debug.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * debug.c
- *
- * Simle debugging/logging macro's and functions.
- *
- * 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 <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "rcscripts.h"
-
-static char log_domain[] = "rcscripts";
-
-void
-debug_message (const char *file, const char *func, int line,
- const char *format, ...)
-{
- va_list arg;
- char *format_str;
- int length;
-
- save_errno ();
-
- length = strlen (log_domain) + strlen ("(): ") + 1;
- /* Do not use xmalloc() here, else we may have recursive issues */
- format_str = malloc (length);
- if (NULL == format_str)
- {
- fprintf (stderr, "(%s) error: in %s, function %s(), line %i:\n",
- log_domain, __FILE__, __FUNCTION__, __LINE__);
- fprintf (stderr, "(%s) Failed to allocate buffer!\n",
- log_domain);
- abort ();
- }
-
- snprintf (format_str, length, "(%s) ", log_domain);
-
- va_start (arg, format);
-
-#if !defined(RC_DEBUG)
- /* Bit of a hack, as how we do things tend to cause seek
- * errors when reading the parent/child pipes */
- /* if ((0 != errno) && (ESPIPE != errno)) { */
- if (0 != saved_errno)
- {
-#endif
- if (0 != saved_errno)
- fprintf (stderr, "(%s) error: ", log_domain);
- else
- fprintf (stderr, "(%s) debug: ", log_domain);
-
- fprintf (stderr, "in %s, function %s(), line %i:\n", file, func, line);
-
- fprintf (stderr, "%s ", format_str);
- vfprintf (stderr, format, arg);
-
-#if defined(RC_DEBUG)
- if (0 != saved_errno)
- {
-#endif
- perror (format_str);
-#if defined(RC_DEBUG)
- }
-#endif
-#if !defined(RC_DEBUG)
- }
-#endif
-
- va_end (arg);
-
- free (format_str);
- restore_errno ();
-}
-
-inline bool
-check_ptr (const void *ptr)
-{
- if (NULL == ptr)
- return FALSE;
-
- return TRUE;
-}
-
-inline bool
-check_str (const char *str)
-{
- if ((NULL == str) || (0 == strlen (str)))
- return FALSE;
-
- return TRUE;
-}
-
-inline bool
-check_strv (char **str)
-{
- if ((NULL == str) || (NULL == *str) || (0 == strlen (*str)))
- return FALSE;
-
- return TRUE;
-}
-
-inline bool
-check_fd (int fd)
-{
- if ((0 >= fd) || (-1 == fcntl (fd, F_GETFL)))
- return FALSE;
-
- return TRUE;
-}
-
-inline bool
-check_fp (FILE *fp)
-{
- if ((NULL == fp) || (-1 == fileno (fp)))
- return FALSE;
-
- return TRUE;
-}
-
-inline bool
-__check_arg_ptr (const void *ptr, const char *file, const char *func, size_t line)
-{
- if (!check_ptr (ptr))
- {
- errno = EINVAL;
-
- debug_message (file, func, line, "Invalid pointer passed!\n");
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-inline bool
-__check_arg_str (const char *str, const char *file, const char *func, size_t line)
-{
- if (!check_str (str))
- {
- errno = EINVAL;
-
- debug_message (file, func, line, "Invalid string passed!\n");
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-inline bool
-__check_arg_strv (char **str, const char *file, const char *func, size_t line)
-{
- if (!check_strv (str))
- {
- errno = EINVAL;
-
- debug_message (file, func, line, "Invalid string array passed!\n");
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-inline bool
-__check_arg_fd (int fd, const char *file, const char *func, size_t line)
-{
- if (!check_fd (fd))
- {
- errno = EBADF;
-
- debug_message (file, func, line, "Invalid file descriptor passed!\n");
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-inline bool
-__check_arg_fp (FILE *fp, const char *file, const char *func, size_t line)
-{
- if (!check_fp (fp))
- {
- errno = EBADF;
-
- debug_message (file, func, line, "Invalid file descriptor passed!\n");
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-inline void *
-__xcalloc(size_t nmemb, size_t size, const char *file,
- const char *func, size_t line)
-{
- void *new_ptr;
-
- new_ptr = calloc (nmemb, size);
- if (NULL == new_ptr)
- {
- /* Set errno in case specific malloc() implementation does not */
- errno = ENOMEM;
-
- debug_message (file, func, line, "Failed to allocate buffer!\n");
-
- return NULL;
- }
-
- return new_ptr;
-}
-
-inline void *
-__xmalloc (size_t size, const char *file, const char *func, size_t line)
-{
- void *new_ptr;
-
- new_ptr = malloc (size);
- if (NULL == new_ptr)
- {
- /* Set errno in case specific malloc() implementation does not */
- errno = ENOMEM;
-
- debug_message (file, func, line, "Failed to allocate buffer!\n");
-
- return NULL;
- }
-
- return new_ptr;
-}
-
-inline void *
-__xrealloc (void *ptr, size_t size, const char *file,
- const char *func, size_t line)
-{
- void *new_ptr;
-
- new_ptr = realloc (ptr, size);
- if (NULL == new_ptr)
- {
- /* Set errno in case specific realloc() implementation does not */
- errno = ENOMEM;
-
- debug_message (file, func, line, "Failed to reallocate buffer!\n");
-
- return NULL;
- }
-
- return new_ptr;
-}
-
-inline char *
-__xstrndup (const char *str, size_t size, const char *file,
- const char *func, size_t line)
-{
- char *new_ptr;
-
- new_ptr = strndup (str, size);
- if (NULL == new_ptr)
- {
- /* Set errno in case specific realloc() implementation does not */
- errno = ENOMEM;
-
- debug_message (file, func, line,
- "Failed to duplicate string via strndup() !\n");
-
- return NULL;
- }
-
- return new_ptr;
-}
-
diff --git a/src/core/librcscripts/depend.c b/src/core/librcscripts/depend.c
deleted file mode 100644
index a5a2629..0000000
--- a/src/core/librcscripts/depend.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
- * depend.c
- *
- * Dependancy engine for Gentoo style rc-scripts.
- *
- * 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 <string.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "rcscripts.h"
-
-LIST_HEAD (service_info_list);
-
-/* Names for service types (service_type_t) in depend.h.
- * Note that this should sync with service_type_t */
-char *service_type_names[] = {
- "NEED",
- "NEED_ME",
- "USE",
- "USE_ME",
- "BEFORE",
- "AFTER",
- "BROKEN",
- "PROVIDE",
- NULL
-};
-
-static char *service_is_recursive_dependency (char *servicename,
- char *dependency,
- bool checkuse);
-static int __service_resolve_dependency (char *servicename, char *dependency,
- service_type_t type);
-
-service_info_t *
-service_get_info (char *servicename)
-{
- service_info_t *info;
-
- if (!check_arg_str (servicename))
- return NULL;
-
- list_for_each_entry (info, &service_info_list, node)
- {
- if (NULL != info->name)
- if (0 == strcmp (info->name, servicename))
- return info;
- }
-
- /* We use this to check if a service exists, so rather do not
- * add debugging, otherwise it is very noisy! */
- /* DBG_MSG("Invalid service name '%s'!\n", servicename); */
-
- return NULL;
-}
-
-int
-service_add (char *servicename)
-{
- service_info_t *info;
- service_info_t *sorted;
- int count;
-
- if (!check_arg_str (servicename))
- return -1;
-
- info = service_get_info (servicename);
- if (NULL == info)
- {
- DBG_MSG ("Adding service '%s'.\n", servicename);
-
- info = xmalloc (sizeof (service_info_t));
- if (NULL == info)
- return -1;
-
- info->name = xstrndup (servicename, strlen (servicename));
- if (NULL == info->name)
- {
- free (info);
- return -1;
- }
-
- for (count = 0; count < ALL_SERVICE_TYPE_T; count++)
- info->depend_info[count] = NULL;
- info->provide = NULL;
-
- /* We want to keep the list sorted */
- list_for_each_entry (sorted, &service_info_list, node)
- {
- if (strcmp (sorted->name, servicename) > 0)
- {
- break;
- }
- }
-
- list_add_tail (&info->node, &sorted->node);
-
- return 0;
- }
- else
- {
- DBG_MSG ("Tried to add duplicate service '%s'!\n", servicename);
- }
-
- return -1;
-}
-
-int
-service_is_dependency (char *servicename, char *dependency,
- service_type_t type)
-{
- service_info_t *info;
- char *service;
- int count = 0;
-
- if ((!check_arg_str (servicename)) || (!check_arg_str (dependency)))
- return -1;
-
- info = service_get_info (servicename);
- if (NULL != info)
- {
- str_list_for_each_item (info->depend_info[type], service, count)
- {
- if (0 == strcmp (dependency, service))
- return 0;
- }
- }
- else
- {
- DBG_MSG ("Invalid service name '%s'!\n", servicename);
- }
-
- return -1;
-}
-
-char *
-service_is_recursive_dependency (char *servicename, char *dependency,
- bool checkuse)
-{
- service_info_t *info;
- char *depend;
- int count = 0;
-
- if ((!check_arg_str (servicename)) || (!check_arg_str (dependency)))
- return NULL;
-
- info = service_get_info (dependency);
- if (NULL != info)
- {
- str_list_for_each_item (info->depend_info[NEED_ME], depend, count)
- {
- if ((0 == service_is_dependency (servicename, depend, NEED))
- || (0 == service_is_dependency (servicename, depend, USE)))
- return depend;
- }
- if (checkuse)
- {
- str_list_for_each_item (info->depend_info[USE_ME], depend, count)
- {
- if ((0 == service_is_dependency (servicename, depend, NEED))
- || (0 == service_is_dependency (servicename, depend, USE)))
- return depend;
- }
- }
- }
- else
- {
- DBG_MSG ("Invalid service name '%s'!\n", servicename);
- }
-
- return NULL;
-}
-
-int
-service_add_dependency (char *servicename, char *dependency,
- service_type_t type)
-{
- service_info_t *info;
- char *buf;
-
- if ((!check_arg_str (servicename)) || (!check_arg_str (dependency)))
- return -1;
-
- info = service_get_info (servicename);
- if (NULL != info)
- {
- /* Do not add duplicates */
- if (-1 == service_is_dependency (servicename, dependency, type))
- {
- DBG_MSG ("Adding dependency '%s' of service '%s', type '%s'.\n",
- dependency, servicename, service_type_names[type]);
-
- buf = xstrndup (dependency, strlen (dependency));
- if (NULL == buf)
- return -1;
-
- str_list_add_item_sorted (info->depend_info[type], buf, error);
- }
- else
- {
- DBG_MSG ("Duplicate dependency '%s' for service '%s', type '%s'!\n",
- dependency, servicename, service_type_names[type]);
- /* Rather do not fail here, as we add a lot of doubles
- * during resolving of dependencies */
- }
-
- return 0;
- }
- else
- {
- DBG_MSG ("Invalid service name '%s'!\n", servicename);
- }
-
-error:
- return -1;
-}
-
-int
-service_del_dependency (char *servicename, char *dependency,
- service_type_t type)
-{
- service_info_t *info;
-
- if ((!check_arg_str (servicename)) || (!check_arg_str (dependency)))
- return -1;
-
- if (-1 == service_is_dependency (servicename, dependency, type))
- {
- DBG_MSG ("Tried to remove invalid dependency '%s'!\n", dependency);
- return -1;
- }
-
- info = service_get_info (servicename);
- if (NULL != info)
- {
- DBG_MSG ("Removing dependency '%s' of service '%s', type '%s'.\n",
- dependency, servicename, service_type_names[type]);
-
- str_list_del_item (info->depend_info[type], dependency, error);
- return 0;
- }
- else
- {
- DBG_MSG ("Invalid service name '%s'!\n", servicename);
- }
-
-error:
- return -1;
-}
-
-service_info_t *
-service_get_virtual (char *virtual)
-{
- service_info_t *info;
-
- if (!check_arg_str (virtual))
- return NULL;
-
- list_for_each_entry (info, &service_info_list, node)
- {
- if (NULL != info->provide)
- if (0 == strcmp (info->provide, virtual))
- return info;
- }
-
- /* We use this to check if a virtual exists, so rather do not
- * add debugging, otherwise it is very noisy! */
- /* DBG_MSG("Invalid service name '%s'!\n", virtual); */
-
- return NULL;
-}
-
-int
-service_add_virtual (char *servicename, char *virtual)
-{
- service_info_t *info;
-
- if ((!check_arg_str (servicename)) || (!check_arg_str (virtual)))
- return -1;
-
- if (NULL != service_get_info (virtual))
- {
- EERROR
- (" Cannot add provide '%s', as a service with the same name exists!\n",
- virtual);
- /* Do not fail here as we do have a service that resolves
- * the virtual */
- }
-
- info = service_get_virtual (virtual);
- if (NULL != info)
- {
- /* We cannot have more than one service Providing a virtual */
- EWARN (" Service '%s' already provides '%s'!;\n", info->name, virtual);
- EWARN (" Not adding service '%s'...\n", servicename);
- /* Do not fail here as we do have a service that resolves
- * the virtual */
- }
- else
- {
- info = service_get_info (servicename);
- if (NULL != info)
- {
- DBG_MSG ("Adding virtual '%s' of service '%s'.\n",
- virtual, servicename);
-
- info->provide = xstrndup (virtual, strlen (virtual));
- if (NULL == info->provide)
- return -1;
- }
- else
- {
- DBG_MSG ("Invalid service name '%s'!\n", servicename);
- return -1;
- }
- }
-
- return 0;
-}
-
-int
-service_set_mtime (char *servicename, time_t mtime)
-{
- service_info_t *info;
-
- if (!check_arg_str (servicename))
- return -1;
-
- info = service_get_info (servicename);
- if (NULL != info)
- {
- DBG_MSG ("Setting mtime '%li' of service '%s'.\n", mtime, servicename);
-
- info->mtime = mtime;
-
- return 0;
- }
- else
- {
- DBG_MSG ("Invalid service name '%s'!\n", servicename);
- }
-
- return -1;
-}
-
-int
-__service_resolve_dependency (char *servicename, char *dependency,
- service_type_t type)
-{
- service_info_t *info;
- int retval;
-
- if ((!check_arg_str (servicename)) || (!check_arg_str (dependency)))
- return -1;
-
- info = service_get_info (servicename);
- if (NULL == info)
- {
- DBG_MSG ("Invalid service name passed!\n");
- return -1;
- }
-
- DBG_MSG ("Checking dependency '%s' of service '%s', type '%s'.\n",
- dependency, servicename, service_type_names[type]);
-
- /* If there are no existing service 'dependency', try to resolve
- * possible virtual services */
- info = service_get_info (dependency);
- if (NULL == info)
- {
- info = service_get_virtual (dependency);
- if (NULL != info)
- {
- DBG_MSG ("Virtual '%s' -> '%s' for service '%s', type '%s'.\n",
- dependency, info->name, servicename,
- service_type_names[type]);
-
- retval = service_del_dependency (servicename, dependency, type);
- if (-1 == retval)
- {
- DBG_MSG ("Failed to delete dependency!\n");
- return -1;
- }
-
- /* Add the actual service name for the virtual */
- dependency = info->name;
- retval = service_add_dependency (servicename, dependency, type);
- if (-1 == retval)
- {
- DBG_MSG ("Failed to add dependency!\n");
- return -1;
- }
- }
- }
-
- /* Handle 'need', as it is the only dependency type that should
- * handle invalid database entries currently. */
- if (NULL == info)
- {
- if ((type == NEED) || (type == NEED_ME))
- {
- EWARN (" Can't find service '%s' needed by '%s'; continuing...\n",
- dependency, servicename);
-
- retval = service_add_dependency (servicename, dependency, BROKEN);
- if (-1 == retval)
- {
- DBG_MSG ("Failed to add dependency!\n");
- return -1;
- }
-
- /* Delete invalid entry */
- goto remove;
- }
-
- /* For the rest, if the dependency is not 'net', just silently
- * die without error. Should not be needed as we add a 'net'
- * service manually before we start, but you never know ... */
- if (0 != strcmp (dependency, "net"))
- {
- /* Delete invalid entry */
- goto remove;
- }
- }
-
- /* Ugly bug ... if a service depends on itself, it creates a
- * 'mini fork bomb' effect, and breaks things horribly ... */
- if (0 == strcmp (servicename, dependency))
- {
- /* Dont work too well with the '*' before and after */
- if ((type != BEFORE) && (type != AFTER))
- EWARN (" Service '%s' can't depend on itself; continuing...\n",
- servicename);
-
- /* Delete invalid entry */
- goto remove;
- }
-
- /* Currently only these depend/order types are supported */
- if ((type == NEED) || (type == USE) || (type == BEFORE) || (type == AFTER))
- {
- if (type == BEFORE)
- {
- char *depend;
-
- /* NEED and USE override BEFORE
- * ('servicename' BEFORE 'dependency') */
- if ((0 == service_is_dependency (servicename, dependency, NEED))
- || (0 == service_is_dependency (servicename, dependency, USE)))
- {
- /* Delete invalid entry */
- goto remove;
- }
-
- depend = service_is_recursive_dependency (servicename, dependency,
- TRUE);
- if (NULL != depend)
- {
- EWARN (" Service '%s' should be BEFORE service '%s', but '%s'\n",
- servicename, dependency, depend);
- EWARN (" needed by '%s', depends in return on '%s'!\n",
- servicename, dependency);
-
- /* Delete invalid entry */
- goto remove;
- }
- }
-
- if (type == AFTER)
- {
- char *depend;
-
- /* NEED and USE override AFTER
- * ('servicename' AFTER 'dependency') */
- if ((0 == service_is_dependency (dependency, servicename, NEED))
- || (0 == service_is_dependency (dependency, servicename, USE)))
- {
- /* Delete invalid entry */
- goto remove;
- }
-
- depend = service_is_recursive_dependency (dependency, servicename,
- TRUE);
- if (NULL != depend)
- {
- EWARN (" Service '%s' should be AFTER service '%s', but '%s'\n",
- servicename, dependency, depend);
- EWARN (" needed by '%s', depends in return on '%s'!\n",
- dependency, servicename);
-
- /* Delete invalid entry */
- goto remove;
- }
- }
-
- /* We do not want to add circular dependencies ... */
- if (0 == service_is_dependency (dependency, servicename, type))
- {
- EWARN (" Services '%s' and '%s' have circular\n",
- servicename, dependency);
- EWARN (" dependency of type '%s'; continuing...\n",
- service_type_names[type]);
-
- /* For now remove this dependency */
- goto remove;
- }
-
- /* Reverse mapping */
- if (type == NEED)
- {
- retval = service_add_dependency (dependency, servicename, NEED_ME);
- if (-1 == retval)
- {
- DBG_MSG ("Failed to add dependency!\n");
- return -1;
- }
- }
-
- /* Reverse mapping */
- if (type == USE)
- {
- retval = service_add_dependency (dependency, servicename, USE_ME);
- if (-1 == retval)
- {
- DBG_MSG ("Failed to add dependency!\n");
- return -1;
- }
- }
-
- /* Reverse mapping */
- if (type == BEFORE)
- {
- retval = service_add_dependency (dependency, servicename, AFTER);
- if (-1 == retval)
- {
- DBG_MSG ("Failed to add dependency!\n");
- return -1;
- }
- }
-
- /* Reverse mapping */
- if (type == AFTER)
- {
- retval = service_add_dependency (dependency, servicename, BEFORE);
- if (-1 == retval)
- {
- DBG_MSG ("Failed to add dependency!\n");
- return -1;
- }
- }
- }
-
- return 0;
-
-remove:
- /* Delete invalid entry */
- DBG_MSG ("Removing invalid dependency '%s' of service '%s', type '%s'.\n",
- dependency, servicename, service_type_names[type]);
-
- retval = service_del_dependency (servicename, dependency, type);
- if (-1 == retval)
- {
- DBG_MSG ("Failed to delete dependency!\n");
- return -1;
- }
-
- /* Here we should not die with error */
- return 0;
-}
-
-int
-service_resolve_dependencies (void)
-{
- service_info_t *info;
- char *service;
- char *next = NULL;
- int count;
-
- /* Add our 'net' service */
- if (NULL == service_get_info ("net"))
- {
- if (-1 == service_add ("net"))
- {
- DBG_MSG ("Failed to add virtual!\n");
- return -1;
- }
- service_set_mtime ("net", 0);
- }
-
- /* Calculate all virtuals */
- list_for_each_entry (info, &service_info_list, node)
- {
- str_list_for_each_item_safe (info->depend_info[PROVIDE], service, next,
- count)
- {
- if (-1 == service_add_virtual (info->name, service))
- {
- DBG_MSG ("Failed to add virtual!\n");
- return -1;
- }
- }
- }
-
- /* Now do NEED, USE, BEFORE and AFTER */
- list_for_each_entry (info, &service_info_list, node)
- {
- str_list_for_each_item_safe (info->depend_info[NEED], service, next, count)
- {
- if (-1 == __service_resolve_dependency (info->name, service, NEED))
- {
- DBG_MSG ("Failed to resolve dependency!\n");
- return -1;
- }
- }
- }
- list_for_each_entry (info, &service_info_list, node)
- {
- str_list_for_each_item_safe (info->depend_info[USE], service, next, count)
- {
- if (-1 == __service_resolve_dependency (info->name, service, USE))
- {
- DBG_MSG ("Failed to resolve dependency!\n");
- return -1;
- }
- }
- }
- list_for_each_entry (info, &service_info_list, node)
- {
- str_list_for_each_item_safe (info->depend_info[BEFORE], service, next,
- count)
- {
- if (-1 == __service_resolve_dependency (info->name, service, BEFORE))
- {
- DBG_MSG ("Failed to resolve dependency!\n");
- return -1;
- }
- }
- }
- list_for_each_entry (info, &service_info_list, node)
- {
- str_list_for_each_item_safe (info->depend_info[AFTER], service, next, count)
- {
- if (-1 == __service_resolve_dependency (info->name, service, AFTER))
- {
- DBG_MSG ("Failed to resolve dependency!\n");
- return -1;
- }
- }
- }
-
- return 0;
-}
diff --git a/src/core/librcscripts/dynbuf.c b/src/core/librcscripts/dynbuf.c
deleted file mode 100644
index 5fc156e..0000000
--- a/src/core/librcscripts/dynbuf.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * dynbuf.c
- *
- * Dynamic allocated buffers.
- *
- * 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 <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "rcscripts.h"
-
-static dyn_buf_t *reallocate_dyn_buf (dyn_buf_t *dynbuf, size_t needed);
-
-dyn_buf_t *
-new_dyn_buf (void)
-{
- dyn_buf_t *dynbuf = NULL;
-
- dynbuf = xmalloc (sizeof (dyn_buf_t));
- if (NULL == dynbuf)
- return NULL;
-
- dynbuf->data = xmalloc (DYNAMIC_BUFFER_SIZE);
- if (NULL == dynbuf->data)
- {
- free (dynbuf);
- return NULL;
- }
-
- dynbuf->length = DYNAMIC_BUFFER_SIZE;
- dynbuf->rd_index = 0;
- dynbuf->wr_index = 0;
- dynbuf->file_map = FALSE;
-
- return dynbuf;
-}
-
-dyn_buf_t *
-new_dyn_buf_mmap_file (const char *name)
-{
- dyn_buf_t *dynbuf = NULL;
-
- dynbuf = xmalloc (sizeof (dyn_buf_t));
- if (NULL == dynbuf)
- return NULL;
-
- if (-1 == file_map (name, &dynbuf->data, &dynbuf->length))
- {
- DBG_MSG ("Failed to mmap file '%s'\n", name);
- free (dynbuf);
-
- return NULL;
- }
-
- dynbuf->wr_index = dynbuf->length;
- dynbuf->rd_index = 0;
- dynbuf->file_map = TRUE;
-
- return dynbuf;
-}
-
-dyn_buf_t *
-reallocate_dyn_buf (dyn_buf_t *dynbuf, size_t needed)
-{
- int len;
-
- if (!check_arg_dyn_buf (dynbuf))
- return NULL;
-
- if (dynbuf->file_map)
- {
- errno = EPERM;
- DBG_MSG ("Cannot reallocate mmap()'d file!\n");
-
- return NULL;
- }
-
- len = sizeof (char) * (dynbuf->wr_index + needed + 1);
-
- if (dynbuf->length < len)
- {
- char *new_ptr;
-
- /* Increase size in chunks to minimize reallocations */
- if (len < (dynbuf->length + DYNAMIC_BUFFER_SIZE))
- len = dynbuf->length + DYNAMIC_BUFFER_SIZE;
-
- new_ptr = xrealloc (dynbuf->data, len);
- if (NULL == new_ptr)
- return NULL;
-
- dynbuf->data = new_ptr;
- dynbuf->length = len;
- }
-
- return dynbuf;
-}
-
-void
-free_dyn_buf (dyn_buf_t *dynbuf)
-{
- if (NULL == dynbuf)
- return;
-
- if (!dynbuf->file_map)
- {
- if (NULL != dynbuf->data)
- {
- free (dynbuf->data);
- dynbuf->data = NULL;
- }
- }
- else
- {
- save_errno ();
- file_unmap (dynbuf->data, dynbuf->length);
- restore_errno ();
- }
-
- dynbuf->length = 0;
- dynbuf->rd_index = 0;
- dynbuf->wr_index = 0;
-
- free (dynbuf);
- dynbuf = NULL;
-}
-
-int
-write_dyn_buf (dyn_buf_t *dynbuf, const char *buf, size_t length)
-{
- int len;
-
- if (!check_arg_dyn_buf (dynbuf))
- return -1;
-
- if (!check_arg_str (buf))
- return -1;
-
- if (dynbuf->file_map)
- {
- errno = EPERM;
- DBG_MSG ("Cannot write to readonly mmap()'d file!\n");
-
- return -1;
- }
-
- if (NULL == reallocate_dyn_buf (dynbuf, length))
- {
- DBG_MSG ("Could not reallocate dynamic buffer!\n");
- return -1;
- }
-
- len = snprintf ((dynbuf->data + dynbuf->wr_index), length + 1, "%s", buf);
-
- /* If len is less than length, it means the string was shorter than
- * given length */
- if (length > len)
- length = len;
-
- if (0 < length)
- dynbuf->wr_index += length;
-
- if (-1 == length)
- DBG_MSG ("Failed to write to dynamic buffer!\n");
-
- return length;
-}
-
-int write_dyn_buf_from_fd (int fd, dyn_buf_t *dynbuf, size_t length)
-{
- int len = length;
-
- if (!check_arg_dyn_buf (dynbuf))
- return -1;
-
- if (!check_arg_fd (fd))
- return -1;
-
- if (dynbuf->file_map)
- {
- errno = EPERM;
- DBG_MSG ("Cannot write to readonly mmap()'d file!\n");
-
- return -1;
- }
-
- if (NULL == reallocate_dyn_buf (dynbuf, length))
- {
- DBG_MSG ("Could not reallocate dynamic buffer!\n");
- return -1;
- }
-
- len = read (fd, (dynbuf->data + dynbuf->wr_index), len);
-
- if (length > len)
- length = len;
-
- if (0 < length)
- dynbuf->wr_index += length;
-
- dynbuf->data[dynbuf->wr_index] = '\0';
-
- if (-1 == length)
- DBG_MSG ("Failed to write to dynamic buffer!\n");
-
- return length;
-}
-
-int
-sprintf_dyn_buf (dyn_buf_t *dynbuf, const char *format, ...)
-{
- va_list arg1, arg2;
- char test_str[10];
- int needed, written = 0;
-
- if (!check_arg_dyn_buf (dynbuf))
- return -1;
-
- if (!check_arg_str (format))
- return -1;
-
- if (dynbuf->file_map)
- {
- errno = EPERM;
- DBG_MSG ("Cannot write to readonly mmap()'d file!\n");
-
- return -1;
- }
-
- va_start (arg1, format);
- va_copy (arg2, arg1);
-
- /* XXX: Lame way to try and figure out how much space we need */
- needed = vsnprintf (test_str, sizeof (test_str), format, arg2);
- va_end (arg2);
-
- if (NULL == reallocate_dyn_buf (dynbuf, needed))
- {
- DBG_MSG ("Could not reallocate dynamic buffer!\n");
- return -1;
- }
-
- written = vsnprintf ((dynbuf->data + dynbuf->wr_index), needed + 1,
- format, arg1);
- va_end (arg1);
-
- if (0 < written)
- dynbuf->wr_index += written;
-
- if (-1 == written)
- DBG_MSG ("Failed to write to dynamic buffer!\n");
-
- return written;
-}
-
-int
-read_dyn_buf (dyn_buf_t *dynbuf, char *buf, size_t length)
-{
- int len = length;
-
- if (!check_arg_dyn_buf (dynbuf))
- return -1;
-
- if (!check_arg_ptr (buf))
- return -1;
-
- if (dynbuf->rd_index >= dynbuf->length)
- return 0;
-
- if (dynbuf->wr_index < (dynbuf->rd_index + length))
- len = dynbuf->wr_index - dynbuf->rd_index;
-
- len = snprintf (buf, len + 1, "%s", (dynbuf->data + dynbuf->rd_index));
-
- /* If len is less than length, it means the string was shorter than
- * given length */
- if (length > len)
- length = len;
-
- if (0 < length)
- dynbuf->rd_index += length;
-
- if (-1 == length)
- DBG_MSG ("Failed to write from dynamic buffer!\n");
-
- return length;
-}
-
-int
-read_dyn_buf_to_fd (int fd, dyn_buf_t *dynbuf, size_t length)
-{
- int len = length;
-
- if (!check_arg_dyn_buf (dynbuf))
- return -1;
-
- if (!check_arg_fd (fd))
- return -1;
-
- if (dynbuf->rd_index >= dynbuf->length)
- return 0;
-
- if (dynbuf->wr_index < (dynbuf->rd_index + length))
- len = dynbuf->wr_index - dynbuf->rd_index;
-
- len = write (fd, (dynbuf->data + dynbuf->rd_index), len);
- if (length > len)
- length = len;
-
- if (0 < length)
- dynbuf->rd_index += length;
-
- if (-1 == length)
- DBG_MSG ("Failed to write from dynamic buffer!\n");
-
- return length;
-}
-
-char *
-read_line_dyn_buf (dyn_buf_t *dynbuf)
-{
- char *buf = NULL;
- size_t count = 0;
-
- if (!check_arg_dyn_buf (dynbuf))
- return NULL;
-
- if (dynbuf->rd_index == dynbuf->wr_index)
- return NULL;
-
- for (count = dynbuf->rd_index; count < dynbuf->wr_index && dynbuf->data[count] != '\n'; count++);
-
- if (count <= dynbuf->wr_index)
- {
- buf = xstrndup ((dynbuf->data + dynbuf->rd_index),
- (count - dynbuf->rd_index));
- if (NULL == buf)
- return NULL;
-
- dynbuf->rd_index = count;
-
- /* Also skip the '\n' .. */
- if (dynbuf->rd_index < dynbuf->wr_index)
- dynbuf->rd_index++;
- }
-
- return buf;
-}
-
-bool
-dyn_buf_rd_eof (dyn_buf_t *dynbuf)
-{
- if (!check_arg_dyn_buf (dynbuf))
- return FALSE;
-
- if (dynbuf->rd_index >= dynbuf->wr_index)
- return TRUE;
-
- return FALSE;
-}
-
-inline bool
-check_dyn_buf (dyn_buf_t *dynbuf)
-{
- if ((NULL == dynbuf) || (NULL == dynbuf->data) || (0 == dynbuf->length))
- return FALSE;
-
- return TRUE;
-}
-
-inline bool
-__check_arg_dyn_buf (dyn_buf_t *dynbuf, const char *file, const char *func,
- size_t line)
-{
- if (!check_dyn_buf (dynbuf))
- {
- errno = EINVAL;
-
- debug_message (file, func, line, "Invalid dynamic buffer passed!\n");
-
- return FALSE;
- }
-
- return TRUE;
-}
-
diff --git a/src/core/librcscripts/misc.c b/src/core/librcscripts/misc.c
deleted file mode 100644
index 37edc5f..0000000
--- a/src/core/librcscripts/misc.c
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * misc.c
- *
- * Miscellaneous macro's and functions.
- *
- * 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 <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "rcscripts.h"
-
-char *
-memrepchr (char **str, char old, char new, size_t size)
-{
- char *str_p;
-
- if (!check_arg_strv (str))
- return NULL;
-
- str_p = memchr (*str, old, size);
-
- while (NULL != str_p)
- {
- str_p[0] = new;
- str_p = memchr (&str_p[1], old, size - (str_p - *str) - 1);
- }
-
- return *str;
-}
-
-char *
-strcatpaths (const char *pathname1, const char *pathname2)
-{
- char *new_path = NULL;
- int lenght;
-
- if ((!check_arg_str (pathname1)) || (!check_arg_str (pathname2)))
- return 0;
-
- /* Lenght of pathname1 + lenght of pathname2 + '/' if needed */
- lenght = strlen (pathname1) + strlen (pathname2) + 2;
- /* lenght + '\0' */
- new_path = xmalloc (lenght);
- if (NULL == new_path)
- return NULL;
-
- snprintf (new_path, lenght, "%s%s%s", pathname1,
- (new_path[strlen (new_path) - 1] != '/') ? "/" : "",
- pathname2);
-
- return new_path;
-}
-
-char *
-strndup (const char *str, size_t size)
-{
- char *new_str = NULL;
- size_t len;
-
- /* We cannot check if its a valid string here, as it might
- * not be '\0' terminated ... */
- if (!check_arg_ptr (str))
- return NULL;
-
- /* Check lenght of str without breaching the size limit */
- for (len = 0; (len < size) && ('\0' != str[len]); len++);
-
- new_str = xmalloc (len + 1);
- if (NULL == new_str)
- return NULL;
-
- /* Make sure our string is NULL terminated */
- new_str[len] = '\0';
-
- return (char *) memcpy (new_str, str, len);
-}
-
-char *
-gbasename (const char *path)
-{
- char *new_path = NULL;
-
- if (!check_arg_str (path))
- return NULL;
-
- /* Copied from glibc */
- new_path = strrchr (path, '/');
- return new_path ? new_path + 1 : (char *) path;
-}
-
-
-int
-exists (const char *pathname)
-{
- struct stat buf;
- int retval;
-
- if (!check_arg_str (pathname))
- return -1;
-
- retval = lstat (pathname, &buf);
- if (-1 != retval)
- return 1;
-
- /* Clear errno, as we do not want debugging to trigger */
- errno = 0;
-
- return 0;
-}
-
-int
-is_file (const char *pathname, int follow_link)
-{
- struct stat buf;
- int retval;
-
- if (!check_arg_str (pathname))
- return -1;
-
- retval = follow_link ? stat (pathname, &buf) : lstat (pathname, &buf);
- if ((-1 != retval) && (S_ISREG (buf.st_mode)))
- return 1;
-
- /* Clear errno, as we do not want debugging to trigger */
- errno = 0;
-
- return 0;
-}
-
-int
-is_link (const char *pathname)
-{
- struct stat buf;
- int retval;
-
- if (!check_arg_str (pathname))
- return -1;
-
- retval = lstat (pathname, &buf);
- if ((-1 != retval) && (S_ISLNK (buf.st_mode)))
- return 1;
-
- /* Clear errno, as we do not want debugging to trigger */
- errno = 0;
-
- return 0;
-}
-
-int
-is_dir (const char *pathname, int follow_link)
-{
- struct stat buf;
- int retval;
-
- if (!check_arg_str (pathname))
- return -1;
-
- retval = follow_link ? stat (pathname, &buf) : lstat (pathname, &buf);
- if ((-1 != retval) && (S_ISDIR (buf.st_mode)))
- return 1;
-
- /* Clear errno, as we do not want debugging to trigger */
- errno = 0;
-
- return 0;
-}
-
-time_t
-get_mtime (const char *pathname, int follow_link)
-{
- struct stat buf;
- int retval;
-
- if (!check_arg_str (pathname))
- return -1;
-
- retval = follow_link ? stat (pathname, &buf) : lstat (pathname, &buf);
- if (-1 != retval)
- return buf.st_mtime;
-
- /* Clear errno, as we do not want debugging to trigger */
- errno = 0;
-
- return 0;
-}
-
-#if !defined(HAVE_REMOVE)
-int
-remove (const char *pathname)
-{
- int retval;
-
- if (!check_arg_str (pathname))
- return -1;
-
- if (1 == is_dir (pathname, 0))
- retval = rmdir (pathname);
- else
- retval = unlink (pathname);
-
- return retval;
-}
-#endif
-
-int
-mktree (const char *pathname, mode_t mode)
-{
- char *temp_name = NULL;
- char *temp_token = NULL;
- char *token_p;
- char *token;
- int retval;
- int lenght;
-
- if (!check_arg_str (pathname))
- return -1;
-
- /* Lenght of 'pathname' + extra for "./" if needed */
- lenght = strlen (pathname) + 2;
- /* lenght + '\0' */
- temp_name = xmalloc (lenght + 1);
- if (NULL == temp_name)
- return -1;
-
- temp_token = xstrndup (pathname, strlen (pathname));
- if (NULL == temp_token)
- goto error;
-
- token_p = temp_token;
-
- if (pathname[0] == '/')
- temp_name[0] = '\0';
- else
- /* If not an absolute path, make it local */
- strncpy (temp_name, ".", lenght);
-
- token = strsep (&token_p, "/");
- /* First token might be "", but that is OK as it will be when the
- * pathname starts with '/' */
- while (NULL != token)
- {
- strncat (temp_name, "/", lenght - strlen (temp_name));
- strncat (temp_name, token, lenght - strlen (temp_name));
-
- /* If it does not exist, create the dir. If it does exit,
- * but is not a directory, we will catch it below. */
- if (1 != exists (temp_name))
- {
- retval = mkdir (temp_name, mode);
- if (-1 == retval)
- {
- DBG_MSG ("Failed to create directory!\n");
- goto error;
- }
- /* Not a directory or symlink pointing to a directory */
- }
- else if (1 != is_dir (temp_name, 1))
- {
- errno = ENOTDIR;
- DBG_MSG ("Component in pathname is not a directory!\n");
- goto error;
- }
-
- do
- {
- token = strsep (&token_p, "/");
- /* The first "" was Ok, but rather skip double '/' after that */
- }
- while ((NULL != token) && (0 == strlen (token)));
- }
-
- free (temp_name);
- free (temp_token);
-
- return 0;
-
-error:
- free (temp_name);
- free (temp_token);
-
- return -1;
-}
-
-int
-rmtree (const char *pathname)
-{
- char **dirlist = NULL;
- int i = 0;
-
- if (!check_arg_str (pathname))
- return -1;
-
- if (1 != exists (pathname))
- {
- errno = ENOENT;
- DBG_MSG ("'%s' does not exists!\n", pathname);
- return -1;
- }
-
- dirlist = ls_dir (pathname, 1);
- if ((NULL == dirlist) && (0 != errno))
- {
- /* Do not error out - caller should decide itself if it
- * it is an issue */
- DBG_MSG ("Could not get listing for '%s'!\n", pathname);
- return -1;
- }
-
- while ((NULL != dirlist) && (NULL != dirlist[i]))
- {
- /* If it is a directory, call rmtree() again with
- * it as argument */
- if (1 == is_dir (dirlist[i], 0))
- {
- if (-1 == rmtree (dirlist[i]))
- {
- DBG_MSG ("Failed to delete sub directory!\n");
- goto error;
- }
- }
-
- /* Now actually remove it. Note that if it was a directory,
- * it should already be removed by above rmtree() call */
- if ((1 == exists (dirlist[i]) && (-1 == remove (dirlist[i]))))
- {
- DBG_MSG ("Failed to remove '%s'!\n", dirlist[i]);
- goto error;
- }
- i++;
- }
-
- str_list_free (dirlist);
-
- /* Now remove the parent */
- if (-1 == remove (pathname))
- {
- DBG_MSG ("Failed to remove '%s'!\n", pathname);
- goto error;
- }
-
- return 0;
-error:
- str_list_free (dirlist);
-
- return -1;
-}
-
-char **
-ls_dir (const char *pathname, int hidden)
-{
- DIR *dp;
- struct dirent *dir_entry;
- char **dirlist = NULL;
-
- if (!check_arg_str (pathname))
- return NULL;
-
- dp = opendir (pathname);
- if (NULL == dp)
- {
- DBG_MSG ("Failed to call opendir()!\n");
- /* errno will be set by opendir() */
- goto error;
- }
-
- do
- {
- /* Clear errno to distinguish between EOF and error */
- errno = 0;
- dir_entry = readdir (dp);
- /* Only an error if 'errno' != 0, else EOF */
- if ((NULL == dir_entry) && (0 != errno))
- {
- DBG_MSG ("Failed to call readdir()!\n");
- goto error;
- }
- if ((NULL != dir_entry)
- /* Should we display hidden files? */
- && (hidden ? 1 : dir_entry->d_name[0] != '.'))
- {
- char *d_name = dir_entry->d_name;
- char *str_ptr;
-
- /* Do not list current or parent entries */
- if ((0 == strcmp (d_name, ".")) || (0 == strcmp (d_name, "..")))
- continue;
-
- str_ptr = strcatpaths (pathname, d_name);
- if (NULL == str_ptr)
- {
- DBG_MSG ("Failed to allocate buffer!\n");
- goto error;
- }
-
- str_list_add_item (dirlist, str_ptr, error);
- }
- }
- while (NULL != dir_entry);
-
- if (!check_strv (dirlist))
- {
- if (NULL != dirlist)
- str_list_free (dirlist);
-
- DBG_MSG ("Directory is empty.\n");
- }
-
- closedir (dp);
-
- return dirlist;
-
-error:
- /* Free dirlist on error */
- str_list_free (dirlist);
-
- if (NULL != dp)
- {
- save_errno ();
- closedir (dp);
- /* closedir() might have changed it */
- restore_errno ();
- }
-
- return NULL;
-}
-
-/* This handles simple 'entry="bar"' type variables. If it is more complex
- * ('entry="$(pwd)"' or such), it will obviously not work, but current behaviour
- * should be fine for the type of variables we want. */
-char *
-get_cnf_entry (const char *pathname, const char *entry)
-{
- dyn_buf_t *dynbuf = NULL;
- char *buf = NULL;
- char *str_ptr;
- char *value = NULL;
- char *token;
-
-
- if ((!check_arg_str (pathname)) || (!check_arg_str (entry)))
- return NULL;
-
- /* If it is not a file or symlink pointing to a file, bail */
- if (1 != is_file (pathname, 1))
- {
- errno = ENOENT;
- DBG_MSG ("Given pathname is not a file or do not exist!\n");
- return NULL;
- }
-
- dynbuf = new_dyn_buf_mmap_file (pathname);
- if (NULL == dynbuf)
- {
- DBG_MSG ("Could not open config file for reading!\n");
- return NULL;
- }
-
- while (NULL != (buf = read_line_dyn_buf (dynbuf)))
- {
- str_ptr = buf;
-
- /* Strip leading spaces/tabs */
- while ((str_ptr[0] == ' ') || (str_ptr[0] == '\t'))
- str_ptr++;
-
- /* Get entry and value */
- token = strsep (&str_ptr, "=");
- /* Bogus entry or value */
- if (NULL == token)
- goto _continue;
-
- /* Make sure we have a string that is larger than 'entry', and
- * the first part equals 'entry' */
- if ((strlen (token) > 0) && (0 == strcmp (entry, token)))
- {
- do
- {
- /* Bash variables are usually quoted */
- token = strsep (&str_ptr, "\"\'");
- /* If quoted, the first match will be "" */
- }
- while ((NULL != token) && (0 == strlen (token)));
-
- /* We have a 'entry='. We respect bash rules, so NULL
- * value for now (if not already) */
- if (NULL == token)
- {
- /* We might have 'entry=' and later 'entry="bar"',
- * so just continue for now ... we will handle
- * it below when 'value == NULL' */
- if (NULL != value)
- {
- free (value);
- value = NULL;
- }
- goto _continue;
- }
-
- /* If we have already allocated 'value', free it */
- if (NULL != value)
- free (value);
-
- value = xstrndup (token, strlen (token));
- if (NULL == value)
- {
- free_dyn_buf (dynbuf);
- free (buf);
-
- return NULL;
- }
-
- /* We do not break, as there might be more than one entry
- * defined, and as bash uses the last, so should we */
- /* break; */
- }
-
-_continue:
- free (buf);
- }
-
- /* read_line_dyn_buf() returned NULL with errno set */
- if ((NULL == buf) && (0 != errno))
- {
- DBG_MSG ("Failed to read line from dynamic buffer!\n");
- free_dyn_buf (dynbuf);
- if (NULL != value)
- free (value);
-
- return NULL;
- }
-
-
- if (NULL == value)
- DBG_MSG ("Failed to get value for config entry '%s'!\n", entry);
-
- free_dyn_buf (dynbuf);
-
- return value;
-}
-
-char **
-get_list_file (char **list, char *filename)
-{
- dyn_buf_t *dynbuf = NULL;
- char *buf = NULL;
- char *tmp_p = NULL;
- char *token = NULL;
-
- if (!check_arg_str (filename))
- return NULL;
-
- dynbuf = new_dyn_buf_mmap_file (filename);
- if (NULL == dynbuf)
- return NULL;
-
- while (NULL != (buf = read_line_dyn_buf (dynbuf)))
- {
- tmp_p = buf;
-
- /* Strip leading spaces/tabs */
- while ((tmp_p[0] == ' ') || (tmp_p[0] == '\t'))
- tmp_p++;
-
- /* Get entry - we do not want comments, and only the first word
- * on a line is valid */
- token = strsep (&tmp_p, "# \t");
- if (check_str (token))
- {
- tmp_p = xstrndup (token, strlen (token));
- if (NULL == tmp_p)
- {
- if (NULL != list)
- str_list_free (list);
- free_dyn_buf (dynbuf);
- free (buf);
-
- return NULL;
- }
-
- str_list_add_item (list, tmp_p, error);
- }
-
- free (buf);
- }
-
- /* read_line_dyn_buf() returned NULL with errno set */
- if ((NULL == buf) && (0 != errno))
- {
- DBG_MSG ("Failed to read line from dynamic buffer!\n");
-error:
- if (NULL != list)
- str_list_free (list);
- free_dyn_buf (dynbuf);
-
- return NULL;
- }
-
- free_dyn_buf (dynbuf);
-
- return list;
-}
-
-
-/*
- * Below three functions (file_map, file_unmap and buf_get_line) are
- * from udev-050 (udev_utils.c).
- * (Some are slightly modified, please check udev for originals.)
- *
- * Copyright (C) 2004 Kay Sievers <kay@vrfy.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.
- *
- */
-
-int
-file_map (const char *filename, char **buf, size_t * bufsize)
-{
- struct stat stats;
- int fd;
-
- fd = open (filename, O_RDONLY);
- if (fd < 0)
- {
- DBG_MSG ("Failed to open file!\n");
- return -1;
- }
-
- if (fstat (fd, &stats) < 0)
- {
- DBG_MSG ("Failed to stat file!\n");
-
- save_errno ();
- close (fd);
- restore_errno ();
-
- return -1;
- }
-
- if (0 == stats.st_size)
- {
- errno = EINVAL;
- DBG_MSG ("Failed to mmap file with 0 size!\n");
-
- save_errno ();
- close (fd);
- restore_errno ();
-
- return -1;
- }
-
- *buf = mmap (NULL, stats.st_size, PROT_READ, MAP_SHARED, fd, 0);
- if (*buf == MAP_FAILED)
- {
- DBG_MSG ("Failed to mmap file!\n");
-
- save_errno ();
- close (fd);
- restore_errno ();
-
- return -1;
- }
- *bufsize = stats.st_size;
-
- close (fd);
-
- return 0;
-}
-
-void
-file_unmap (char *buf, size_t bufsize)
-{
- munmap (buf, bufsize);
-}
-
-size_t
-buf_get_line (char *buf, size_t buflen, size_t cur)
-{
- size_t count = 0;
-
- for (count = cur; count < buflen && buf[count] != '\n'; count++);
-
- return count - cur;
-}
diff --git a/src/core/librcscripts/parse.c b/src/core/librcscripts/parse.c
deleted file mode 100644
index 2711c3b..0000000
--- a/src/core/librcscripts/parse.c
+++ /dev/null
@@ -1,828 +0,0 @@
-/*
- * parse.c
- *
- * Parser for Gentoo style rc-scripts.
- *
- * 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 <string.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/poll.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-
-#include "rcscripts.h"
-
-#define READ_PIPE 0
-#define WRITE_PIPE 1
-
-/* _pipe[0] is used to send data to the parent (thus the parent only use the
- * read pipe, and the child uses the write pipe)
- * _pipe[1] is used to send data to the child (thus the child only use the read
- * pipe, and the parent uses the write pipe)
- */
-#define PARENT_READ_PIPE(_pipe) (_pipe[0][READ_PIPE])
-#define PARENT_WRITE_PIPE(_pipe) (_pipe[1][WRITE_PIPE])
-#define CHILD_READ_PIPE(_pipe) (_pipe[1][READ_PIPE])
-#define CHILD_WRITE_PIPE(_pipe) (_pipe[0][WRITE_PIPE])
-
-#define PARSE_BUFFER_SIZE 256
-
-static size_t parse_rcscript (char *scriptname, dyn_buf_t *data);
-
-static size_t parse_print_start (dyn_buf_t *data);
-static size_t parse_print_header (char *scriptname, dyn_buf_t *data);
-static size_t parse_print_body (char *scriptname, dyn_buf_t *data);
-
-/* Return count on success, -1 on error. If it was critical, errno will be set. */
-size_t
-parse_rcscript (char *scriptname, dyn_buf_t *data)
-{
- regex_data_t tmp_data;
- dyn_buf_t *dynbuf = NULL;
- char *buf = NULL;
- size_t write_count = 0;
- size_t tmp_count;
-
- if (!check_arg_dyn_buf (data))
- return -1;
-
- if (!check_arg_str (scriptname))
- return -1;
-
- dynbuf = new_dyn_buf_mmap_file (scriptname);
- if (NULL == dynbuf)
- {
- DBG_MSG ("Could not open '%s' for reading!\n", gbasename (scriptname));
- return -1;
- }
-
- DBG_MSG ("Parsing '%s'.\n", gbasename (scriptname));
-
- tmp_count = parse_print_header (gbasename (scriptname), data);
- if (-1 == tmp_count)
- {
- DBG_MSG ("Failed to call parse_print_header()!\n");
- goto error;
- }
- write_count += tmp_count;
-
- while (NULL != (buf = read_line_dyn_buf(dynbuf)))
- {
- /* Check for lines with comments, and skip them */
- DO_REGEX (tmp_data, buf, "^[ \t]*#", error);
- if (REGEX_MATCH (tmp_data))
- {
- free (buf);
- continue;
- }
-
- /* If the line contains 'depend()', call parse_print_body () and break */
- DO_REGEX (tmp_data, buf, "depend[ \t]*()[ \t]*{?", error);
- if (REGEX_MATCH (tmp_data))
- {
- DBG_MSG ("Got 'depend()' function.\n");
-
- tmp_count = parse_print_body (gbasename (scriptname), data);
- if (-1 == tmp_count)
- {
- DBG_MSG ("Failed to call parse_print_body()!\n");
- goto error;
- }
-
- write_count += tmp_count;
-
- /* This is the last loop */
- free (buf);
- break;
- }
-
- free (buf);
- }
-
- /* read_line_dyn_buf() returned NULL with errno set */
- if ((NULL == buf) && (0 != errno))
- {
- DBG_MSG ("Failed to read line from dynamic buffer!\n");
- free_dyn_buf (dynbuf);
-
- return -1;
- }
-
- free_dyn_buf (dynbuf);
-
- return write_count;
-
-error:
- if (NULL != buf)
- free (buf);
- if (NULL != dynbuf)
- free_dyn_buf (dynbuf);
-
- return -1;
-}
-
-
-size_t
-generate_stage1 (dyn_buf_t *data)
-{
- rcscript_info_t *info;
- size_t write_count = 0;
- size_t tmp_count;
-
- if (!check_arg_dyn_buf (data))
- return -1;
-
- write_count = parse_print_start (data);
- if (-1 == write_count)
- {
- DBG_MSG ("Failed to call parse_print_start()!\n");
- return -1;
- }
-
- list_for_each_entry (info, &rcscript_list, node)
- {
- tmp_count = parse_rcscript (info->filename, data);
- if (-1 == tmp_count)
- {
- DBG_MSG ("Failed to parse '%s'!\n", gbasename (info->filename));
-
- /* If 'errno' is set, it is critical (hopefully) */
- if (0 != errno)
- return -1;
- }
- else
- {
- write_count += tmp_count;
- }
- }
-
- return write_count;
-}
-
-/* Empty signal handler for SIGPIPE */
-static void
-sig_handler (int signum)
-{
- return;
-}
-
-/* Returns data's lenght on success, else -1 on error. */
-size_t
-generate_stage2 (dyn_buf_t *data)
-{
- int pipe_fds[2][2] = { {0, 0}, {0, 0} };
- pid_t child_pid;
- size_t write_count = 0;
- int old_errno = 0;
-
- if (!check_arg_dyn_buf (data))
- return -1;
-
- /* Pipe to send data to parent */
- if (-1 == pipe (pipe_fds[0]))
- {
- DBG_MSG ("Failed to open pipe!\n");
- goto error;
- }
- /* Pipe to send data to child */
- if (-1 == pipe (pipe_fds[1]))
- {
- DBG_MSG ("Failed to open pipe!\n");
- /* Close parent_pfds */
- goto error;
- }
-
- child_pid = fork ();
- if (-1 == child_pid)
- {
- DBG_MSG ("Failed to fork()!\n");
- /* Close all pipes */
- goto error;
- }
- if (0 == child_pid)
- {
- /***
- *** In child
- ***/
-
- char *const argv[] = {
- "bash",
- "--noprofile",
- "--norc",
- "--",
- NULL
- };
-
- /* Close the sides of the pipes we do not use */
- close (PARENT_WRITE_PIPE (pipe_fds));
- close (PARENT_READ_PIPE (pipe_fds));
-
- /* dup2 child side read pipe to STDIN */
- dup2 (CHILD_READ_PIPE (pipe_fds), STDIN_FILENO);
- /* dup2 child side write pipe to STDOUT */
- dup2 (CHILD_WRITE_PIPE (pipe_fds), STDOUT_FILENO);
-
- /* We need to be in RCSCRIPTS_INITDDIR for 'before'/'after' '*' to work */
- if (-1 == chdir (RCSCRIPTS_INITDDIR))
- {
- DBG_MSG ("Failed to chdir to '%s'!\n", RCSCRIPTS_INITDDIR);
- exit (EXIT_FAILURE);
- }
-
- if (-1 == execv (SHELL_PARSER, argv))
- {
- DBG_MSG ("Failed to execv %s!\n", SHELL_PARSER);
- exit (EXIT_FAILURE);
- }
- }
- else
- {
- /***
- *** In parent
- ***/
-
- dyn_buf_t *stage1_data;
- struct sigaction act_new;
- struct sigaction act_old;
- struct pollfd poll_fds[2];
- int status = 0;
-
- DBG_MSG ("Child pid = %i\n", child_pid);
-
- /* Set signal handler for SIGPIPE to empty in case bash errors
- * out. It will then close the write pipe, and instead of us
- * getting SIGPIPE, we can handle the write error like normal.
- */
- memset (&act_new, 0x00, sizeof (act_new));
- act_new.sa_handler = (void (*)(int)) sig_handler;
- sigemptyset (&act_new.sa_mask);
- act_new.sa_flags = 0;
- sigaction (SIGPIPE, &act_new, &act_old);
-
- /* Close the sides of the pipes we do not use */
- close (CHILD_WRITE_PIPE (pipe_fds));
- CHILD_WRITE_PIPE (pipe_fds) = 0;
- close (CHILD_READ_PIPE (pipe_fds));
- CHILD_READ_PIPE (pipe_fds) = 0;
-
- stage1_data = new_dyn_buf ();
- if (NULL == stage1_data)
- {
- DBG_MSG ("Failed to allocate dynamic buffer!\n");
- goto error;
- }
-
- /* Pipe parse_rcscripts() to bash */
- if (-1 == generate_stage1 (stage1_data))
- {
- DBG_MSG ("Failed to generate stage1!\n");
- goto error;
- }
-
-#if 0
- int tmp_fd = open ("bar", O_CREAT | O_TRUNC | O_RDWR, 0600);
- write (tmp_fd, stage1_data->data, stage1_data->wr_index);
- close (tmp_fd);
-#endif
-
- do
- {
- int tmp_count = 0;
- int do_write = 0;
- int do_read = 0;
-
- /* Check if we can write or read */
- poll_fds[WRITE_PIPE].fd = PARENT_WRITE_PIPE (pipe_fds);
- poll_fds[WRITE_PIPE].events = POLLOUT;
- poll_fds[READ_PIPE].fd = PARENT_READ_PIPE (pipe_fds);
- poll_fds[READ_PIPE].events = POLLIN | POLLPRI;
- if (!dyn_buf_rd_eof (stage1_data))
- {
- poll (poll_fds, 2, -1);
- if (poll_fds[WRITE_PIPE].revents & POLLOUT)
- do_write = 1;
- }
- else
- {
- poll (&(poll_fds[READ_PIPE]), 1, -1);
- }
- if ((poll_fds[READ_PIPE].revents & POLLIN)
- || (poll_fds[READ_PIPE].revents & POLLPRI))
- do_read = 1;
-
- do
- {
- /* While we can write, or there is nothing to
- * read, keep feeding the write pipe */
- if ((dyn_buf_rd_eof (stage1_data))
- || (1 == do_read)
- || (1 != do_write))
- break;
-
- tmp_count = read_dyn_buf_to_fd (PARENT_WRITE_PIPE (pipe_fds),
- stage1_data, PARSE_BUFFER_SIZE);
- if ((-1 == tmp_count) && (EINTR != errno))
- {
- DBG_MSG ("Error writing to PARENT_WRITE_PIPE!\n");
- goto failed;
- }
- /* We were interrupted, try to write again */
- if (-1 == tmp_count)
- {
- errno = 0;
- /* Make sure we retry */
- tmp_count = 1;
- continue;
- }
-
- /* Close the write pipe if we done
- * writing to get a EOF signaled to
- * bash */
- if (dyn_buf_rd_eof (stage1_data))
- {
- close (PARENT_WRITE_PIPE (pipe_fds));
- PARENT_WRITE_PIPE (pipe_fds) = 0;
- }
- }
- while ((tmp_count > 0) && (!dyn_buf_rd_eof (stage1_data)));
-
- /* Reset tmp_count for below read loop */
- tmp_count = 0;
-
- do
- {
- if (1 != do_read)
- continue;
-
- tmp_count = write_dyn_buf_from_fd (PARENT_READ_PIPE (pipe_fds),
- data, PARSE_BUFFER_SIZE);
- if ((-1 == tmp_count) && (EINTR != errno))
- {
- DBG_MSG ("Error reading PARENT_READ_PIPE!\n");
- goto failed;
- }
- /* We were interrupted, try to read again */
- if ((-1 == tmp_count) || (0 == tmp_count))
- {
- errno = 0;
- continue;
- }
-
- write_count += tmp_count;
- }
- while (tmp_count > 0);
- }
- while (!(poll_fds[READ_PIPE].revents & POLLHUP));
-
-failed:
- /* Set old_errno to disable child exit code checking below */
- if (0 != errno)
- old_errno = errno;
-
- free_dyn_buf (stage1_data);
-
- if (0 != PARENT_WRITE_PIPE (pipe_fds))
- close (PARENT_WRITE_PIPE (pipe_fds));
- close (PARENT_READ_PIPE (pipe_fds));
-
- /* Restore the old signal handler for SIGPIPE */
- sigaction (SIGPIPE, &act_old, NULL);
-
- /* Wait for bash to finish */
- waitpid (child_pid, &status, 0);
- /* If old_errno is set, we had an error in the read loop, so do
- * not worry about the child's exit code */
- if (0 == old_errno)
- {
- if ((!WIFEXITED (status)) || (0 != WEXITSTATUS (status)))
- {
- /* FIXME: better errno ? */
- errno = ECANCELED;
- DBG_MSG ("Bash failed with status 0x%x!\n", status);
-
- return -1;
- }
- }
- else
- {
- /* Right, we had an error, so set errno, and exit */
- errno = old_errno;
- return -1;
- }
- }
-
- return write_count;
-
- /* Close parent side pipes */
-error:
- /* Close all pipes */
- old_errno = errno;
- if (0 != CHILD_READ_PIPE (pipe_fds))
- close (CHILD_READ_PIPE (pipe_fds));
- if (0 != CHILD_WRITE_PIPE (pipe_fds))
- close (CHILD_WRITE_PIPE (pipe_fds));
- if (0 != PARENT_READ_PIPE (pipe_fds))
- close (PARENT_READ_PIPE (pipe_fds));
- if (0 != PARENT_WRITE_PIPE (pipe_fds))
- close (PARENT_WRITE_PIPE (pipe_fds));
- /* close() might have changed it */
- errno = old_errno;
-
- return -1;
-}
-
-int
-write_legacy_stage3 (FILE * output)
-{
- service_info_t *info;
- char *service;
- int count;
- int sindex = 0;
- int dep_count;
- int i;
-
- if (!check_arg_fp (output))
- return -1;
-
- fprintf (output, "rc_type_ineed=2\n");
- fprintf (output, "rc_type_needsme=3\n");
- fprintf (output, "rc_type_iuse=4\n");
- fprintf (output, "rc_type_usesme=5\n");
- fprintf (output, "rc_type_ibefore=6\n");
- fprintf (output, "rc_type_iafter=7\n");
- fprintf (output, "rc_type_broken=8\n");
- fprintf (output, "rc_type_mtime=9\n");
- fprintf (output, "rc_index_scale=10\n\n");
- fprintf (output, "declare -a RC_DEPEND_TREE\n\n");
-
- list_for_each_entry (info, &service_info_list, node)
- {
- sindex++;
- }
- if (0 == sindex)
- {
- EERROR ("No services to generate dependency tree for!\n");
- return -1;
- }
-
- fprintf (output, "RC_DEPEND_TREE[0]=%i\n\n", sindex);
-
- sindex = 1;
-
- list_for_each_entry (info, &service_info_list, node)
- {
- fprintf (output, "RC_DEPEND_TREE[%i]=\"%s\"\n", sindex * 10, info->name);
-
- for (i = 0; i <= BROKEN; i++)
- {
- dep_count = 0;
-
- fprintf (output, "RC_DEPEND_TREE[%i+%i]=", (sindex * 10), (i + 2));
-
- str_list_for_each_item (info->depend_info[i], service, count)
- {
- if (0 == dep_count)
- fprintf (output, "\"%s", service);
- else
- fprintf (output, " %s", service);
-
- dep_count++;
- }
-
- if (dep_count > 0)
- fprintf (output, "\"\n");
- else
- fprintf (output, "\n");
- }
-
- fprintf (output, "RC_DEPEND_TREE[%i+9]=\"%li\"\n\n",
- sindex * 10, info->mtime);
- sindex++;
- }
-
- fprintf (output, "RC_GOT_DEPTREE_INFO=\"yes\"\n");
-
- info = service_get_virtual ("logger");
- if (NULL == info)
- {
- DBG_MSG ("No service provides the 'logger' logger virtual!\n");
- fprintf (output, "\nLOGGER_SERVICE=\n");
- }
- else
- {
- fprintf (output, "\nLOGGER_SERVICE=\"%s\"\n", info->name);
- }
-
-
- return 0;
-}
-
-int
-parse_cache (const dyn_buf_t *data)
-{
- service_info_t *info;
- service_type_t type = ALL_SERVICE_TYPE_T;
- rcscript_info_t *rs_info;
- char *buf = NULL;
- char *rc_name = NULL;
- char *str_ptr;
- char *token;
- char *field;
- int retval;
-
- if (!check_arg_dyn_buf ((dyn_buf_t *) data))
- goto error;
-
- while (NULL != (buf = read_line_dyn_buf ((dyn_buf_t *) data)))
- {
- str_ptr = buf;
-
- /* Strip leading spaces/tabs */
- while ((str_ptr[0] == ' ') || (str_ptr[0] == '\t'))
- str_ptr++;
-
- /* Get FIELD name and FIELD value */
- token = strsep (&str_ptr, " ");
-
- /* FIELD name empty/bogus? */
- if ((!check_str (token))
- /* We got an empty FIELD value */
- || (!check_str (str_ptr)))
- {
- errno = EMSGSIZE;
- DBG_MSG ("Parsing stopped due to short read!\n");
-
- goto error;
- }
-
- if (0 == strcmp (token, FIELD_RCSCRIPT))
- {
- DBG_MSG ("Field = '%s', value = '%s'\n", token, str_ptr);
-
- /* Add the service to the list, and initialize all data */
- retval = service_add (str_ptr);
- if (-1 == retval)
- {
- DBG_MSG ("Failed to add %s to service list!\n", str_ptr);
- goto error;
- }
-
- info = service_get_info (str_ptr);
- if (NULL == info)
- {
- DBG_MSG ("Failed to get info for '%s'!\n", str_ptr);
- goto error;
- }
- /* Save the rc-script name for next passes of loop */
- rc_name = info->name;
-
- goto _continue;
- }
-
- if (NULL == rc_name)
- {
- DBG_MSG ("Other fields should come after '%s'!\n", FIELD_RCSCRIPT);
- goto error;
- }
-
- if (0 == strcmp (token, FIELD_NEED))
- type = NEED;
- else if (0 == strcmp (token, FIELD_USE))
- type = USE;
- else if (0 == strcmp (token, FIELD_BEFORE))
- type = BEFORE;
- else if (0 == strcmp (token, FIELD_AFTER))
- type = AFTER;
- else if (0 == strcmp (token, FIELD_PROVIDE))
- type = PROVIDE;
- else if (0 == strcmp (token, FIELD_FAILED))
- {
- type = BROKEN;
-
- /* FIXME: Need to think about what to do syntax BROKEN
- * services */
- EWARN ("'%s' has syntax errors, please correct!\n", rc_name);
- }
-
- if (type < ALL_SERVICE_TYPE_T)
- {
- /* Get the first value *
- * As the values are passed to a bash function, and we
- * then use 'echo $*' to parse them, they should only
- * have one space between each value ... */
- token = strsep (&str_ptr, " ");
-
- /* Get the correct type name */
- field = service_type_names[type];
-
- while (NULL != token)
- {
- DBG_MSG ("Field = '%s', service = '%s', value = '%s'\n",
- field, rc_name, token);
-
- retval = service_add_dependency (rc_name, token, type);
- if (-1 == retval)
- {
- DBG_MSG
- ("Failed to add dependency '%s' to service '%s', type '%s'!\n",
- token, rc_name, field);
- goto error;
- }
-
- /* Get the next value (if any) */
- token = strsep (&str_ptr, " ");
- }
-
- goto _continue;
- }
-
- /* Fall through */
- DBG_MSG ("Unknown FIELD in data!\n");
-
-_continue:
- type = ALL_SERVICE_TYPE_T;
- free (buf);
- /* Do not free 'rc_name', as it should be consistant
- * across loops */
- }
-
- /* read_line_dyn_buf() returned NULL with errno set */
- if ((NULL == buf) && (0 != errno))
- {
- DBG_MSG ("Failed to read line from dynamic buffer!\n");
- return -1;
- }
-
- /* Set the mtimes
- * FIXME: Can drop this when we no longer need write_legacy_stage3() */
- list_for_each_entry (rs_info, &rcscript_list, node)
- {
- rc_name = gbasename (rs_info->filename);
- if (NULL == service_get_info (rc_name))
- continue;
-
- retval = service_set_mtime (rc_name, rs_info->mtime);
- if (-1 == retval)
- {
- DBG_MSG ("Failed to set mtime for service '%s'!\n", rc_name);
- return -1;
- }
- }
-
- return 0;
-
-error:
- free (buf);
-
- return -1;
-}
-
-size_t
-parse_print_start (dyn_buf_t *data)
-{
- size_t write_count;
-
- if (!check_arg_dyn_buf (data))
- return -1;
-
- write_count =
- sprintf_dyn_buf (data,
- ". /sbin/functions.sh\n"
- "[ -e /etc/rc.conf ] && . /etc/rc.conf\n"
- "\n"
- /* "set -e\n" */
- "\n");
-
- return write_count;
-}
-
-size_t
-parse_print_header (char *scriptname, dyn_buf_t *data)
-{
- size_t write_count;
-
- if (!check_arg_dyn_buf (data))
- return -1;
-
- write_count =
- sprintf_dyn_buf (data,
- "#*** %s ***\n"
- "\n"
- "myservice=\"%s\"\n"
- "echo \"RCSCRIPT ${myservice}\"\n"
- "\n", scriptname, scriptname);
-
- return write_count;
-}
-
-size_t
-parse_print_body (char *scriptname, dyn_buf_t *data)
-{
- size_t write_count;
- char *buf = NULL;
- char *str_ptr;
- char *base;
- char *ext;
-
- if (!check_arg_dyn_buf (data))
- return -1;
-
- buf = xstrndup (scriptname, strlen (scriptname));
- if (NULL == buf)
- return -1;
-
- /*
- * Rather do the next block in C than bash, in case we want to
- * use ash or another shell in the place of bash
- */
-
- /* bash: base="${myservice%%.*}" */
- base = buf;
- str_ptr = strchr (buf, '.');
- if (NULL != str_ptr)
- {
- str_ptr[0] = '\0';
- str_ptr++;
- }
- else
- {
- str_ptr = buf;
- }
- /* bash: ext="${myservice##*.}" */
- ext = strrchr (str_ptr, '.');
- if (NULL == ext)
- ext = str_ptr;
-
- write_count =
- sprintf_dyn_buf (data,
- "\n"
- "(\n"
- " # Get settings for rc-script ...\n"
- " [ -e \"/etc/conf.d/${myservice}\" ] && \\\n"
- " . \"/etc/conf.d/${myservice}\"\n"
- " [ -e /etc/conf.d/net ] && \\\n"
- " [ \"%s\" = \"net\" ] && \\\n"
- " [ \"%s\" != \"${myservice}\" ] && \\\n"
- " . /etc/conf.d/net\n"
- " depend() {\n"
- " return 0\n"
- " }\n"
- " \n"
- " # Actual depend() function ...\n"
- " (\n"
- " set -e\n"
- " . \"/etc/init.d/%s\" >/dev/null 2>&1\n"
- " set +e\n"
- " \n"
- " need() {\n"
- " [ \"$#\" -gt 0 ] && echo \"NEED $*\"; return 0\n"
- " }\n"
- " \n"
- " use() {\n"
- " [ \"$#\" -gt 0 ] && echo \"USE $*\"; return 0\n"
- " }\n"
- " \n"
- " before() {\n"
- " [ \"$#\" -gt 0 ] && echo \"BEFORE $*\"; return 0\n"
- " }\n"
- " \n"
- " after() {\n"
- " [ \"$#\" -gt 0 ] && echo \"AFTER $*\"; return 0\n"
- " }\n"
- " \n"
- " provide() {\n"
- " [ \"$#\" -gt 0 ] && echo \"PROVIDE $*\"; return 0\n"
- " }\n"
- " \n"
- " depend\n"
- " ) || echo \"FAILED ${myservice}\"\n"
- ")\n" "\n\n", base, ext, scriptname);
-
- return write_count;
-}
diff --git a/src/core/librcscripts/rcscripts.h b/src/core/librcscripts/rcscripts.h
deleted file mode 100644
index 3740832..0000000
--- a/src/core/librcscripts/rcscripts.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * rcscripts.h
- *
- * Core defines.
- *
- * 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$
- */
-
-#ifndef __RCSCRIPTS_H__
-#define __RCSCRIPTS_H__
-
-#include <stddef.h>
-#include <sys/types.h>
-
-#include "config.h"
-
-#include "api/rctypes.h"
-#include "api/debug.h"
-#include "api/misc.h"
-#include "api/list.h"
-#include "api/str_list.h"
-#include "api/dynbuf.h"
-#include "api/simple-regex.h"
-#include "api/scripts.h"
-#include "api/runlevels.h"
-#include "api/parse.h"
-#include "api/depend.h"
-
-#define RCSCRIPTS_CONFDDIR ETCDIR "/conf.d"
-#define RCSCRIPTS_INITDDIR ETCDIR "/init.d"
-#define RCSCRIPTS_LIBDIR LIBDIR "/rcscripts"
-
-#define RUNLEVELS_DIR ETCDIR "/runlevels"
-
-#define SBIN_RC SBINDIR "/rc"
-#define PROFILE_ENV ETCDIR "/profile.env"
-
-#define RC_CONF_FILE_NAME ETCDIR "/rc.conf"
-#define RC_CONFD_FILE_NAME ETCDIR "/conf.d/rc"
-
-#define RCSCRIPT_HELP RCSCRIPTS_LIBDIR "/sh/rc-help.sh"
-
-#define SVCDIR_CONFIG_ENTRY "svcdir"
-
-#define SHELL_PARSER BINDIR "/bash"
-
-#define DEFAULT_PATH "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin"
-
-#define SELINUX_LIB RCSCRIPTS_LIBDIR "/runscript_selinux.so"
-
-#define SYS_WHITELIST RCSCRIPTS_LIBDIR "/conf.d/env_whitelist"
-#define USR_WHITELIST RCSCRIPTS_CONFDDIR "/env_whitelist"
-
-#define SOFTLEVEL "SOFTLEVEL"
-
-#endif /* __RCSCRIPTS_H__ */
diff --git a/src/core/librcscripts/runlevels.c b/src/core/librcscripts/runlevels.c
deleted file mode 100644
index 914f7ab..0000000
--- a/src/core/librcscripts/runlevels.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * 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 "rcscripts.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 = 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 (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", gbasename (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 = 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 (!is_link (dir_item))
- {
- DBG_MSG ("Skipping non symlink '%s' !\n", dir_item);
- continue;
- }
-
- script_info = get_rcscript_info (gbasename (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",
- gbasename (script_info->filename),
- gbasename (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 (gbasename (info->dirname)))
- && (0 == strncmp (runlevel, gbasename (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 (is_dir (runlevel_dir, 0))
- return TRUE;
-
- return FALSE;
-}
-
diff --git a/src/core/librcscripts/scripts.c b/src/core/librcscripts/scripts.c
deleted file mode 100644
index 040bd8f..0000000
--- a/src/core/librcscripts/scripts.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * scripts.c
- *
- * Get info etc for Gentoo style rc-scripts.
- *
- * 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 "rcscripts.h"
-
-LIST_HEAD (rcscript_list);
-
-int
-get_rcscripts (void)
-{
- rcscript_info_t *info;
- char **file_list = NULL;
- char *rcscript;
- char *confd_file = NULL;
- int count;
-
- file_list = ls_dir (RCSCRIPTS_INITDDIR, 0);
- if (NULL == file_list)
- {
- errno = ENOENT;
- DBG_MSG ("'%s' is empty!\n", RCSCRIPTS_INITDDIR);
-
- return -1;
- }
-
- str_list_for_each_item (file_list, rcscript, count)
- {
- /* Is it a file? */
- if (!(is_file (rcscript, 1))
- /* Do not process scripts, source or backup files. */
- || (CHECK_FILE_EXTENSION (rcscript, ".c"))
- || (CHECK_FILE_EXTENSION (rcscript, ".bak"))
- || (CHECK_FILE_EXTENSION (rcscript, "~")))
- {
- DBG_MSG ("'%s' is not a valid rc-script!\n", gbasename (rcscript));
- }
- else
- {
- regex_data_t tmp_data;
- dyn_buf_t *dynbuf = NULL;
- char *buf = NULL;
-
- dynbuf = new_dyn_buf_mmap_file (rcscript);
- if (NULL == dynbuf)
- {
- DBG_MSG ("Could not open '%s' for reading!\n",
- gbasename (rcscript));
- goto error;
- }
-
- buf = read_line_dyn_buf (dynbuf);
- free_dyn_buf (dynbuf);
- if ((NULL == buf) && (0 != errno))
- goto error;
- if (NULL == buf)
- {
- DBG_MSG ("'%s' is not a valid rc-script!\n",
- gbasename (rcscript));
- continue;
- }
-
- /* Check if it starts with '#!/sbin/runscript' */
- DO_REGEX (tmp_data, buf, "[ \t]*#![ \t]*/sbin/runscript[ \t]*.*",
- check_error);
- free (buf);
- if (REGEX_FULL_MATCH != tmp_data.match)
- {
- DBG_MSG ("'%s' is not a valid rc-script!\n",
- gbasename (rcscript));
- continue;
- }
-
- /* We do not want rc-scripts ending in '.sh' */
- if (CHECK_FILE_EXTENSION (rcscript, ".sh"))
- {
- EWARN ("'%s' is invalid (should not end with '.sh')!\n",
- gbasename (rcscript));
- continue;
- }
-
- DBG_MSG ("Adding rc-script '%s' to list.\n", gbasename (rcscript));
-
- info = xmalloc (sizeof (rcscript_info_t));
- if (NULL == info)
- goto error;
-
- /* Copy the name */
- info->filename = xstrndup (rcscript, strlen (rcscript));
- if (NULL == info->filename)
- goto loop_error;
-
- /* Get the modification time */
- info->mtime = get_mtime (rcscript, 1);
- if (0 == info->mtime)
- {
- DBG_MSG ("Failed to get modification time for '%s'!\n", rcscript);
- /* We do not care if it fails - we will pick up
- * later if there is a problem with the file */
- }
-
- /* File name for the conf.d config file (if any) */
- confd_file = strcatpaths (RCSCRIPTS_CONFDDIR, gbasename (rcscript));
- if (NULL == confd_file)
- {
- DBG_MSG ("Failed to allocate temporary buffer!\n");
- goto loop_error;
- }
-
- /* Get the modification time of the conf.d file
- * (if any exists) */
- info->confd_mtime = get_mtime (confd_file, 1);
- if (0 == info->confd_mtime)
- {
- DBG_MSG ("Failed to get modification time for '%s'!\n",
- confd_file);
- /* We do not care that it fails, as not all
- * rc-scripts will have conf.d config files */
- }
-
- free (confd_file);
-
- list_add_tail (&info->node, &rcscript_list);
-
- continue;
-
-check_error:
- free (buf);
- goto error;
-
-loop_error:
- if (NULL != info)
- free (info->filename);
- free (info);
-
- goto error;
- }
- }
-
- /* Final check if we have some entries */
- if (!check_strv (file_list))
- {
- errno = ENOENT;
- DBG_MSG ("No rc-scripts to parse!\n");
- goto error;
- }
-
- str_list_free (file_list);
-
- return 0;
-
-error:
- str_list_free (file_list);
-
- return -1;
-}
-
-/* Returns 0 if we do not need to regen the cache file, else -1 with
- * errno set if something went wrong */
-int
-check_rcscripts_mtime (const char *cachefile)
-{
- rcscript_info_t *info;
- time_t cache_mtime;
- time_t rc_conf_mtime;
- time_t rc_confd_mtime;
-
- if (!check_arg_str (cachefile))
- return -1;
-
- cache_mtime = get_mtime (cachefile, 1);
- if (0 == cache_mtime)
- {
- DBG_MSG ("Could not get modification time for cache file '%s'!\n",
- cachefile);
- return -1;
- }
-
- /* Get and compare mtime for RC_CONF_FILE_NAME with that of cachefile */
- rc_conf_mtime = get_mtime (RC_CONF_FILE_NAME, 1);
- if (rc_conf_mtime > cache_mtime)
- {
- DBG_MSG ("'%s' have a later modification time than '%s'.\n",
- RC_CONF_FILE_NAME, cachefile);
- return -1;
- }
- /* Get and compare mtime for RC_CONFD_FILE_NAME with that of cachefile */
- rc_confd_mtime = get_mtime (RC_CONFD_FILE_NAME, 1);
- if (rc_confd_mtime > cache_mtime)
- {
- DBG_MSG ("'%s' have a later modification time than '%s'.\n",
- RC_CONFD_FILE_NAME, cachefile);
- return -1;
- }
-
- /* Get and compare mtime for each rc-script and its conf.d config file
- * with that of cachefile */
- list_for_each_entry (info, &rcscript_list, node)
- {
- if ((info->mtime > cache_mtime) || (info->confd_mtime > cache_mtime))
- {
- DBG_MSG ("'%s' have a later modification time than '%s'.\n",
- info->filename, cachefile);
- return -1;
- }
- }
-
- return 0;
-}
-
-rcscript_info_t *
-get_rcscript_info (const char *scriptname)
-{
- rcscript_info_t *info;
-
- if (!check_arg_str (scriptname))
- return NULL;
-
- list_for_each_entry (info, &rcscript_list, node)
- {
- if ((strlen (scriptname) == strlen (gbasename (info->filename)))
- && (0 == strncmp (scriptname, gbasename (info->filename),
- strlen (scriptname))))
- return info;
- }
-
- return NULL;
-}
-
diff --git a/src/core/librcscripts/simple-regex.c b/src/core/librcscripts/simple-regex.c
deleted file mode 100644
index fc365de..0000000
--- a/src/core/librcscripts/simple-regex.c
+++ /dev/null
@@ -1,869 +0,0 @@
-/*
- * simple_regex.c
- *
- * Simle regex library.
- *
- * 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$
- */
-
-/*
- * Some notes:
- *
- * - This is a very simple regex library (read: return a match if some string
- * matches some regex). It is probably not POSIX (if there are a POSIX or
- * other standard) compatible.
- *
- * - I primarily wrote it to _not_ use glibc type regex functions, in case we
- * might want to use it in code that have to be linked agaist klibc, etc.
- *
- * - It really is not optimized in any way yet.
- *
- * - Supported operators are:
- *
- * '.', '?', '*', '+' - So called 'wildcards'
- * '[a-z]', '[^a-z]' - Basic 'lists'. Note that 'a-z' just specify that
- * it supports basic lists as well as sequences ..
- * The '^' is for an inverted list of course.
- * '^', '$' - The 'from start' and 'to end' operators. If these
- * are not used at the start ('^') or end ('$') of the
- * regex, they will be treated as normal characters
- * (this of course exclude the use of '^' in a 'list').
- *
- * - If an invalid argument was passed, the functions returns 0 with
- * 'regex_data-match == 0' (no error with no match) rather than -1. It may
- * not be consistant with other practices, but I personally do not feel it is
- * a critical error for these types of functions, and there are debugging you
- * can enable to verify that there are no such issues.
- *
- * - __somefunction() is usually a helper function for somefunction(). I guess
- * recursion might be an alternative, but I try to avoid it.
- *
- * - In general if we are matching a 'wildcard' ('*', '+' or '?'), a 'word'
- * (read: some part of the regex that do not contain a 'wildcard' or 'list')
- * will have a greater 'weight' than the 'wildcard'. This means that we
- * will only continue to evaluate the 'wildcard' until the following 'word'
- * (if any) matches. Currently this do not hold true for a 'list' not
- * followed by a 'wildcard' - I might fix this in future.
- *
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "rcscripts.h"
-
-/* Macro to check if a regex_data_t pointer is valid */
-#define CHECK_REGEX_DATA_P(_regex_data, _on_error) \
- do { \
- if ((NULL == _regex_data) \
- || (NULL == _regex_data->data) \
- /* We do not check for this, as it might still \
- * provide a match ('*' or '?' wildcard) */ \
- /* || (0 == strlen(_regex_data->data)) */ \
- || (NULL == _regex_data->regex) \
- || (0 == strlen(_regex_data->regex))) \
- { \
- errno = EINVAL; \
- DBG_MSG("Invalid argument passed!\n"); \
- goto _on_error; \
- } \
- } while (0)
-
-static size_t get_word (const char *regex, char **r_word);
-static int match_word (regex_data_t * regex_data);
-static size_t get_list_size (const char *regex);
-static size_t get_list (const char *regex, char **r_list);
-static int __match_list (regex_data_t * regex_data);
-static int match_list (regex_data_t * regex_data);
-static size_t get_wildcard (const char *regex, char *r_wildcard);
-static int __match_wildcard (regex_data_t * regex_data,
- int (*match_func) (regex_data_t * regex_data),
- const char *regex);
-static int match_wildcard (regex_data_t * regex_data);
-static int __match (regex_data_t * regex_data);
-
-/*
- * Return values for match_* functions
- *
- * 0 - There was no error. If there was a match, regex_data->match
- * - will be > 0 (this is the definitive check - if not true, the
- * - other values of the struct may be bogus), regex_data->count
- * - will be the amount of data that was matched (might be 0 for
- * - some wildcards), and regex_data->r_count will be > 0.
- *
- * -1 - An error occured. Check errno for more info.
- *
- */
-
-size_t
-get_word (const char *regex, char **r_word)
-{
- char *r_list;
- char *str_ptr;
- size_t count = 0;
- size_t tmp_count;
-
- if (!check_arg_str (regex))
- return 0;
-
- *r_word = xmalloc (strlen (regex) + 1);
- if (NULL == r_word)
- return 0;
-
- str_ptr = *r_word;
-
- while (strlen (regex) > 0)
- {
- switch (regex[0])
- {
- case '*':
- case '+':
- case '?':
- /* If its a wildcard, backup one step */
- *(--str_ptr) = '\0';
- count--;
- return count;
- case '[':
- tmp_count = get_list (regex, &r_list);
- free (r_list);
- /* In theory should not happen, but you never know
- * what may happen in future ... */
- if (-1 == tmp_count)
- goto error;
-
- /* Bail if we have a list */
- if (tmp_count > 0)
- {
- str_ptr[0] = '\0';
- return count;
- }
- default:
- *str_ptr++ = *regex++;
- count++;
- break;
- }
- }
-
- str_ptr[0] = '\0';
-
- return count;
-
-error:
- free (*r_word);
-
- return -1;
-}
-
-int
-match_word (regex_data_t * regex_data)
-{
- char *data_p = regex_data->data;
- char *r_word = NULL, *r_word_p;
- size_t count = 0;
-
- CHECK_REGEX_DATA_P (regex_data, exit);
-
- count = get_word (regex_data->regex, &r_word);
- if (-1 == count)
- goto error;
- if (0 == count)
- goto exit;
- r_word_p = r_word;
-
- while ((strlen (data_p) > 0) && (strlen (r_word_p) > 0))
- {
- /* If 'r_word' is not 100% part of 'string', we do not have
- * a match. If its a '.', it matches no matter what. */
- if ((data_p[0] != r_word_p[0]) && ('.' != r_word_p[0]))
- {
- count = 0;
- goto exit;
- }
-
- data_p++;
- r_word_p++;
- }
-
- /* If 'string' is shorter than 'r_word', we do not have a match */
- if ((0 == strlen (data_p)) && (0 < strlen (r_word_p)))
- {
- count = 0;
- goto exit;
- }
-
-exit:
- /* Fill in our structure */
- if (0 == count)
- regex_data->match = REGEX_NO_MATCH;
- else if (strlen (regex_data->data) == count)
- regex_data->match = REGEX_FULL_MATCH;
- else
- regex_data->match = REGEX_PARTIAL_MATCH;
- if (regex_data->match != REGEX_NO_MATCH)
- regex_data->where = regex_data->data;
- else
- regex_data->where = NULL;
- regex_data->count = count;
- regex_data->r_count = count;
-
- free (r_word);
- return 0;
-
-error:
- regex_data->match = REGEX_NO_MATCH;
-
- free (r_word);
- return -1;
-}
-
-size_t
-get_list_size (const char *regex)
-{
- size_t count = 0;
-
- if (!check_arg_str (regex))
- return 0;
-
- if ('[' != regex[0])
- {
- errno = EINVAL;
- DBG_MSG ("Invalid argument passed!\n");
- return 0;
- }
-
- regex++;
-
- while ((strlen (regex) > 0) && (']' != regex[0]))
- {
- /* We have a sequence (x-y) */
- if (('-' == regex[0])
- && (']' != regex[1])
- && (strlen (regex) >= 2) && (regex[-1] < regex[1]))
- {
- /* Add current + diff in sequence */
- count += regex[1] - regex[-1];
- /* Take care of '-' and next char */
- regex += 2;
- }
- else
- {
- regex++;
- count++;
- }
- }
-
- return count;
-}
-
-size_t
-get_list (const char *regex, char **r_list)
-{
- char *buf = NULL;
- size_t count = 0;
- size_t size;
-
- if (!check_arg_str (regex))
- return 0;
-
- /* Bail if we do not have a list. Do not add debugging, as
- * it is very noisy (used a lot when we call match_list() in
- * __match() and match() to test for list matching) */
- if ('[' != regex[0])
- return 0;
-
- size = get_list_size (regex);
- if (0 == size)
- {
- /* Should not be an issue, but just in case */
- DBG_MSG ("0 returned by get_list_size.\n");
- return 0;
- }
-
- *r_list = xmalloc (size + 1);
- if (NULL == *r_list)
- return -1;
-
- buf = *r_list;
-
- /* Take care of '[' */
- regex++;
- count++;
-
- while ((strlen (regex) > 0) && (']' != regex[0]))
- {
- /* We have a sequence (x-y) */
- if (('-' == regex[0])
- && (']' != regex[1])
- && (strlen (regex) >= 2) && (regex[-1] < regex[1]))
- {
- /* Fill in missing chars in sequence */
- while (buf[-1] < regex[1])
- {
- buf[0] = (char) (buf[-1] + 1);
- buf++;
- /* We do not increase count */
- }
- /* Take care of '-' and next char */
- count += 2;
- regex += 2;
- }
- else
- {
- *buf++ = *regex++;
- count++;
- }
- }
-
- buf[0] = '\0';
- /* Take care of ']' */
- count++;
-
- /* We do not have a list as it does not end in ']' */
- if (']' != regex[0])
- {
- count = 0;
- free (*r_list);
- }
-
- return count;
-}
-
-/* If the first is the '^' character, everything but the list is matched
- * NOTE: We only evaluate _ONE_ data character at a time!! */
-int
-__match_list (regex_data_t * regex_data)
-{
- regex_data_t tmp_data;
- char *data_p = regex_data->data;
- char *list_p = regex_data->regex;
- char test_regex[2] = { '\0', '\0' };
- int invert = 0;
- int lmatch;
- int retval;
-
- CHECK_REGEX_DATA_P (regex_data, failed);
-
- if ('^' == list_p[0])
- {
- /* We need to invert the match */
- invert = 1;
- /* Make sure '^' is not part of our list */
- list_p++;
- }
-
- if (invert)
- /* All should be a match if not in the list */
- lmatch = 1;
- else
- /* We only have a match if in the list */
- lmatch = 0;
-
- while (strlen (list_p) > 0)
- {
- test_regex[0] = list_p[0];
-
- FILL_REGEX_DATA (tmp_data, data_p, test_regex);
- retval = match_word (&tmp_data);
- if (-1 == retval)
- goto error;
-
- if (REGEX_MATCH (tmp_data))
- {
- if (invert)
- /* If we exclude the list from
- * characters we try to match, we
- * have a match until one of the
- * list is found. */
- lmatch = 0;
- else
- /* If not, we have to keep looking
- * until one from the list match
- * before we have a match */
- lmatch = 1;
- break;
- }
- list_p++;
- }
-
- /* Fill in our structure */
- if (lmatch)
- {
- regex_data->match = REGEX_PARTIAL_MATCH;
- regex_data->where = regex_data->data;
- regex_data->count = 1;
- /* This one is more cosmetic, as match_list() will
- * do the right thing */
- regex_data->r_count = 0; /* strlen(regex_data->regex); */
- }
- else
- {
-failed:
- regex_data->match = REGEX_NO_MATCH;
- regex_data->where = NULL;
- regex_data->count = 0;
- regex_data->r_count = 0;
- }
-
- return 0;
-
-error:
- regex_data->match = REGEX_NO_MATCH;
-
- return -1;
-}
-
-int
-match_list (regex_data_t * regex_data)
-{
- regex_data_t tmp_data;
- char *data_p = regex_data->data;
- char *list_p = regex_data->regex;
- char *r_list = NULL;
- size_t r_count = 0;
- int retval;
-
- CHECK_REGEX_DATA_P (regex_data, failed);
-
- r_count = get_list (list_p, &r_list);
- if (-1 == r_count)
- goto error;
- if (0 == r_count)
- goto failed;
-
- FILL_REGEX_DATA (tmp_data, data_p, &list_p[r_count - 1]);
- retval = __match_wildcard (&tmp_data, __match_list, r_list);
- if (-1 == retval)
- goto error;
- if (REGEX_MATCH (tmp_data))
- {
- /* This should be 2 ('word' + 'wildcard'), so just remove
- * the wildcard */
- tmp_data.r_count--;
- goto exit;
- }
-
- FILL_REGEX_DATA (tmp_data, data_p, r_list);
- retval = __match_list (&tmp_data);
- if (-1 == retval)
- goto error;
- if (REGEX_MATCH (tmp_data))
- goto exit;
-
-failed:
- /* We will fill in regex_data below */
- tmp_data.match = REGEX_NO_MATCH;
- tmp_data.where = NULL;
- tmp_data.count = 0;
- tmp_data.r_count = 0;
-
-exit:
- /* Fill in our structure */
- regex_data->match = tmp_data.match;
- regex_data->where = tmp_data.where;
- regex_data->count = tmp_data.count;
- if (regex_data->match != REGEX_NO_MATCH)
- /* tmp_data.r_count for __match_wildcard will take care of the
- * wildcard, and tmp_data.r_count for __match_list will be 0 */
- regex_data->r_count = r_count + tmp_data.r_count;
- else
- regex_data->r_count = 0;
-
- free (r_list);
- return 0;
-
-error:
- regex_data->match = REGEX_NO_MATCH;
-
- free (r_list);
- return -1;
-}
-
-size_t
-get_wildcard (const char *regex, char *r_wildcard)
-{
- if (!check_arg_str (regex))
- return 0;
-
- r_wildcard[0] = regex[0];
- r_wildcard[2] = '\0';
-
- switch (regex[1])
- {
- case '*':
- case '+':
- case '?':
- r_wildcard[1] = regex[1];
- break;
- default:
- r_wildcard[0] = '\0';
- return 0;
- }
-
- return strlen (r_wildcard);
-}
-
-int
-__match_wildcard (regex_data_t * regex_data,
- int (*match_func) (regex_data_t * regex_data),
- const char *regex)
-{
- regex_data_t tmp_data;
- char *data_p = regex_data->data;
- char *wildcard_p = regex_data->regex;
- char r_wildcard[3];
- size_t count = 0;
- size_t r_count = 0;
- int is_match = 0;
- int retval;
-
- CHECK_REGEX_DATA_P (regex_data, exit);
-
- if (NULL == match_func)
- {
- errno = EINVAL;
- DBG_MSG ("NULL match_func was passed!\n");
- goto exit;
- }
-
- r_count = get_wildcard (wildcard_p, r_wildcard);
- if (0 == r_count)
- goto exit;
-
- FILL_REGEX_DATA (tmp_data, data_p, (char *) regex);
- retval = match_func (&tmp_data);
- if (-1 == retval)
- goto error;
-
- switch (r_wildcard[1])
- {
- case '*':
- case '?':
- /* '*' and '?' always matches */
- is_match = 1;
- case '+':
- /* We need to match all of them */
- do
- {
- /* If we have at least one match for '+', or none
- * for '*' or '?', check if we have a word or list match.
- * We do this because a word weights more than a wildcard */
- if ((strlen (wildcard_p) > 2)
- && ((count > 0)
- || ('*' == r_wildcard[1])
- || ('?' == r_wildcard[1])))
- {
- regex_data_t tmp_data2;
-#if 0
- printf ("data_p = %s, wildcard_p = %s\n", data_p, wildcard_p);
-#endif
-
- FILL_REGEX_DATA (tmp_data2, data_p, &wildcard_p[2]);
- retval = match (&tmp_data2);
- if (-1 == retval)
- goto error;
-
- if (
- /* '.' might be a special case ... */
- /* ('.' != wildcard_p[2]) && */
- ((REGEX_MATCH (tmp_data2))
- && (REGEX_FULL_MATCH == tmp_data2.match)))
- {
- goto exit;
- }
- }
-
- if (REGEX_MATCH (tmp_data))
- {
- data_p += tmp_data.count;
- count += tmp_data.count;
- is_match = 1;
-
- FILL_REGEX_DATA (tmp_data, data_p, (char *) regex);
- retval = match_func (&tmp_data);
- if (-1 == retval)
- goto error;
- }
- /* Only once for '?' */
- }
- while ((REGEX_MATCH (tmp_data)) && ('?' != r_wildcard[1]));
-
- break;
- default:
- /* No wildcard */
- break;
- }
-
-exit:
- /* Fill in our structure */
- /* We can still have a match ('*' and '?'), although count == 0 */
- if ((0 == count) && (0 == is_match))
- regex_data->match = REGEX_NO_MATCH;
- else if (strlen (regex_data->data) == count)
- regex_data->match = REGEX_FULL_MATCH;
- else
- regex_data->match = REGEX_PARTIAL_MATCH;
- if (regex_data->match != REGEX_NO_MATCH)
- regex_data->where = regex_data->data;
- else
- regex_data->where = NULL;
- regex_data->count = count;
- regex_data->r_count = r_count;
-
- return 0;
-
-error:
- regex_data->match = REGEX_NO_MATCH;
-
- return -1;
-}
-
-int
-match_wildcard (regex_data_t * regex_data)
-{
- regex_data_t tmp_data;
- char *data_p = regex_data->data;
- char *wildcard_p = regex_data->regex;
- char r_wildcard[3];
- size_t r_count;
- int retval;
-
- CHECK_REGEX_DATA_P (regex_data, failed);
-
- /* Invalid wildcard - we need a character + a regex operator */
- if (strlen (wildcard_p) < 2)
- goto failed;
-
- r_count = get_wildcard (wildcard_p, r_wildcard);
- if (0 == r_count)
- goto failed;
-
- /* Needed so that match_word() will not bail if it sees the wildcard */
- r_wildcard[1] = '\0';
-
- FILL_REGEX_DATA (tmp_data, data_p, wildcard_p);
- retval = __match_wildcard (&tmp_data, match_word, r_wildcard);
- if (-1 == retval)
- goto error;
- if (REGEX_MATCH (tmp_data))
- goto exit;
-
-failed:
- /* We will fill in regex_data below */
- tmp_data.match = REGEX_NO_MATCH;
- tmp_data.where = NULL;
- tmp_data.count = 0;
- tmp_data.r_count = 0;
-
-exit:
- /* Fill in our structure */
- regex_data->match = tmp_data.match;
- regex_data->where = tmp_data.where;
- regex_data->count = tmp_data.count;
- regex_data->r_count = tmp_data.r_count;
-
- return 0;
-
-error:
- regex_data->match = REGEX_NO_MATCH;
-
- return -1;
-}
-
-int
-__match (regex_data_t * regex_data)
-{
- regex_data_t tmp_data;
- char *data_p = regex_data->data;
- char *regex_p = regex_data->regex;
- size_t count = 0;
- size_t r_count = 0;
- int rmatch = 0;
- int retval;
-
- CHECK_REGEX_DATA_P (regex_data, failed);
-
- while (strlen (regex_p) > 0)
- {
-#if 0
- printf ("data_p = '%s', regex_p = '%s'\n", data_p, regex_p);
-#endif
-
- FILL_REGEX_DATA (tmp_data, data_p, regex_p);
- retval = match_list (&tmp_data);
- if (-1 == retval)
- goto error;
- if (REGEX_MATCH (tmp_data))
- goto have_match;
-
- FILL_REGEX_DATA (tmp_data, data_p, regex_p);
- retval = match_wildcard (&tmp_data);
- if (-1 == retval)
- goto error;
- if (REGEX_MATCH (tmp_data))
- goto have_match;
-
- FILL_REGEX_DATA (tmp_data, data_p, regex_p);
- retval = match_word (&tmp_data);
- if (-1 == retval)
- goto error;
- if (REGEX_MATCH (tmp_data))
- goto have_match;
-
- break;
-
-have_match:
- data_p += tmp_data.count;
- count += tmp_data.count;
- regex_p += tmp_data.r_count;
- r_count += tmp_data.r_count;
- rmatch = 1;
-
- /* Check that we do not go out of bounds */
- if (((data_p - regex_data->data) > strlen (regex_data->data))
- || ((regex_p - regex_data->regex) > strlen (regex_data->regex)))
- goto failed;
- }
-
- /* We could not match the whole regex (data too short?) */
- if (0 != strlen (regex_p))
- goto failed;
-
- goto exit;
-
-failed:
- /* We will fill in regex_data below */
- count = 0;
- r_count = 0;
- rmatch = 0;
-
-exit:
- /* Fill in our structure */
- /* We can still have a match ('*' and '?'), although count == 0 */
- if ((0 == count) && (0 == rmatch))
- regex_data->match = REGEX_NO_MATCH;
- else if (strlen (regex_data->data) == count)
- regex_data->match = REGEX_FULL_MATCH;
- else
- regex_data->match = REGEX_PARTIAL_MATCH;
- if (regex_data->match != REGEX_NO_MATCH)
- regex_data->where = regex_data->data;
- else
- regex_data->where = NULL;
- regex_data->count = count;
- regex_data->r_count = r_count;
-
- return 0;
-
-error:
- regex_data->match = REGEX_NO_MATCH;
-
- return -1;
-}
-
-int
-match (regex_data_t * regex_data)
-{
- regex_data_t tmp_data;
- char *data_p = regex_data->data;
- char *regex_p;
- char *buf = NULL;
- int from_start = 0;
- int to_end = 0;
- int retval;
-
- CHECK_REGEX_DATA_P (regex_data, failed);
-
- /* We might be modifying regex_p, so make a copy */
- buf = xstrndup (regex_data->regex, strlen (regex_data->regex));
- if (NULL == buf)
- goto error;
-
- regex_p = buf;
-
- /* Should we only match from the start? */
- if ('^' == regex_p[0])
- {
- regex_p++;
- from_start = 1;
- }
-
- /* Should we match up to the end? */
- if ('$' == regex_p[strlen (regex_p) - 1])
- {
- regex_p[strlen (regex_p) - 1] = '\0';
- to_end = 1;
- }
-
- do
- {
- FILL_REGEX_DATA (tmp_data, data_p, regex_p);
- retval = __match (&tmp_data);
- if (-1 == retval)
- goto error;
- }
- while ((strlen (data_p++) > 0)
- && (!REGEX_MATCH (tmp_data)) && (0 == from_start));
-
- /* Compensate for above extra inc */
- data_p--;
-
- /* Fill in our structure */
- if (REGEX_MATCH (tmp_data))
- {
- /* Check if we had an '$' at the end of the regex, and
- * verify that we still have a match */
- if ((1 == to_end) && (tmp_data.count != strlen (data_p)))
- {
- goto failed;
- }
-
- if ((data_p == regex_data->data)
- && (tmp_data.match == REGEX_FULL_MATCH))
- regex_data->match = REGEX_FULL_MATCH;
- else
- regex_data->match = REGEX_PARTIAL_MATCH;
- regex_data->where = data_p;
- regex_data->count = tmp_data.count;
- regex_data->r_count = tmp_data.r_count;
- if (1 == from_start)
- regex_data->r_count++;
- if (1 == to_end)
- regex_data->r_count++;
- }
- else
- {
-failed:
- regex_data->match = REGEX_NO_MATCH;
- regex_data->where = NULL;
- regex_data->count = 0;
- regex_data->r_count = 0;
- }
-
- free (buf);
-
- return 0;
-
-error:
- regex_data->match = REGEX_NO_MATCH;
- free (buf);
-
- return -1;
-}