Make rc_getline private and save it's buffer so it's sort of like getline from glibc.

This commit is contained in:
Roy Marples 2008-03-17 21:27:37 +00:00
parent b9eb450696
commit 51c825ceee
9 changed files with 77 additions and 82 deletions

View File

@ -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 .

View File

@ -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;

View File

@ -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

View File

@ -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;
return 0;
do {
len += BUFSIZ;
line = xrealloc (line, sizeof (char) * len);
p = line + last;
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');
} 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;
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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 *);

View File

@ -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;

View File

@ -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;