Make rc_getline private and save it's buffer so it's sort of like getline from glibc.
This commit is contained in:
parent
b9eb450696
commit
51c825ceee
@ -22,17 +22,16 @@
|
|||||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
.\" SUCH DAMAGE.
|
.\" SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd Mar 16, 2008
|
.Dd Mar 17, 2008
|
||||||
.Dt RC_CONFIG 3 SMM
|
.Dt RC_CONFIG 3 SMM
|
||||||
.Os OpenRC
|
.Os OpenRC
|
||||||
.Sh NAME
|
.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
|
.Nd functions to query OpenRC service configurations
|
||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
Run Command library (librc, -lrc)
|
Run Command library (librc, -lrc)
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.In rc.h
|
.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_list "const char *file"
|
||||||
.Ft "RC_STRINGLIST *" Fn rc_config_load "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"
|
.Ft "char *" Fn rc_config_value "const char *const *list" "const char *entry"
|
||||||
@ -40,14 +39,6 @@ Run Command library (librc, -lrc)
|
|||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
These functions provide an easy means of querying OpenRC configuration files.
|
These functions provide an easy means of querying OpenRC configuration files.
|
||||||
.Pp
|
.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
|
.Fn rc_config_list
|
||||||
returns a list of non comment lines in
|
returns a list of non comment lines in
|
||||||
.Fa file .
|
.Fa file .
|
||||||
|
@ -311,7 +311,8 @@ librc_hidden_def(rc_find_pids)
|
|||||||
static bool _match_daemon(const char *path, const char *file,
|
static bool _match_daemon(const char *path, const char *file,
|
||||||
RC_STRINGLIST *match)
|
RC_STRINGLIST *match)
|
||||||
{
|
{
|
||||||
char *line;
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
char ffile[PATH_MAX];
|
char ffile[PATH_MAX];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
RC_STRING *m;
|
RC_STRING *m;
|
||||||
@ -322,7 +323,7 @@ static bool _match_daemon(const char *path, const char *file,
|
|||||||
if (! fp)
|
if (! fp)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while ((line = rc_getline(fp))) {
|
while ((rc_getline(&line, &len, fp))) {
|
||||||
TAILQ_FOREACH(m, match, entries)
|
TAILQ_FOREACH(m, match, entries)
|
||||||
if (strcmp(line, m->value) == 0) {
|
if (strcmp(line, m->value) == 0) {
|
||||||
TAILQ_REMOVE(match, m, entries);
|
TAILQ_REMOVE(match, m, entries);
|
||||||
@ -332,6 +333,7 @@ static bool _match_daemon(const char *path, const char *file,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
free(line);
|
||||||
if (TAILQ_FIRST(match))
|
if (TAILQ_FIRST(match))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@ -493,7 +495,8 @@ bool rc_service_daemons_crashed(const char *service)
|
|||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
char *path = dirpath;
|
char *path = dirpath;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *line;
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
char **argv = NULL;
|
char **argv = NULL;
|
||||||
char *exec = NULL;
|
char *exec = NULL;
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
@ -525,17 +528,13 @@ bool rc_service_daemons_crashed(const char *service)
|
|||||||
if (! fp)
|
if (! fp)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
while ((line = rc_getline(fp))) {
|
while ((rc_getline(&line, &len, fp))) {
|
||||||
p = line;
|
p = line;
|
||||||
if ((token = strsep(&p, "=")) == NULL || ! p) {
|
if ((token = strsep(&p, "=")) == NULL || ! p)
|
||||||
free(line);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (! *p) {
|
if (! *p)
|
||||||
free(line);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(token, "argv_", 5) == 0) {
|
if (strncmp(token, "argv_", 5) == 0) {
|
||||||
if (! list)
|
if (! list)
|
||||||
@ -551,11 +550,10 @@ bool rc_service_daemons_crashed(const char *service)
|
|||||||
name = xstrdup(p);
|
name = xstrdup(p);
|
||||||
} else if (strcmp(token, "pidfile") == 0) {
|
} else if (strcmp(token, "pidfile") == 0) {
|
||||||
pidfile = xstrdup(p);
|
pidfile = xstrdup(p);
|
||||||
free(line);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(line);
|
|
||||||
}
|
}
|
||||||
|
free(line);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
pid = 0;
|
pid = 0;
|
||||||
|
@ -121,7 +121,8 @@ RC_DEPTREE *rc_deptree_load(void)
|
|||||||
RC_DEPTREE *deptree;
|
RC_DEPTREE *deptree;
|
||||||
RC_DEPINFO *depinfo = NULL;
|
RC_DEPINFO *depinfo = NULL;
|
||||||
RC_DEPTYPE *deptype = NULL;
|
RC_DEPTYPE *deptype = NULL;
|
||||||
char *line;
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
char *type;
|
char *type;
|
||||||
char *p;
|
char *p;
|
||||||
char *e;
|
char *e;
|
||||||
@ -133,43 +134,43 @@ RC_DEPTREE *rc_deptree_load(void)
|
|||||||
deptree = xmalloc(sizeof(*deptree));
|
deptree = xmalloc(sizeof(*deptree));
|
||||||
STAILQ_INIT(deptree);
|
STAILQ_INIT(deptree);
|
||||||
|
|
||||||
while ((line = rc_getline(fp)))
|
while ((rc_getline(&line, &len, fp)))
|
||||||
{
|
{
|
||||||
p = line;
|
p = line;
|
||||||
e = strsep(&p, "_");
|
e = strsep(&p, "_");
|
||||||
if (! e || strcmp(e, "depinfo") != 0)
|
if (! e || strcmp(e, "depinfo") != 0)
|
||||||
goto next;
|
continue;
|
||||||
|
|
||||||
e = strsep (&p, "_");
|
e = strsep (&p, "_");
|
||||||
if (! e || sscanf(e, "%d", &i) != 1)
|
if (! e || sscanf(e, "%d", &i) != 1)
|
||||||
goto next;
|
continue;
|
||||||
|
|
||||||
if (! (type = strsep(&p, "_=")))
|
if (! (type = strsep(&p, "_=")))
|
||||||
goto next;
|
continue;
|
||||||
|
|
||||||
if (strcmp(type, "service") == 0)
|
if (strcmp(type, "service") == 0)
|
||||||
{
|
{
|
||||||
/* Sanity */
|
/* Sanity */
|
||||||
e = get_shell_value(p);
|
e = get_shell_value(p);
|
||||||
if (! e || *e == '\0')
|
if (! e || *e == '\0')
|
||||||
goto next;
|
continue;
|
||||||
|
|
||||||
depinfo = xmalloc(sizeof(*depinfo));
|
depinfo = xmalloc(sizeof(*depinfo));
|
||||||
STAILQ_INIT(&depinfo->depends);
|
STAILQ_INIT(&depinfo->depends);
|
||||||
depinfo->service = xstrdup(e);
|
depinfo->service = xstrdup(e);
|
||||||
STAILQ_INSERT_TAIL(deptree, depinfo, entries);
|
STAILQ_INSERT_TAIL(deptree, depinfo, entries);
|
||||||
deptype = NULL;
|
deptype = NULL;
|
||||||
goto next;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
e = strsep(&p, "=");
|
e = strsep(&p, "=");
|
||||||
if (! e || sscanf(e, "%d", &i) != 1)
|
if (! e || sscanf(e, "%d", &i) != 1)
|
||||||
goto next;
|
continue;
|
||||||
|
|
||||||
/* Sanity */
|
/* Sanity */
|
||||||
e = get_shell_value(p);
|
e = get_shell_value(p);
|
||||||
if (! e || *e == '\0')
|
if (! e || *e == '\0')
|
||||||
goto next;
|
continue;
|
||||||
|
|
||||||
if (! deptype || strcmp(deptype->type, type) != 0) {
|
if (! deptype || strcmp(deptype->type, type) != 0) {
|
||||||
deptype = xmalloc(sizeof(*deptype));
|
deptype = xmalloc(sizeof(*deptype));
|
||||||
@ -179,10 +180,9 @@ RC_DEPTREE *rc_deptree_load(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc_stringlist_add(deptype->services, e);
|
rc_stringlist_add(deptype->services, e);
|
||||||
next:
|
|
||||||
free(line);
|
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
free(line);
|
||||||
|
|
||||||
return deptree;
|
return deptree;
|
||||||
}
|
}
|
||||||
@ -724,14 +724,15 @@ bool rc_deptree_update(void)
|
|||||||
RC_STRING *s;
|
RC_STRING *s;
|
||||||
RC_STRING *s2;
|
RC_STRING *s2;
|
||||||
RC_DEPTYPE *provide;
|
RC_DEPTYPE *provide;
|
||||||
char *line;
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
char *depend;
|
char *depend;
|
||||||
char *depends;
|
char *depends;
|
||||||
char *service;
|
char *service;
|
||||||
char *type;
|
char *type;
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t k;
|
size_t k;
|
||||||
size_t len;
|
size_t l;
|
||||||
int retval = true;
|
int retval = true;
|
||||||
const char *sys = rc_sys();
|
const char *sys = rc_sys();
|
||||||
char *nosys;
|
char *nosys;
|
||||||
@ -750,14 +751,14 @@ bool rc_deptree_update(void)
|
|||||||
|
|
||||||
config = rc_stringlist_new();
|
config = rc_stringlist_new();
|
||||||
|
|
||||||
while ((line = rc_getline(fp)))
|
while ((rc_getline(&line, &len, fp)))
|
||||||
{
|
{
|
||||||
depends = line;
|
depends = line;
|
||||||
service = strsep(&depends, " ");
|
service = strsep(&depends, " ");
|
||||||
if (! service || ! *service)
|
if (! service || ! *service)
|
||||||
goto next;
|
continue;
|
||||||
type = strsep(&depends, " ");
|
|
||||||
|
|
||||||
|
type = strsep(&depends, " ");
|
||||||
if (! depinfo || strcmp(depinfo->service, service) != 0) {
|
if (! depinfo || strcmp(depinfo->service, service) != 0) {
|
||||||
deptype = NULL;
|
deptype = NULL;
|
||||||
depinfo = get_depinfo(deptree, service);
|
depinfo = get_depinfo(deptree, service);
|
||||||
@ -771,7 +772,7 @@ bool rc_deptree_update(void)
|
|||||||
|
|
||||||
/* We may not have any depends */
|
/* We may not have any depends */
|
||||||
if (! type || ! depends)
|
if (! type || ! depends)
|
||||||
goto next;
|
continue;
|
||||||
|
|
||||||
/* Get the type */
|
/* Get the type */
|
||||||
if (strcmp(type, "config") != 0) {
|
if (strcmp(type, "config") != 0) {
|
||||||
@ -798,11 +799,11 @@ bool rc_deptree_update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* .sh files are not init scripts */
|
/* .sh files are not init scripts */
|
||||||
len = strlen(depend);
|
l = strlen(depend);
|
||||||
if (len > 2 &&
|
if (l > 2 &&
|
||||||
depend[len - 3] == '.' &&
|
depend[l - 3] == '.' &&
|
||||||
depend[len - 2] == 's' &&
|
depend[l - 2] == 's' &&
|
||||||
depend[len - 1] == 'h')
|
depend[l - 1] == 'h')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Remove our dependency if instructed */
|
/* Remove our dependency if instructed */
|
||||||
@ -828,10 +829,8 @@ bool rc_deptree_update(void)
|
|||||||
rc_stringlist_delete(dt->services, depend);
|
rc_stringlist_delete(dt->services, depend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
next:
|
|
||||||
free(line);
|
|
||||||
}
|
}
|
||||||
|
free(line);
|
||||||
pclose(fp);
|
pclose(fp);
|
||||||
|
|
||||||
/* Phase 2 - if we're a special system, remove services that don't
|
/* Phase 2 - if we're a special system, remove services that don't
|
||||||
|
@ -54,37 +54,38 @@ bool rc_yesno (const char *value)
|
|||||||
}
|
}
|
||||||
librc_hidden_def(rc_yesno)
|
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;
|
char *p;
|
||||||
size_t len = 0;
|
|
||||||
size_t last = 0;
|
size_t last = 0;
|
||||||
|
|
||||||
if (feof (fp))
|
if (feof(fp))
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
len += BUFSIZ;
|
if (*line == NULL || last != 0) {
|
||||||
line = xrealloc (line, sizeof (char) * len);
|
*len += BUFSIZ;
|
||||||
p = line + last;
|
*line = xrealloc(*line, *len);
|
||||||
memset (p, 0, BUFSIZ);
|
}
|
||||||
fgets (p, BUFSIZ, fp);
|
p = *line + last;
|
||||||
last += strlen (p);
|
memset(p, 0, BUFSIZ);
|
||||||
} while (! feof (fp) && line[last - 1] != '\n');
|
fgets(p, BUFSIZ, fp);
|
||||||
|
last += strlen(p);
|
||||||
|
} while (! feof(fp) && (*line)[last - 1] != '\n');
|
||||||
|
|
||||||
/* Trim the trailing newline */
|
/* Trim the trailing newline */
|
||||||
if (*line && line[--last] == '\n')
|
if (**line && (*line)[last - 1] == '\n')
|
||||||
line[last] = '\0';
|
(*line)[last - 1] = '\0';
|
||||||
|
|
||||||
return line;
|
return last;
|
||||||
}
|
}
|
||||||
librc_hidden_def(rc_getline)
|
librc_hidden_def(rc_getline)
|
||||||
|
|
||||||
RC_STRINGLIST *rc_config_list(const char *file)
|
RC_STRINGLIST *rc_config_list(const char *file)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *buffer;
|
char *buffer = NULL;
|
||||||
|
size_t len = 0;
|
||||||
char *p;
|
char *p;
|
||||||
char *token;
|
char *token;
|
||||||
RC_STRINGLIST *list = NULL;
|
RC_STRINGLIST *list = NULL;
|
||||||
@ -92,7 +93,8 @@ RC_STRINGLIST *rc_config_list(const char *file)
|
|||||||
if (!(fp = fopen(file, "r")))
|
if (!(fp = fopen(file, "r")))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while ((p = buffer = rc_getline(fp))) {
|
while ((rc_getline(&buffer, &len, fp))) {
|
||||||
|
p = buffer;
|
||||||
/* Strip leading spaces/tabs */
|
/* Strip leading spaces/tabs */
|
||||||
while ((*p == ' ') || (*p == '\t'))
|
while ((*p == ' ') || (*p == '\t'))
|
||||||
p++;
|
p++;
|
||||||
@ -111,9 +113,9 @@ RC_STRINGLIST *rc_config_list(const char *file)
|
|||||||
rc_stringlist_add(list, token);
|
rc_stringlist_add(list, token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(buffer);
|
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,8 @@ static bool rm_dir(const char *pathname, bool top)
|
|||||||
static bool file_regex(const char *file, const char *regex)
|
static bool file_regex(const char *file, const char *regex)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *line;
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
regex_t re;
|
regex_t re;
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
int result;
|
int result;
|
||||||
@ -183,14 +184,14 @@ static bool file_regex(const char *file, const char *regex)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((line = rc_getline(fp))) {
|
while ((rc_getline(&line, &len, fp))) {
|
||||||
if (regexec(&re, line, 0, NULL, 0) == 0)
|
if (regexec(&re, line, 0, NULL, 0) == 0)
|
||||||
retval = true;
|
retval = true;
|
||||||
free(line);
|
|
||||||
if (retval)
|
if (retval)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
free(line);
|
||||||
regfree(&re);
|
regfree(&re);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
@ -401,6 +402,7 @@ RC_STRINGLIST *rc_service_extra_commands(const char *service)
|
|||||||
char *svc;
|
char *svc;
|
||||||
char *cmd = NULL;
|
char *cmd = NULL;
|
||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
|
size_t len = 0;
|
||||||
RC_STRINGLIST *commands = NULL;
|
RC_STRINGLIST *commands = NULL;
|
||||||
char *token;
|
char *token;
|
||||||
char *p;
|
char *p;
|
||||||
@ -417,7 +419,8 @@ RC_STRINGLIST *rc_service_extra_commands(const char *service)
|
|||||||
free(svc);
|
free(svc);
|
||||||
|
|
||||||
if ((fp = popen(cmd, "r"))) {
|
if ((fp = popen(cmd, "r"))) {
|
||||||
p = buffer = rc_getline(fp);
|
rc_getline(&buffer, &len, fp);
|
||||||
|
p = buffer;
|
||||||
while ((token = strsep(&p, " "))) {
|
while ((token = strsep(&p, " "))) {
|
||||||
if (! commands)
|
if (! commands)
|
||||||
commands = rc_stringlist_new();
|
commands = rc_stringlist_new();
|
||||||
@ -437,6 +440,7 @@ char *rc_service_description(const char *service, const char *option)
|
|||||||
char *svc;
|
char *svc;
|
||||||
char *cmd;
|
char *cmd;
|
||||||
char *desc = NULL;
|
char *desc = NULL;
|
||||||
|
size_t len = 0;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
@ -451,7 +455,7 @@ char *rc_service_description(const char *service, const char *option)
|
|||||||
snprintf(cmd, l, DESCSTR, svc, option ? "_" : "", option);
|
snprintf(cmd, l, DESCSTR, svc, option ? "_" : "", option);
|
||||||
free(svc);
|
free(svc);
|
||||||
if ((fp = popen(cmd, "r"))) {
|
if ((fp = popen(cmd, "r"))) {
|
||||||
desc = rc_getline(fp);
|
rc_getline(&desc, &len, fp);
|
||||||
pclose(fp);
|
pclose(fp);
|
||||||
}
|
}
|
||||||
free(cmd);
|
free(cmd);
|
||||||
@ -633,12 +637,13 @@ char *rc_service_value_get(const char *service, const char *option)
|
|||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
char file[PATH_MAX];
|
char file[PATH_MAX];
|
||||||
|
|
||||||
snprintf(file, sizeof(file), RC_SVCDIR "/options/%s/%s",
|
snprintf(file, sizeof(file), RC_SVCDIR "/options/%s/%s",
|
||||||
service, option);
|
service, option);
|
||||||
if ((fp = fopen(file, "r"))) {
|
if ((fp = fopen(file, "r"))) {
|
||||||
line = rc_getline(fp);
|
rc_getline(&line, &len, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +71,8 @@
|
|||||||
#define librc_hidden_proto(x) hidden_proto(x)
|
#define librc_hidden_proto(x) hidden_proto(x)
|
||||||
#define librc_hidden_def(x) hidden_def(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_list)
|
||||||
librc_hidden_proto(rc_config_load)
|
librc_hidden_proto(rc_config_load)
|
||||||
librc_hidden_proto(rc_config_value)
|
librc_hidden_proto(rc_config_value)
|
||||||
|
@ -378,10 +378,6 @@ int rc_plugin_hook(RC_HOOK, const char *);
|
|||||||
* variables they wish. Variables should be separated by NULLs. */
|
* variables they wish. Variables should be separated by NULLs. */
|
||||||
extern FILE *rc_environ_fd;
|
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. */
|
/*! Return a NULL terminated list of non comment lines from a file. */
|
||||||
RC_STRINGLIST *rc_config_list(const char *);
|
RC_STRINGLIST *rc_config_list(const char *);
|
||||||
|
@ -12,7 +12,6 @@ global:
|
|||||||
rc_deptree_update_needed;
|
rc_deptree_update_needed;
|
||||||
rc_environ_fd;
|
rc_environ_fd;
|
||||||
rc_find_pids;
|
rc_find_pids;
|
||||||
rc_getline;
|
|
||||||
rc_newer_than;
|
rc_newer_than;
|
||||||
rc_runlevel_exists;
|
rc_runlevel_exists;
|
||||||
rc_runlevel_get;
|
rc_runlevel_get;
|
||||||
|
13
src/rc/rc.c
13
src/rc/rc.c
@ -49,6 +49,10 @@ const char rc_copyright[] = "Copyright (c) 2007-2008 Roy Marples";
|
|||||||
# include <ifaddrs.h>
|
# include <ifaddrs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
# include <asm/setup.h> /* for COMMAND_LINE_SIZE */
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -176,7 +180,7 @@ static void cleanup(void)
|
|||||||
static char *proc_getent(const char *ent)
|
static char *proc_getent(const char *ent)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *proc;
|
char proc[COMMAND_LINE_SIZE];
|
||||||
char *p;
|
char *p;
|
||||||
char *value = NULL;
|
char *value = NULL;
|
||||||
int i;
|
int i;
|
||||||
@ -189,9 +193,9 @@ static char *proc_getent(const char *ent)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((proc = rc_getline(fp)) &&
|
memset(proc, 0, sizeof(proc));
|
||||||
(p = strstr(proc, ent)))
|
fgets(proc, sizeof(proc), fp);
|
||||||
{
|
if (*proc && (p = strstr(proc, ent))) {
|
||||||
i = p - proc;
|
i = p - proc;
|
||||||
if (i == '\0' || proc[i - 1] == ' ') {
|
if (i == '\0' || proc[i - 1] == ' ') {
|
||||||
p += strlen(ent);
|
p += strlen(ent);
|
||||||
@ -201,7 +205,6 @@ static char *proc_getent(const char *ent)
|
|||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
free(proc);
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
|
Loading…
Reference in New Issue
Block a user