summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/rc_config.313
-rw-r--r--src/librc/librc-daemon.c22
-rw-r--r--src/librc/librc-depend.c49
-rw-r--r--src/librc/librc-misc.c38
-rw-r--r--src/librc/librc.c17
-rw-r--r--src/librc/librc.h2
-rw-r--r--src/librc/rc.h4
-rw-r--r--src/librc/rc.map1
-rw-r--r--src/rc/rc.c13
9 files changed, 77 insertions, 82 deletions
diff --git a/man/rc_config.3 b/man/rc_config.3
index f420d43..2bf90a1 100644
--- a/man/rc_config.3
+++ b/man/rc_config.3
@@ -22,17 +22,16 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd Mar 16, 2008
+.Dd Mar 17, 2008
.Dt RC_CONFIG 3 SMM
.Os OpenRC
.Sh NAME
-.Nm rc_getline , rc_config_list , rc_config_load , rc_config_value , rc_yesno
+.Nm rc_config_list , rc_config_load , rc_config_value , rc_yesno
.Nd functions to query OpenRC service configurations
.Sh LIBRARY
Run Command library (librc, -lrc)
.Sh SYNOPSIS
.In rc.h
-.Ft "char *" Fn rc_getline "FILE *fp"
.Ft "RC_STRINGLIST *" Fn rc_config_list "const char *file"
.Ft "RC_STRINGLIST *" Fn rc_config_load "const char *file"
.Ft "char *" Fn rc_config_value "const char *const *list" "const char *entry"
@@ -40,14 +39,6 @@ Run Command library (librc, -lrc)
.Sh DESCRIPTION
These functions provide an easy means of querying OpenRC configuration files.
.Pp
-.Fn rc_getline
-expands it's buffer using
-.Fn malloc
-until it has read a whole line from the file or EOF.
-Trailing newlines are removed and the buffer is returned. Any functions that
-read from files should use this function to avoid any potential overflows and
-to ensure that arbitary long lines are read.
-.Pp
.Fn rc_config_list
returns a list of non comment lines in
.Fa file .
diff --git a/src/librc/librc-daemon.c b/src/librc/librc-daemon.c
index aed37e4..46162d5 100644
--- a/src/librc/librc-daemon.c
+++ b/src/librc/librc-daemon.c
@@ -311,7 +311,8 @@ librc_hidden_def(rc_find_pids)
static bool _match_daemon(const char *path, const char *file,
RC_STRINGLIST *match)
{
- char *line;
+ char *line = NULL;
+ size_t len = 0;
char ffile[PATH_MAX];
FILE *fp;
RC_STRING *m;
@@ -322,7 +323,7 @@ static bool _match_daemon(const char *path, const char *file,
if (! fp)
return false;
- while ((line = rc_getline(fp))) {
+ while ((rc_getline(&line, &len, fp))) {
TAILQ_FOREACH(m, match, entries)
if (strcmp(line, m->value) == 0) {
TAILQ_REMOVE(match, m, entries);
@@ -332,6 +333,7 @@ static bool _match_daemon(const char *path, const char *file,
break;
}
fclose(fp);
+ free(line);
if (TAILQ_FIRST(match))
return false;
return true;
@@ -493,7 +495,8 @@ bool rc_service_daemons_crashed(const char *service)
struct dirent *d;
char *path = dirpath;
FILE *fp;
- char *line;
+ char *line = NULL;
+ size_t len = 0;
char **argv = NULL;
char *exec = NULL;
char *name = NULL;
@@ -525,17 +528,13 @@ bool rc_service_daemons_crashed(const char *service)
if (! fp)
break;
- while ((line = rc_getline(fp))) {
+ while ((rc_getline(&line, &len, fp))) {
p = line;
- if ((token = strsep(&p, "=")) == NULL || ! p) {
- free(line);
+ if ((token = strsep(&p, "=")) == NULL || ! p)
continue;
- }
- if (! *p) {
- free(line);
+ if (! *p)
continue;
- }
if (strncmp(token, "argv_", 5) == 0) {
if (! list)
@@ -551,11 +550,10 @@ bool rc_service_daemons_crashed(const char *service)
name = xstrdup(p);
} else if (strcmp(token, "pidfile") == 0) {
pidfile = xstrdup(p);
- free(line);
break;
}
- free(line);
}
+ free(line);
fclose(fp);
pid = 0;
diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c
index a9bf304..d3a3f78 100644
--- a/src/librc/librc-depend.c
+++ b/src/librc/librc-depend.c
@@ -121,7 +121,8 @@ RC_DEPTREE *rc_deptree_load(void)
RC_DEPTREE *deptree;
RC_DEPINFO *depinfo = NULL;
RC_DEPTYPE *deptype = NULL;
- char *line;
+ char *line = NULL;
+ size_t len = 0;
char *type;
char *p;
char *e;
@@ -133,43 +134,43 @@ RC_DEPTREE *rc_deptree_load(void)
deptree = xmalloc(sizeof(*deptree));
STAILQ_INIT(deptree);
- while ((line = rc_getline(fp)))
+ while ((rc_getline(&line, &len, fp)))
{
p = line;
e = strsep(&p, "_");
if (! e || strcmp(e, "depinfo") != 0)
- goto next;
+ continue;
e = strsep (&p, "_");
if (! e || sscanf(e, "%d", &i) != 1)
- goto next;
+ continue;
if (! (type = strsep(&p, "_=")))
- goto next;
+ continue;
if (strcmp(type, "service") == 0)
{
/* Sanity */
e = get_shell_value(p);
if (! e || *e == '\0')
- goto next;
+ continue;
depinfo = xmalloc(sizeof(*depinfo));
STAILQ_INIT(&depinfo->depends);
depinfo->service = xstrdup(e);
STAILQ_INSERT_TAIL(deptree, depinfo, entries);
deptype = NULL;
- goto next;
+ continue;
}
e = strsep(&p, "=");
if (! e || sscanf(e, "%d", &i) != 1)
- goto next;
+ continue;
/* Sanity */
e = get_shell_value(p);
if (! e || *e == '\0')
- goto next;
+ continue;
if (! deptype || strcmp(deptype->type, type) != 0) {
deptype = xmalloc(sizeof(*deptype));
@@ -179,10 +180,9 @@ RC_DEPTREE *rc_deptree_load(void)
}
rc_stringlist_add(deptype->services, e);
-next:
- free(line);
}
fclose(fp);
+ free(line);
return deptree;
}
@@ -724,14 +724,15 @@ bool rc_deptree_update(void)
RC_STRING *s;
RC_STRING *s2;
RC_DEPTYPE *provide;
- char *line;
+ char *line = NULL;
+ size_t len = 0;
char *depend;
char *depends;
char *service;
char *type;
size_t i;
size_t k;
- size_t len;
+ size_t l;
int retval = true;
const char *sys = rc_sys();
char *nosys;
@@ -750,14 +751,14 @@ bool rc_deptree_update(void)
config = rc_stringlist_new();
- while ((line = rc_getline(fp)))
+ while ((rc_getline(&line, &len, fp)))
{
depends = line;
service = strsep(&depends, " ");
if (! service || ! *service)
- goto next;
- type = strsep(&depends, " ");
+ continue;
+ type = strsep(&depends, " ");
if (! depinfo || strcmp(depinfo->service, service) != 0) {
deptype = NULL;
depinfo = get_depinfo(deptree, service);
@@ -771,7 +772,7 @@ bool rc_deptree_update(void)
/* We may not have any depends */
if (! type || ! depends)
- goto next;
+ continue;
/* Get the type */
if (strcmp(type, "config") != 0) {
@@ -798,11 +799,11 @@ bool rc_deptree_update(void)
}
/* .sh files are not init scripts */
- len = strlen(depend);
- if (len > 2 &&
- depend[len - 3] == '.' &&
- depend[len - 2] == 's' &&
- depend[len - 1] == 'h')
+ l = strlen(depend);
+ if (l > 2 &&
+ depend[l - 3] == '.' &&
+ depend[l - 2] == 's' &&
+ depend[l - 1] == 'h')
continue;
/* Remove our dependency if instructed */
@@ -828,10 +829,8 @@ bool rc_deptree_update(void)
rc_stringlist_delete(dt->services, depend);
}
}
-
-next:
- free(line);
}
+ free(line);
pclose(fp);
/* Phase 2 - if we're a special system, remove services that don't
diff --git a/src/librc/librc-misc.c b/src/librc/librc-misc.c
index 747a8fb..5c7e366 100644
--- a/src/librc/librc-misc.c
+++ b/src/librc/librc-misc.c
@@ -54,37 +54,38 @@ bool rc_yesno (const char *value)
}
librc_hidden_def(rc_yesno)
-char *rc_getline (FILE *fp)
+ssize_t rc_getline (char **line, size_t *len, FILE *fp)
{
- char *line = NULL;
char *p;
- size_t len = 0;
size_t last = 0;
- if (feof (fp))
- return NULL;
+ if (feof(fp))
+ return 0;
do {
- len += BUFSIZ;
- line = xrealloc (line, sizeof (char) * len);
- p = line + last;
- memset (p, 0, BUFSIZ);
- fgets (p, BUFSIZ, fp);
- last += strlen (p);
- } while (! feof (fp) && line[last - 1] != '\n');
+ if (*line == NULL || last != 0) {
+ *len += BUFSIZ;
+ *line = xrealloc(*line, *len);
+ }
+ p = *line + last;
+ memset(p, 0, BUFSIZ);
+ fgets(p, BUFSIZ, fp);
+ last += strlen(p);
+ } while (! feof(fp) && (*line)[last - 1] != '\n');
/* Trim the trailing newline */
- if (*line && line[--last] == '\n')
- line[last] = '\0';
+ if (**line && (*line)[last - 1] == '\n')
+ (*line)[last - 1] = '\0';
- return line;
+ return last;
}
librc_hidden_def(rc_getline)
RC_STRINGLIST *rc_config_list(const char *file)
{
FILE *fp;
- char *buffer;
+ char *buffer = NULL;
+ size_t len = 0;
char *p;
char *token;
RC_STRINGLIST *list = NULL;
@@ -92,7 +93,8 @@ RC_STRINGLIST *rc_config_list(const char *file)
if (!(fp = fopen(file, "r")))
return NULL;
- while ((p = buffer = rc_getline(fp))) {
+ while ((rc_getline(&buffer, &len, fp))) {
+ p = buffer;
/* Strip leading spaces/tabs */
while ((*p == ' ') || (*p == '\t'))
p++;
@@ -111,9 +113,9 @@ RC_STRINGLIST *rc_config_list(const char *file)
rc_stringlist_add(list, token);
}
}
- free(buffer);
}
fclose(fp);
+ free(buffer);
return list;
}
diff --git a/src/librc/librc.c b/src/librc/librc.c
index cb75521..75b0e41 100644
--- a/src/librc/librc.c
+++ b/src/librc/librc.c
@@ -166,7 +166,8 @@ static bool rm_dir(const char *pathname, bool top)
static bool file_regex(const char *file, const char *regex)
{
FILE *fp;
- char *line;
+ char *line = NULL;
+ size_t len = 0;
regex_t re;
bool retval = false;
int result;
@@ -183,14 +184,14 @@ static bool file_regex(const char *file, const char *regex)
return false;
}
- while ((line = rc_getline(fp))) {
+ while ((rc_getline(&line, &len, fp))) {
if (regexec(&re, line, 0, NULL, 0) == 0)
retval = true;
- free(line);
if (retval)
break;
}
fclose(fp);
+ free(line);
regfree(&re);
return retval;
@@ -401,6 +402,7 @@ RC_STRINGLIST *rc_service_extra_commands(const char *service)
char *svc;
char *cmd = NULL;
char *buffer = NULL;
+ size_t len = 0;
RC_STRINGLIST *commands = NULL;
char *token;
char *p;
@@ -417,7 +419,8 @@ RC_STRINGLIST *rc_service_extra_commands(const char *service)
free(svc);
if ((fp = popen(cmd, "r"))) {
- p = buffer = rc_getline(fp);
+ rc_getline(&buffer, &len, fp);
+ p = buffer;
while ((token = strsep(&p, " "))) {
if (! commands)
commands = rc_stringlist_new();
@@ -437,6 +440,7 @@ char *rc_service_description(const char *service, const char *option)
char *svc;
char *cmd;
char *desc = NULL;
+ size_t len = 0;
FILE *fp;
size_t l;
@@ -451,7 +455,7 @@ char *rc_service_description(const char *service, const char *option)
snprintf(cmd, l, DESCSTR, svc, option ? "_" : "", option);
free(svc);
if ((fp = popen(cmd, "r"))) {
- desc = rc_getline(fp);
+ rc_getline(&desc, &len, fp);
pclose(fp);
}
free(cmd);
@@ -633,12 +637,13 @@ char *rc_service_value_get(const char *service, const char *option)
{
FILE *fp;
char *line = NULL;
+ size_t len = 0;
char file[PATH_MAX];
snprintf(file, sizeof(file), RC_SVCDIR "/options/%s/%s",
service, option);
if ((fp = fopen(file, "r"))) {
- line = rc_getline(fp);
+ rc_getline(&line, &len, fp);
fclose(fp);
}
diff --git a/src/librc/librc.h b/src/librc/librc.h
index 376a62f..62d389b 100644
--- a/src/librc/librc.h
+++ b/src/librc/librc.h
@@ -71,6 +71,8 @@
#define librc_hidden_proto(x) hidden_proto(x)
#define librc_hidden_def(x) hidden_def(x)
+ssize_t rc_getline(char **, size_t *, FILE *);
+
librc_hidden_proto(rc_config_list)
librc_hidden_proto(rc_config_load)
librc_hidden_proto(rc_config_value)
diff --git a/src/librc/rc.h b/src/librc/rc.h
index ba49e78..5deb0e9 100644
--- a/src/librc/rc.h
+++ b/src/librc/rc.h
@@ -378,10 +378,6 @@ int rc_plugin_hook(RC_HOOK, const char *);
* variables they wish. Variables should be separated by NULLs. */
extern FILE *rc_environ_fd;
-/*! @name Configuration
- * These functions help to deal with shell based configuration files */
-/*! Return a line from a file, stripping the trailing newline. */
-char *rc_getline(FILE *);
/*! Return a NULL terminated list of non comment lines from a file. */
RC_STRINGLIST *rc_config_list(const char *);
diff --git a/src/librc/rc.map b/src/librc/rc.map
index 55dea00..845ae94 100644
--- a/src/librc/rc.map
+++ b/src/librc/rc.map
@@ -12,7 +12,6 @@ global:
rc_deptree_update_needed;
rc_environ_fd;
rc_find_pids;
- rc_getline;
rc_newer_than;
rc_runlevel_exists;
rc_runlevel_get;
diff --git a/src/rc/rc.c b/src/rc/rc.c
index 30bedcb..eec0332 100644
--- a/src/rc/rc.c
+++ b/src/rc/rc.c
@@ -49,6 +49,10 @@ const char rc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
# include <ifaddrs.h>
#endif
+#ifdef __linux__
+# include <asm/setup.h> /* for COMMAND_LINE_SIZE */
+#endif
+
#include <errno.h>
#include <dirent.h>
#include <ctype.h>
@@ -176,7 +180,7 @@ static void cleanup(void)
static char *proc_getent(const char *ent)
{
FILE *fp;
- char *proc;
+ char proc[COMMAND_LINE_SIZE];
char *p;
char *value = NULL;
int i;
@@ -189,9 +193,9 @@ static char *proc_getent(const char *ent)
return NULL;
}
- if ((proc = rc_getline(fp)) &&
- (p = strstr(proc, ent)))
- {
+ memset(proc, 0, sizeof(proc));
+ fgets(proc, sizeof(proc), fp);
+ if (*proc && (p = strstr(proc, ent))) {
i = p - proc;
if (i == '\0' || proc[i - 1] == ' ') {
p += strlen(ent);
@@ -201,7 +205,6 @@ static char *proc_getent(const char *ent)
}
} else
errno = ENOENT;
- free(proc);
fclose(fp);
return value;