diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c index d584af2cd..f39917289 100644 --- a/src/librc/librc-depend.c +++ b/src/librc/librc-depend.c @@ -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 */ @@ -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) { @@ -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); @@ -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; @@ -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) @@ -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; } @@ -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); @@ -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; @@ -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; @@ -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) @@ -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 */ @@ -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; @@ -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 */ @@ -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] = '-'; @@ -893,29 +901,30 @@ 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); } @@ -923,24 +932,20 @@ rc_deptree_update(void) /* 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) @@ -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(); @@ -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++; @@ -1078,8 +1070,7 @@ 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 { @@ -1087,6 +1078,6 @@ rc_deptree_update(void) } rc_stringlist_free(config); - free(deptree); + rc_deptree_free(deptree); return retval; }