Skip to content

Commit

Permalink
librc/librc-depend.c: small refactor
Browse files Browse the repository at this point in the history
some changes for code redability, and fixing leaking the whole internals
of the deptree at the end of rc_deptree_update.
  • Loading branch information
navi-desu authored and williamh committed Jul 22, 2024
1 parent 6ddec6a commit 446e621
Showing 1 changed file with 96 additions and 105 deletions.
201 changes: 96 additions & 105 deletions src/librc/librc-depend.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,27 +67,23 @@ void
rc_deptree_free(RC_DEPTREE *deptree)
{
RC_DEPINFO *di;
RC_DEPINFO *di2;
RC_DEPINFO *di_save;
RC_DEPTYPE *dt;
RC_DEPTYPE *dt2;
RC_DEPTYPE *dt_save;

if (!deptree)
return;

di = TAILQ_FIRST(deptree);
while (di) {
di2 = TAILQ_NEXT(di, entries);
dt = TAILQ_FIRST(&di->depends);
while (dt) {
dt2 = TAILQ_NEXT(dt, entries);
TAILQ_FOREACH_SAFE(di, deptree, entries, di_save) {
TAILQ_FOREACH_SAFE(dt, &di->depends, entries, dt_save) {
TAILQ_REMOVE(&di->depends, dt, entries);
rc_stringlist_free(dt->services);
free(dt->type);
free(dt);
dt = dt2;
}
TAILQ_REMOVE(deptree, di, entries);
free(di->service);
free(di);
di = di2;
}

/* Use free() here since rc_deptree_free should not call itself */
Expand All @@ -106,6 +102,17 @@ get_depinfo(const RC_DEPTREE *deptree, const char *service)
return NULL;
}

static RC_DEPINFO *
make_depinfo(RC_DEPTREE *deptree, const char *service)
{
RC_DEPINFO *depinfo = xmalloc(sizeof(*depinfo));
TAILQ_INIT(&depinfo->depends);
depinfo->service = xstrdup(service);
TAILQ_INSERT_TAIL(deptree, depinfo, entries);

return depinfo;
}

static RC_DEPTYPE *
get_deptype(const RC_DEPINFO *depinfo, const char *type)
{
Expand All @@ -119,6 +126,17 @@ get_deptype(const RC_DEPINFO *depinfo, const char *type)
return NULL;
}

static RC_DEPTYPE *
make_deptype(RC_DEPINFO *depinfo, const char *type)
{
RC_DEPTYPE *deptype = xmalloc(sizeof(*deptype));
deptype->type = xstrdup(type);
deptype->services = rc_stringlist_new();
TAILQ_INSERT_TAIL(&depinfo->depends, deptype, entries);

return deptype;
}

RC_DEPTREE *
rc_deptree_load(void) {
return rc_deptree_load_file(RC_DEPTREE_CACHE);
Expand All @@ -133,6 +151,7 @@ rc_deptree_load_file(const char *deptree_file)
RC_DEPTYPE *deptype = NULL;
char *line = NULL;
size_t len = 0;
ssize_t size;
char *type;
char *p;
char *e;
Expand All @@ -143,8 +162,8 @@ rc_deptree_load_file(const char *deptree_file)

deptree = xmalloc(sizeof(*deptree));
TAILQ_INIT(deptree);
while ((rc_getline(&line, &len, fp)))
{
while ((size = getline(&line, &len, fp)) != -1) {
line[size - 1] = '\0';
p = line;
e = strsep(&p, "_");
if (!e || strcmp(e, "depinfo") != 0)
Expand All @@ -159,10 +178,7 @@ rc_deptree_load_file(const char *deptree_file)
e = get_shell_value(p);
if (!e || *e == '\0')
continue;
depinfo = xmalloc(sizeof(*depinfo));
TAILQ_INIT(&depinfo->depends);
depinfo->service = xstrdup(e);
TAILQ_INSERT_TAIL(deptree, depinfo, entries);
depinfo = make_depinfo(deptree, e);
deptype = NULL;
continue;
}
Expand All @@ -173,12 +189,8 @@ rc_deptree_load_file(const char *deptree_file)
e = get_shell_value(p);
if (!e || *e == '\0')
continue;
if (!deptype || strcmp(deptype->type, type) != 0) {
deptype = xmalloc(sizeof(*deptype));
deptype->services = rc_stringlist_new();
deptype->type = xstrdup(type);
TAILQ_INSERT_TAIL(&depinfo->depends, deptype, entries);
}
if (!deptype || strcmp(deptype->type, type) != 0)
deptype = make_deptype(depinfo, type);
rc_stringlist_add(deptype->services, e);
}
fclose(fp);
Expand Down Expand Up @@ -759,6 +771,7 @@ rc_deptree_update_needed(time_t *newest, char *file)
bool
rc_deptree_update(void)
{

FILE *fp;
RC_DEPTREE *deptree, *providers;
RC_DEPINFO *depinfo = NULL, *depinfo_np, *di;
Expand All @@ -767,8 +780,9 @@ rc_deptree_update(void)
RC_STRING *s, *s2, *s2_np, *s3, *s4;
char *line = NULL;
size_t len = 0;
char *depend, *depends, *service, *type, *nosys, *onosys;
size_t i, k, l;
ssize_t size;
char *depend, *depends, *service, *type;
size_t i, l;
bool retval = true;
const char *sys = rc_sys();
struct utsname uts;
Expand All @@ -785,11 +799,12 @@ rc_deptree_update(void)
if (!(fp = popen(GENDEP, "r")))
return false;

config = rc_stringlist_new();

deptree = xmalloc(sizeof(*deptree));
TAILQ_INIT(deptree);
config = rc_stringlist_new();
while ((rc_getline(&line, &len, fp)))
{
while ((size = getline(&line, &len, fp)) != -1) {
line[size - 1] = '\0';
depends = line;
service = strsep(&depends, " ");
if (!service || !*service)
Expand All @@ -799,12 +814,8 @@ rc_deptree_update(void)
if (!depinfo || strcmp(depinfo->service, service) != 0) {
deptype = NULL;
depinfo = get_depinfo(deptree, service);
if (!depinfo) {
depinfo = xmalloc(sizeof(*depinfo));
TAILQ_INIT(&depinfo->depends);
depinfo->service = xstrdup(service);
TAILQ_INSERT_TAIL(deptree, depinfo, entries);
}
if (!depinfo)
depinfo = make_depinfo(deptree, service);
}

/* We may not have any depends */
Expand All @@ -813,20 +824,16 @@ rc_deptree_update(void)

/* Get the type */
if (strcmp(type, "config") != 0) {
if (!deptype || strcmp(deptype->type, type) != 0)
if (!deptype || strcmp(deptype->type, type) != 0) {
deptype = get_deptype(depinfo, type);
if (!deptype) {
deptype = xmalloc(sizeof(*deptype));
deptype->type = xstrdup(type);
deptype->services = rc_stringlist_new();
TAILQ_INSERT_TAIL(&depinfo->depends, deptype, entries);
if (!deptype)
deptype = make_deptype(depinfo, type);
}
}

/* Now add each depend to our type.
We do this individually so we handle multiple spaces gracefully */
while ((depend = strsep(&depends, " ")))
{
while ((depend = strsep(&depends, " "))) {
if (depend[0] == 0)
continue;

Expand All @@ -835,9 +842,8 @@ rc_deptree_update(void)
continue;
}

/* Don't provide ourself */
if (strcmp(type, "iprovide") == 0 &&
strcmp(depend, service) == 0)
/* Don't depend on ourself */
if (strcmp(depend, service) == 0)
continue;

/* .sh files are not init scripts */
Expand Down Expand Up @@ -879,6 +885,8 @@ rc_deptree_update(void)
/* Phase 2 - if we're a special system, remove services that don't
* work for them. This doesn't stop them from being run directly. */
if (sys) {
char *nosys, *onosys;

len = strlen(sys);
nosys = xmalloc(len + 2);
nosys[0] = '-';
Expand All @@ -893,54 +901,51 @@ rc_deptree_update(void)
onosys[i + 2] = (char)tolower((unsigned char)sys[i]);
onosys[i + 2] = '\0';

TAILQ_FOREACH_SAFE(depinfo, deptree, entries, depinfo_np)
if ((deptype = get_deptype(depinfo, "keyword")))
TAILQ_FOREACH(s, deptype->services, entries)
if (strcmp(s->value, nosys) == 0 ||
strcmp(s->value, onosys) == 0)
{
provide = get_deptype(depinfo, "iprovide");
TAILQ_REMOVE(deptree, depinfo, entries);
TAILQ_FOREACH(di, deptree, entries) {
TAILQ_FOREACH_SAFE(dt, &di->depends, entries, dt_np) {
rc_stringlist_delete(dt->services, depinfo->service);
if (provide)
TAILQ_FOREACH(s2, provide->services, entries)
rc_stringlist_delete(dt->services, s2->value);
if (!TAILQ_FIRST(dt->services)) {
TAILQ_REMOVE(&di->depends, dt, entries);
free(dt->type);
free(dt->services);
free(dt);
}
}
TAILQ_FOREACH_SAFE(depinfo, deptree, entries, depinfo_np) {
if (!(deptype = get_deptype(depinfo, "keyword")))
continue;
TAILQ_FOREACH(s, deptype->services, entries) {
if (strcmp(s->value, nosys) != 0 && strcmp(s->value, onosys) != 0)
continue;
provide = get_deptype(depinfo, "iprovide");
TAILQ_REMOVE(deptree, depinfo, entries);
TAILQ_FOREACH(di, deptree, entries) {
TAILQ_FOREACH_SAFE(dt, &di->depends, entries, dt_np) {
rc_stringlist_delete(dt->services, depinfo->service);
if (provide)
TAILQ_FOREACH(s2, provide->services, entries)
rc_stringlist_delete(dt->services, s2->value);
if (!TAILQ_FIRST(dt->services)) {
TAILQ_REMOVE(&di->depends, dt, entries);
free(dt->type);
free(dt->services);
free(dt);
}
}
}
}
}
free(nosys);
free(onosys);
}

/* Phase 3 - add our providers to the tree */
providers = xmalloc(sizeof(*providers));
TAILQ_INIT(providers);
TAILQ_FOREACH(depinfo, deptree, entries)
if ((deptype = get_deptype(depinfo, "iprovide")))
TAILQ_FOREACH(s, deptype->services, entries) {
TAILQ_FOREACH(di, providers, entries)
if (strcmp(di->service, s->value) == 0)
break;
if (!di) {
di = xmalloc(sizeof(*di));
TAILQ_INIT(&di->depends);
di->service = xstrdup(s->value);
TAILQ_INSERT_TAIL(providers, di, entries);
}
}
TAILQ_FOREACH(depinfo, deptree, entries) {
if (!(deptype = get_deptype(depinfo, "iprovide")))
continue;
TAILQ_FOREACH(s, deptype->services, entries) {
di = get_depinfo(providers, s->value);
if (!di)
di = make_depinfo(providers, s->value);
}
}
TAILQ_CONCAT(deptree, providers, entries);
free(providers);

/* Phase 4 - backreference our depends */
TAILQ_FOREACH(depinfo, deptree, entries)
TAILQ_FOREACH(depinfo, deptree, entries) {
for (i = 0; deppairs[i].depend; i++) {
deptype = get_deptype(depinfo, deppairs[i].depend);
if (!deptype)
Expand All @@ -949,33 +954,23 @@ rc_deptree_update(void)
di = get_depinfo(deptree, s->value);
if (!di) {
if (strcmp(deptype->type, "ineed") == 0) {
fprintf(stderr,
"Service `%s' needs non"
" existent service `%s'\n",
fprintf(stderr, "Service '%s' needs non existent service '%s'\n",
depinfo->service, s->value);
dt = get_deptype(depinfo, "broken");
if (!dt) {
dt = xmalloc(sizeof(*dt));
dt->type = xstrdup("broken");
dt->services = rc_stringlist_new();
TAILQ_INSERT_TAIL(&depinfo->depends, dt, entries);
}
if (!dt)
dt = make_deptype(depinfo, "broken");
rc_stringlist_addu(dt->services, s->value);
}
continue;
}

dt = get_deptype(di, deppairs[i].addto);
if (!dt) {
dt = xmalloc(sizeof(*dt));
dt->type = xstrdup(deppairs[i].addto);
dt->services = rc_stringlist_new();
TAILQ_INSERT_TAIL(&di->depends, dt, entries);
}
if (!dt)
dt = make_deptype(di, deppairs[i].addto);
rc_stringlist_addu(dt->services, depinfo->service);
}
}

}

/* Phase 5 - Remove broken before directives */
types = rc_stringlist_new();
Expand Down Expand Up @@ -1051,15 +1046,12 @@ rc_deptree_update(void)
if ((fp = fopen(RC_DEPTREE_CACHE, "w"))) {
i = 0;
TAILQ_FOREACH(depinfo, deptree, entries) {
fprintf(fp, "depinfo_%zu_service='%s'\n",
i, depinfo->service);
fprintf(fp, "depinfo_%zu_service='%s'\n", i, depinfo->service);
TAILQ_FOREACH(deptype, &depinfo->depends, entries) {
k = 0;
size_t k = 0;
TAILQ_FOREACH(s, deptype->services, entries) {
fprintf(fp,
"depinfo_%zu_%s_%zu='%s'\n",
i, deptype->type, k, s->value);
k++;
fprintf(fp, "depinfo_%zu_%s_%zu='%s'\n",
i, deptype->type, k++, s->value);
}
}
i++;
Expand All @@ -1078,15 +1070,14 @@ rc_deptree_update(void)
fprintf(fp, "%s\n", s->value);
fclose(fp);
} else {
fprintf(stderr, "fopen `%s': %s\n",
RC_DEPCONFIG, strerror(errno));
fprintf(stderr, "fopen `%s': %s\n", RC_DEPCONFIG, strerror(errno));
retval = false;
}
} else {
unlink(RC_DEPCONFIG);
}

rc_stringlist_free(config);
free(deptree);
rc_deptree_free(deptree);
return retval;
}

0 comments on commit 446e621

Please sign in to comment.