/[baselayout]/trunk/src/librc-depend.c
Gentoo

Diff of /trunk/src/librc-depend.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 2556 Revision 2569
57 { 57 {
58 rc_depinfo_t *dip = di->next; 58 rc_depinfo_t *dip = di->next;
59 rc_deptype_t *dt = di->depends; 59 rc_deptype_t *dt = di->depends;
60 free (di->service); 60 free (di->service);
61 while (dt) 61 while (dt)
62 { 62 {
63 rc_deptype_t *dtp = dt->next; 63 rc_deptype_t *dtp = dt->next;
64 free (dt->type); 64 free (dt->type);
65 rc_strlist_free (dt->services); 65 rc_strlist_free (dt->services);
66 free (dt); 66 free (dt);
67 dt = dtp; 67 dt = dtp;
68 } 68 }
69 free (di); 69 free (di);
70 di = dip; 70 di = dip;
71 } 71 }
72} 72}
73 73
92 while (fgets (buffer, RC_LINEBUFFER, fp)) 92 while (fgets (buffer, RC_LINEBUFFER, fp))
93 { 93 {
94 p = buffer; 94 p = buffer;
95 e = strsep (&p, "_"); 95 e = strsep (&p, "_");
96 if (! e || strcmp (e, "depinfo") != 0) 96 if (! e || strcmp (e, "depinfo") != 0)
97 continue; 97 continue;
98 98
99 e = strsep (&p, "_"); 99 e = strsep (&p, "_");
100 if (! e || sscanf (e, "%d", &i) != 1) 100 if (! e || sscanf (e, "%d", &i) != 1)
101 continue; 101 continue;
102 102
103 if (! (type = strsep (&p, "_="))) 103 if (! (type = strsep (&p, "_=")))
104 continue; 104 continue;
105 105
106 if (strcmp (type, "service") == 0) 106 if (strcmp (type, "service") == 0)
107 { 107 {
108 /* Sanity */ 108 /* Sanity */
109 e = get_shell_value (p); 109 e = get_shell_value (p);
110 if (! e || strlen (e) == 0) 110 if (! e || strlen (e) == 0)
111 continue; 111 continue;
112 112
113 if (! deptree) 113 if (! deptree)
114 { 114 {
115 deptree = rc_xmalloc (sizeof (rc_depinfo_t)); 115 deptree = rc_xmalloc (sizeof (rc_depinfo_t));
116 depinfo = deptree; 116 depinfo = deptree;
117 } 117 }
118 else 118 else
119 { 119 {
120 depinfo->next = rc_xmalloc (sizeof (rc_depinfo_t)); 120 depinfo->next = rc_xmalloc (sizeof (rc_depinfo_t));
121 depinfo = depinfo->next; 121 depinfo = depinfo->next;
122 } 122 }
123 memset (depinfo, 0, sizeof (rc_depinfo_t)); 123 memset (depinfo, 0, sizeof (rc_depinfo_t));
124 depinfo->service = strdup (e); 124 depinfo->service = strdup (e);
125 deptype = NULL; 125 deptype = NULL;
126 continue; 126 continue;
127 } 127 }
128 128
129 e = strsep (&p, "="); 129 e = strsep (&p, "=");
130 if (! e || sscanf (e, "%d", &i) != 1) 130 if (! e || sscanf (e, "%d", &i) != 1)
131 continue; 131 continue;
132 132
133 /* Sanity */ 133 /* Sanity */
134 e = get_shell_value (p); 134 e = get_shell_value (p);
135 if (! e || strlen (e) == 0) 135 if (! e || strlen (e) == 0)
136 continue; 136 continue;
137 137
138 if (! deptype) 138 if (! deptype)
139 { 139 {
140 depinfo->depends = rc_xmalloc (sizeof (rc_deptype_t)); 140 depinfo->depends = rc_xmalloc (sizeof (rc_deptype_t));
141 deptype = depinfo->depends; 141 deptype = depinfo->depends;
142 memset (deptype, 0, sizeof (rc_deptype_t)); 142 memset (deptype, 0, sizeof (rc_deptype_t));
143 } 143 }
144 else 144 else
145 if (strcmp (deptype->type, type) != 0) 145 if (strcmp (deptype->type, type) != 0)
146 { 146 {
147 deptype->next = rc_xmalloc (sizeof (rc_deptype_t)); 147 deptype->next = rc_xmalloc (sizeof (rc_deptype_t));
148 deptype = deptype->next; 148 deptype = deptype->next;
149 memset (deptype, 0, sizeof (rc_deptype_t)); 149 memset (deptype, 0, sizeof (rc_deptype_t));
150 } 150 }
151 151
152 if (! deptype->type) 152 if (! deptype->type)
153 deptype->type = strdup (type); 153 deptype->type = strdup (type);
154 154
155 deptype->services = rc_strlist_addsort (deptype->services, e); 155 deptype->services = rc_strlist_addsort (deptype->services, e);
156 } 156 }
157 fclose (fp); 157 fclose (fp);
158 158
188} 188}
189 189
190static bool valid_service (const char *runlevel, const char *service) 190static bool valid_service (const char *runlevel, const char *service)
191{ 191{
192 return ((strcmp (runlevel, RC_LEVEL_BOOT) != 0 && 192 return ((strcmp (runlevel, RC_LEVEL_BOOT) != 0 &&
193 rc_service_in_runlevel (service, RC_LEVEL_BOOT)) || 193 rc_service_in_runlevel (service, RC_LEVEL_BOOT)) ||
194 rc_service_in_runlevel (service, runlevel) || 194 rc_service_in_runlevel (service, runlevel) ||
195 rc_service_state (service, rc_service_coldplugged) || 195 rc_service_state (service, rc_service_coldplugged) ||
196 rc_service_state (service, rc_service_started)); 196 rc_service_state (service, rc_service_started));
197} 197}
198 198
199static bool get_provided1 (const char *runlevel, struct lhead *providers, 199static bool get_provided1 (const char *runlevel, struct lhead *providers,
200 rc_deptype_t *deptype, 200 rc_deptype_t *deptype,
201 const char *level, bool coldplugged, 201 const char *level, bool coldplugged,
202 bool started, bool inactive) 202 bool started, bool inactive)
203{ 203{
204 char *service; 204 char *service;
205 int i; 205 int i;
206 bool retval = false; 206 bool retval = false;
207 207
208 STRLIST_FOREACH (deptype->services, service, i) 208 STRLIST_FOREACH (deptype->services, service, i)
209 { 209 {
210 bool ok = true; 210 bool ok = true;
211 if (level) 211 if (level)
212 ok = rc_service_in_runlevel (service, level); 212 ok = rc_service_in_runlevel (service, level);
213 else if (coldplugged) 213 else if (coldplugged)
214 ok = (rc_service_state (service, rc_service_coldplugged) && 214 ok = (rc_service_state (service, rc_service_coldplugged) &&
215 ! rc_service_in_runlevel (service, runlevel) && 215 ! rc_service_in_runlevel (service, runlevel) &&
216 ! rc_service_in_runlevel (service, RC_LEVEL_BOOT)); 216 ! rc_service_in_runlevel (service, RC_LEVEL_BOOT));
217 217
218 if (! ok) 218 if (! ok)
219 continue; 219 continue;
220 220
221 if (started) 221 if (started)
222 ok = (rc_service_state (service, rc_service_starting) || 222 ok = (rc_service_state (service, rc_service_starting) ||
223 rc_service_state (service, rc_service_started) || 223 rc_service_state (service, rc_service_started) ||
224 rc_service_state (service, rc_service_stopping)); 224 rc_service_state (service, rc_service_stopping));
225 else if (inactive) 225 else if (inactive)
226 ok = rc_service_state (service, rc_service_inactive); 226 ok = rc_service_state (service, rc_service_inactive);
227 227
228 if (! ok) 228 if (! ok)
229 continue; 229 continue;
230 230
231 retval = true; 231 retval = true;
232 providers->list = rc_strlist_add (providers->list, service); 232 providers->list = rc_strlist_add (providers->list, service);
233 } 233 }
234 234
235 return (retval); 235 return (retval);
243 243
244 If there are any bugs in rc-depend, they will probably be here as 244 If there are any bugs in rc-depend, they will probably be here as
245 provided dependancy can change depending on runlevel state. 245 provided dependancy can change depending on runlevel state.
246 */ 246 */
247static char **get_provided (rc_depinfo_t *deptree, rc_depinfo_t *depinfo, 247static char **get_provided (rc_depinfo_t *deptree, rc_depinfo_t *depinfo,
248 const char *runlevel, int options) 248 const char *runlevel, int options)
249{ 249{
250 rc_deptype_t *dt; 250 rc_deptype_t *dt;
251 struct lhead providers; 251 struct lhead providers;
252 char *service; 252 char *service;
253 int i; 253 int i;
266 This is especially true for net services as they could force a restart 266 This is especially true for net services as they could force a restart
267 of the local dns resolver which may depend on net. */ 267 of the local dns resolver which may depend on net. */
268 if (options & RC_DEP_STOP) 268 if (options & RC_DEP_STOP)
269 { 269 {
270 STRLIST_FOREACH (dt->services, service, i) 270 STRLIST_FOREACH (dt->services, service, i)
271 providers.list = rc_strlist_add (providers.list, service); 271 providers.list = rc_strlist_add (providers.list, service);
272 272
273 return (providers.list); 273 return (providers.list);
274 } 274 }
275 275
276 /* If we're strict, then only use what we have in our runlevel */ 276 /* If we're strict, then only use what we have in our runlevel */
277 if (options & RC_DEP_STRICT) 277 if (options & RC_DEP_STRICT)
278 { 278 {
279 STRLIST_FOREACH (dt->services, service, i) 279 STRLIST_FOREACH (dt->services, service, i)
280 if (rc_service_in_runlevel (service, runlevel)) 280 if (rc_service_in_runlevel (service, runlevel))
281 providers.list = rc_strlist_add (providers.list, service); 281 providers.list = rc_strlist_add (providers.list, service);
282 282
283 if (providers.list) 283 if (providers.list)
284 return (providers.list); 284 return (providers.list);
285 } 285 }
286 286
287 /* OK, we're not strict or there were no services in our runlevel. 287 /* OK, we're not strict or there were no services in our runlevel.
288 This is now where the logic gets a little fuzzy :) 288 This is now where the logic gets a little fuzzy :)
289 If there is >1 running service then we return NULL. 289 If there is >1 running service then we return NULL.
296 { \ 296 { \
297 rc_strlist_free (providers.list); \ 297 rc_strlist_free (providers.list); \
298 return (NULL); \ 298 return (NULL); \
299 } \ 299 } \
300 else if (providers.list) \ 300 else if (providers.list) \
301 return providers.list; \ 301 return providers.list; \
302 302
303 /* Anything in the runlevel has to come first */ 303 /* Anything in the runlevel has to come first */
304 if (get_provided1 (runlevel, &providers, dt, runlevel, false, true, false)) 304 if (get_provided1 (runlevel, &providers, dt, runlevel, false, true, false))
305 { DO } 305 { DO }
306 if (get_provided1 (runlevel, &providers, dt, runlevel, false, false, true)) 306 if (get_provided1 (runlevel, &providers, dt, runlevel, false, false, true))
314 314
315 /* Check bootlevel if we're not in it */ 315 /* Check bootlevel if we're not in it */
316 if (strcmp (runlevel, RC_LEVEL_BOOT) != 0) 316 if (strcmp (runlevel, RC_LEVEL_BOOT) != 0)
317 { 317 {
318 if (get_provided1 (runlevel, &providers, dt, RC_LEVEL_BOOT, false, true, false)) 318 if (get_provided1 (runlevel, &providers, dt, RC_LEVEL_BOOT, false, true, false))
319 { DO } 319 { DO }
320 if (get_provided1 (runlevel, &providers, dt, RC_LEVEL_BOOT, false, false, true)) 320 if (get_provided1 (runlevel, &providers, dt, RC_LEVEL_BOOT, false, false, true))
321 { DO } 321 { DO }
322 } 322 }
323 323
324 /* Check coldplugged inactive services */ 324 /* Check coldplugged inactive services */
325 if (get_provided1 (runlevel, &providers, dt, NULL, true, false, true)) 325 if (get_provided1 (runlevel, &providers, dt, NULL, true, false, true))
326 { DO } 326 { DO }
338 && (get_provided1 (runlevel, &providers, dt, RC_LEVEL_BOOT, false, false, false))) 338 && (get_provided1 (runlevel, &providers, dt, RC_LEVEL_BOOT, false, false, false)))
339 return (providers.list); 339 return (providers.list);
340 340
341 /* Still nothing? OK, list all services */ 341 /* Still nothing? OK, list all services */
342 STRLIST_FOREACH (dt->services, service, i) 342 STRLIST_FOREACH (dt->services, service, i)
343 providers.list = rc_strlist_add (providers.list, service); 343 providers.list = rc_strlist_add (providers.list, service);
344 344
345 return (providers.list); 345 return (providers.list);
346} 346}
347 347
348static void visit_service (rc_depinfo_t *deptree, char **types, 348static void visit_service (rc_depinfo_t *deptree, char **types,
349 struct lhead *sorted, struct lhead *visited, 349 struct lhead *sorted, struct lhead *visited,
350 rc_depinfo_t *depinfo, 350 rc_depinfo_t *depinfo,
351 const char *runlevel, int options) 351 const char *runlevel, int options)
352{ 352{
353 int i, j, k; 353 int i, j, k;
354 char *lp, *item; 354 char *lp, *item;
355 char *service; 355 char *service;
356 rc_depinfo_t *di; 356 rc_depinfo_t *di;
370 visited->list = rc_strlist_add (visited->list, depinfo->service); 370 visited->list = rc_strlist_add (visited->list, depinfo->service);
371 371
372 STRLIST_FOREACH (types, item, i) 372 STRLIST_FOREACH (types, item, i)
373 { 373 {
374 if ((dt = rc_get_deptype (depinfo, item))) 374 if ((dt = rc_get_deptype (depinfo, item)))
375 { 375 {
376 STRLIST_FOREACH (dt->services, service, j) 376 STRLIST_FOREACH (dt->services, service, j)
377 { 377 {
378 if (! options & RC_DEP_TRACE || strcmp (item, "iprovide") == 0) 378 if (! options & RC_DEP_TRACE || strcmp (item, "iprovide") == 0)
379 { 379 {
380 sorted->list = rc_strlist_add (sorted->list, service); 380 sorted->list = rc_strlist_add (sorted->list, service);
381 continue; 381 continue;
382 } 382 }
383 383
384 di = rc_get_depinfo (deptree, service); 384 di = rc_get_depinfo (deptree, service);
385 if ((provides = get_provided (deptree, di, runlevel, options))) 385 if ((provides = get_provided (deptree, di, runlevel, options)))
386 { 386 {
387 STRLIST_FOREACH (provides, lp, k) 387 STRLIST_FOREACH (provides, lp, k)
388 { 388 {
389 di = rc_get_depinfo (deptree, lp); 389 di = rc_get_depinfo (deptree, lp);
390 if (di && (strcmp (item, "ineed") == 0 ||
391 valid_service (runlevel, di->service)))
392 visit_service (deptree, types, sorted, visited, di,
393 runlevel, options | RC_DEP_TRACE);
394 }
395 rc_strlist_free (provides);
396 }
397 else
390 if (di && (strcmp (item, "ineed") == 0 || 398 if (di && (strcmp (item, "ineed") == 0 ||
391 valid_service (runlevel, di->service))) 399 valid_service (runlevel, service)))
392 visit_service (deptree, types, sorted, visited, di,
393 runlevel, options | RC_DEP_TRACE);
394 }
395 rc_strlist_free (provides);
396 }
397 else
398 if (di && (strcmp (item, "ineed") == 0 ||
399 valid_service (runlevel, service)))
400 visit_service (deptree, types, sorted, visited, di, 400 visit_service (deptree, types, sorted, visited, di,
401 runlevel, options | RC_DEP_TRACE); 401 runlevel, options | RC_DEP_TRACE);
402 } 402 }
403 } 403 }
404 } 404 }
405 405
406 /* Now visit the stuff we provide for */ 406 /* Now visit the stuff we provide for */
407 if (options & RC_DEP_TRACE && (dt = rc_get_deptype (depinfo, "iprovide"))) 407 if (options & RC_DEP_TRACE && (dt = rc_get_deptype (depinfo, "iprovide")))
408 { 408 {
409 STRLIST_FOREACH (dt->services, service, i) 409 STRLIST_FOREACH (dt->services, service, i)
410 { 410 {
411 if ((di = rc_get_depinfo (deptree, service))) 411 if ((di = rc_get_depinfo (deptree, service)))
412 if ((provides = get_provided (deptree, di, runlevel, options))) 412 if ((provides = get_provided (deptree, di, runlevel, options)))
413 { 413 {
414 STRLIST_FOREACH (provides, lp, j) 414 STRLIST_FOREACH (provides, lp, j)
415 if (strcmp (lp, depinfo->service) == 0) 415 if (strcmp (lp, depinfo->service) == 0)
416 { 416 {
417 visit_service (deptree, types, sorted, visited, di, 417 visit_service (deptree, types, sorted, visited, di,
418 runlevel, options | RC_DEP_TRACE); 418 runlevel, options | RC_DEP_TRACE);
419 break; 419 break;
420 } 420 }
421 rc_strlist_free (provides); 421 rc_strlist_free (provides);
422 }
422 } 423 }
423 }
424 } 424 }
425 425
426 /* We've visited everything we need, so add ourselves unless we 426 /* We've visited everything we need, so add ourselves unless we
427 are also the service calling us or we are provided by something */ 427 are also the service calling us or we are provided by something */
428 svcname = getenv("SVCNAME"); 428 svcname = getenv("SVCNAME");
430 if (! rc_get_deptype (depinfo, "providedby")) 430 if (! rc_get_deptype (depinfo, "providedby"))
431 sorted->list = rc_strlist_add (sorted->list, depinfo->service); 431 sorted->list = rc_strlist_add (sorted->list, depinfo->service);
432} 432}
433 433
434char **rc_get_depends (rc_depinfo_t *deptree, 434char **rc_get_depends (rc_depinfo_t *deptree,
435 char **types, char **services, 435 char **types, char **services,
436 const char *runlevel, int options) 436 const char *runlevel, int options)
437{ 437{
438 struct lhead sorted; 438 struct lhead sorted;
439 struct lhead visited; 439 struct lhead visited;
440 rc_depinfo_t *di; 440 rc_depinfo_t *di;
441 char *service; 441 char *service;
456 rc_strlist_free (visited.list); 456 rc_strlist_free (visited.list);
457 return (sorted.list); 457 return (sorted.list);
458} 458}
459 459
460char **rc_order_services (rc_depinfo_t *deptree, const char *runlevel, 460char **rc_order_services (rc_depinfo_t *deptree, const char *runlevel,
461 int options) 461 int options)
462{ 462{
463 char **list = NULL; 463 char **list = NULL;
464 char **types = NULL; 464 char **types = NULL;
465 char **services = NULL; 465 char **services = NULL;
466 bool reverse = false; 466 bool reverse = false;
485 /* Add coldplugged services */ 485 /* Add coldplugged services */
486 list = rc_ls_dir (list, RC_SVCDIR_COLDPLUGGED, RC_LS_INITD); 486 list = rc_ls_dir (list, RC_SVCDIR_COLDPLUGGED, RC_LS_INITD);
487 487
488 /* If we're not the boot runlevel then add that too */ 488 /* If we're not the boot runlevel then add that too */
489 if (strcmp (runlevel, RC_LEVEL_BOOT) != 0) 489 if (strcmp (runlevel, RC_LEVEL_BOOT) != 0)
490 { 490 {
491 char *path = rc_strcatpaths (RC_RUNLEVELDIR, RC_LEVEL_BOOT, 491 char *path = rc_strcatpaths (RC_RUNLEVELDIR, RC_LEVEL_BOOT,
492 (char *) NULL); 492 (char *) NULL);
493 list = rc_ls_dir (list, path, RC_LS_INITD); 493 list = rc_ls_dir (list, path, RC_LS_INITD);
494 free (path); 494 free (path);
495 } 495 }
496 } 496 }
497 497
498 /* Now we have our lists, we need to pull in any dependencies 498 /* Now we have our lists, we need to pull in any dependencies
499 and order them */ 499 and order them */
500 types = rc_strlist_add (NULL, "ineed"); 500 types = rc_strlist_add (NULL, "ineed");
501 types = rc_strlist_add (types, "iuse"); 501 types = rc_strlist_add (types, "iuse");
502 types = rc_strlist_add (types, "iafter"); 502 types = rc_strlist_add (types, "iafter");
503 services = rc_get_depends (deptree, types, list, runlevel, 503 services = rc_get_depends (deptree, types, list, runlevel,
504 RC_DEP_STRICT | RC_DEP_TRACE | options); 504 RC_DEP_STRICT | RC_DEP_TRACE | options);
505 rc_strlist_free (list); 505 rc_strlist_free (list);
506 rc_strlist_free (types); 506 rc_strlist_free (types);
507 507
508 if (reverse) 508 if (reverse)
509 rc_strlist_reverse (services); 509 rc_strlist_reverse (services);
531 char **targets = rc_ls_dir (NULL, target, 0); 531 char **targets = rc_ls_dir (NULL, target, 0);
532 char *t; 532 char *t;
533 int i; 533 int i;
534 bool newer = true; 534 bool newer = true;
535 STRLIST_FOREACH (targets, t, i) 535 STRLIST_FOREACH (targets, t, i)
536 { 536 {
537 char *path = rc_strcatpaths (target, t, (char *) NULL); 537 char *path = rc_strcatpaths (target, t, (char *) NULL);
538 newer = is_newer_than (file, path); 538 newer = is_newer_than (file, path);
539 free (path); 539 free (path);
540 if (! newer) 540 if (! newer)
541 break; 541 break;
542 } 542 }
543 rc_strlist_free (targets); 543 rc_strlist_free (targets);
544 return (newer); 544 return (newer);
545 } 545 }
546 546
547 return (true); 547 return (true);
611 611
612 /* Create base directories if needed */ 612 /* Create base directories if needed */
613 for (i = 0; depdirs[i]; i++) 613 for (i = 0; depdirs[i]; i++)
614 if (! rc_is_dir (depdirs[i])) 614 if (! rc_is_dir (depdirs[i]))
615 if (mkdir (depdirs[i], 0755) != 0) 615 if (mkdir (depdirs[i], 0755) != 0)
616 eerrorx ("mkdir `%s': %s", depdirs[i], strerror (errno)); 616 eerrorx ("mkdir `%s': %s", depdirs[i], strerror (errno));
617 617
618 if (! force) 618 if (! force)
619 if (is_newer_than (RC_DEPTREE, RC_INITDIR) && 619 if (is_newer_than (RC_DEPTREE, RC_INITDIR) &&
620 is_newer_than (RC_DEPTREE, RC_CONFDIR) && 620 is_newer_than (RC_DEPTREE, RC_CONFDIR) &&
621 is_newer_than (RC_DEPTREE, "/etc/rc.conf")) 621 is_newer_than (RC_DEPTREE, "/etc/rc.conf"))
622 return 0; 622 return 0;
623 623
624 ebegin ("Caching service dependencies"); 624 ebegin ("Caching service dependencies");
625 625
626 /* Some init scripts need RC_LIBDIR to source stuff 626 /* Some init scripts need RC_LIBDIR to source stuff
627 Ideally we should be setting our full env instead */ 627 Ideally we should be setting our full env instead */
639 /* Phase 2 */ 639 /* Phase 2 */
640 while (fgets (buffer, RC_LINEBUFFER, fp)) 640 while (fgets (buffer, RC_LINEBUFFER, fp))
641 { 641 {
642 /* Trim the newline */ 642 /* Trim the newline */
643 if (buffer[strlen (buffer) - 1] == '\n') 643 if (buffer[strlen (buffer) - 1] == '\n')
644 buffer[strlen(buffer) -1] = 0; 644 buffer[strlen(buffer) -1] = 0;
645 645
646 depends = buffer; 646 depends = buffer;
647 service = strsep (&depends, " "); 647 service = strsep (&depends, " ");
648 if (! service) 648 if (! service)
649 continue; 649 continue;
650 type = strsep (&depends, " "); 650 type = strsep (&depends, " ");
651 651
652 for (depinfo = deptree; depinfo; depinfo = depinfo->next) 652 for (depinfo = deptree; depinfo; depinfo = depinfo->next)
653 { 653 {
654 last_depinfo = depinfo; 654 last_depinfo = depinfo;
655 if (depinfo->service && strcmp (depinfo->service, service) == 0) 655 if (depinfo->service && strcmp (depinfo->service, service) == 0)
656 break; 656 break;
657 } 657 }
658 658
659 if (! depinfo) 659 if (! depinfo)
660 { 660 {
661 if (! last_depinfo->service) 661 if (! last_depinfo->service)
662 depinfo = last_depinfo; 662 depinfo = last_depinfo;
663 else 663 else
664 { 664 {
665 last_depinfo->next = rc_xmalloc (sizeof (rc_depinfo_t)); 665 last_depinfo->next = rc_xmalloc (sizeof (rc_depinfo_t));
666 depinfo = last_depinfo->next; 666 depinfo = last_depinfo->next;
667 } 667 }
668 memset (depinfo, 0, sizeof (rc_depinfo_t)); 668 memset (depinfo, 0, sizeof (rc_depinfo_t));
669 depinfo->service = strdup (service); 669 depinfo->service = strdup (service);
670 } 670 }
671 671
672 /* We may not have any depends */ 672 /* We may not have any depends */
673 if (! type || ! depends) 673 if (! type || ! depends)
674 continue; 674 continue;
675 675
676 last_deptype = NULL; 676 last_deptype = NULL;
677 for (deptype = depinfo->depends; deptype; deptype = deptype->next) 677 for (deptype = depinfo->depends; deptype; deptype = deptype->next)
678 { 678 {
679 last_deptype = deptype; 679 last_deptype = deptype;
680 if (strcmp (deptype->type, type) == 0) 680 if (strcmp (deptype->type, type) == 0)
681 break; 681 break;
682 } 682 }
683 683
684 if (! deptype) 684 if (! deptype)
685 { 685 {
686 if (! last_deptype) 686 if (! last_deptype)
687 { 687 {
688 depinfo->depends = rc_xmalloc (sizeof (rc_deptype_t)); 688 depinfo->depends = rc_xmalloc (sizeof (rc_deptype_t));
689 deptype = depinfo->depends; 689 deptype = depinfo->depends;
690 } 690 }
691 else 691 else
692 { 692 {
693 last_deptype->next = rc_xmalloc (sizeof (rc_deptype_t)); 693 last_deptype->next = rc_xmalloc (sizeof (rc_deptype_t));
694 deptype = last_deptype->next; 694 deptype = last_deptype->next;
695 } 695 }
696 memset (deptype, 0, sizeof (rc_deptype_t)); 696 memset (deptype, 0, sizeof (rc_deptype_t));
697 deptype->type = strdup (type); 697 deptype->type = strdup (type);
698 } 698 }
699 699
700 /* Now add each depend to our type. 700 /* Now add each depend to our type.
701 We do this individually so we handle multiple spaces gracefully */ 701 We do this individually so we handle multiple spaces gracefully */
702 while ((depend = strsep (&depends, " "))) 702 while ((depend = strsep (&depends, " ")))
703 { 703 {
704 if (depend[0] == 0) 704 if (depend[0] == 0)
705 continue; 705 continue;
706 706
707 /* .sh files are not init scripts */ 707 /* .sh files are not init scripts */
708 len = strlen (depend); 708 len = strlen (depend);
709 if (len > 2 && 709 if (len > 2 &&
710 depend[len - 3] == '.' && 710 depend[len - 3] == '.' &&
711 depend[len - 2] == 's' && 711 depend[len - 2] == 's' &&
712 depend[len - 1] == 'h') 712 depend[len - 1] == 'h')
713 continue; 713 continue;
714 714
715 deptype->services = rc_strlist_addsort (deptype->services, depend); 715 deptype->services = rc_strlist_addsort (deptype->services, depend);
716 } 716 }
717 717
718 } 718 }
719 pclose (fp); 719 pclose (fp);
720 720
721 /* Phase 3 - add our providors to the tree */ 721 /* Phase 3 - add our providors to the tree */
722 for (depinfo = deptree; depinfo; depinfo = depinfo->next) 722 for (depinfo = deptree; depinfo; depinfo = depinfo->next)
723 { 723 {
724 if ((deptype = rc_get_deptype (depinfo, "iprovide"))) 724 if ((deptype = rc_get_deptype (depinfo, "iprovide")))
725 STRLIST_FOREACH (deptype->services, service, i) 725 STRLIST_FOREACH (deptype->services, service, i)
726 { 726 {
727 for (di = deptree; di; di = di->next) 727 for (di = deptree; di; di = di->next)
728 { 728 {
729 last_depinfo = di; 729 last_depinfo = di;
730 if (strcmp (di->service, service) == 0) 730 if (strcmp (di->service, service) == 0)
731 break; 731 break;
732 } 732 }
733 if (! di) 733 if (! di)
734 { 734 {
735 last_depinfo->next = rc_xmalloc (sizeof (rc_depinfo_t)); 735 last_depinfo->next = rc_xmalloc (sizeof (rc_depinfo_t));
736 di = last_depinfo->next; 736 di = last_depinfo->next;
737 memset (di, 0, sizeof (rc_depinfo_t)); 737 memset (di, 0, sizeof (rc_depinfo_t));
738 di->service = strdup (service); 738 di->service = strdup (service);
739 } 739 }
740 } 740 }
741 } 741 }
742 742
743 /* Phase 4 - backreference our depends */ 743 /* Phase 4 - backreference our depends */
744 for (depinfo = deptree; depinfo; depinfo = depinfo->next) 744 for (depinfo = deptree; depinfo; depinfo = depinfo->next)
745 { 745 {
746 for (i = 0; deppairs[i].depend; i++) 746 for (i = 0; deppairs[i].depend; i++)
747 { 747 {
748 deptype = rc_get_deptype (depinfo, deppairs[i].depend); 748 deptype = rc_get_deptype (depinfo, deppairs[i].depend);
749 if (! deptype) 749 if (! deptype)
750 continue; 750 continue;
751 751
752 STRLIST_FOREACH (deptype->services, service, j) 752 STRLIST_FOREACH (deptype->services, service, j)
753 { 753 {
754 di = rc_get_depinfo (deptree, service); 754 di = rc_get_depinfo (deptree, service);
755 if (! di) 755 if (! di)
756 { 756 {
757 if (strcmp (deptype->type, "ineed") == 0) 757 if (strcmp (deptype->type, "ineed") == 0)
758 { 758 {
759 eerror ("Service `%s' needs non existant service `%s'", 759 eerror ("Service `%s' needs non existant service `%s'",
760 depinfo->service, service); 760 depinfo->service, service);
761 retval = -1; 761 retval = -1;
762 } 762 }
763 continue; 763 continue;
764 } 764 }
765 765
766 /* Add our deptype now */ 766 /* Add our deptype now */
767 last_deptype = NULL; 767 last_deptype = NULL;
768 for (dt = di->depends; dt; dt = dt->next) 768 for (dt = di->depends; dt; dt = dt->next)
769 { 769 {
770 last_deptype = dt; 770 last_deptype = dt;
771 if (strcmp (dt->type, deppairs[i].addto) == 0) 771 if (strcmp (dt->type, deppairs[i].addto) == 0)
772 break; 772 break;
773 } 773 }
774 if (! dt) 774 if (! dt)
775 { 775 {
776 if (! last_deptype) 776 if (! last_deptype)
777 { 777 {
778 di->depends = rc_xmalloc (sizeof (rc_deptype_t)); 778 di->depends = rc_xmalloc (sizeof (rc_deptype_t));
779 dt = di->depends; 779 dt = di->depends;
780 } 780 }
781 else 781 else
782 { 782 {
783 last_deptype->next = rc_xmalloc (sizeof (rc_deptype_t)); 783 last_deptype->next = rc_xmalloc (sizeof (rc_deptype_t));
784 dt = last_deptype->next; 784 dt = last_deptype->next;
785 } 785 }
786 memset (dt, 0, sizeof (rc_deptype_t)); 786 memset (dt, 0, sizeof (rc_deptype_t));
787 dt->type = strdup (deppairs[i].addto); 787 dt->type = strdup (deppairs[i].addto);
788 } 788 }
789 789
790 already_added = false; 790 already_added = false;
791 STRLIST_FOREACH (dt->services, service, k) 791 STRLIST_FOREACH (dt->services, service, k)
792 if (strcmp (service, depinfo->service) == 0) 792 if (strcmp (service, depinfo->service) == 0)
793 { 793 {
794 already_added = true; 794 already_added = true;
795 break; 795 break;
796 } 796 }
797 797
798 if (! already_added) 798 if (! already_added)
799 dt->services = rc_strlist_addsort (dt->services, 799 dt->services = rc_strlist_addsort (dt->services,
800 depinfo->service); 800 depinfo->service);
801 } 801 }
802 } 802 }
803 } 803 }
804 804
805 /* Phase 5 - save to disk 805 /* Phase 5 - save to disk
806 Now that we're purely in C, do we need to keep a shell parseable file? 806 Now that we're purely in C, do we need to keep a shell parseable file?
807 I think yes as then it stays human readable 807 I think yes as then it stays human readable
812 eerror ("fopen `%s': %s", RC_DEPTREE, strerror (errno)); 812 eerror ("fopen `%s': %s", RC_DEPTREE, strerror (errno));
813 else 813 else
814 { 814 {
815 i = 0; 815 i = 0;
816 for (depinfo = deptree; depinfo; depinfo = depinfo->next) 816 for (depinfo = deptree; depinfo; depinfo = depinfo->next)
817 { 817 {
818 fprintf (fp, "depinfo_%d_service='%s'\n", i, depinfo->service); 818 fprintf (fp, "depinfo_%d_service='%s'\n", i, depinfo->service);
819 for (deptype = depinfo->depends; deptype; deptype = deptype->next) 819 for (deptype = depinfo->depends; deptype; deptype = deptype->next)
820 { 820 {
821 k = 0; 821 k = 0;
822 STRLIST_FOREACH (deptype->services, service, j) 822 STRLIST_FOREACH (deptype->services, service, j)
823 { 823 {
824 fprintf (fp, "depinfo_%d_%s_%d='%s'\n", i, deptype->type, 824 fprintf (fp, "depinfo_%d_%s_%d='%s'\n", i, deptype->type,
825 k, service); 825 k, service);
826 k++; 826 k++;
827 } 827 }
828 } 828 }
829 i++; 829 i++;
830 } 830 }
831 fclose (fp); 831 fclose (fp);
832 } 832 }
833 833
834 rc_free_deptree (deptree); 834 rc_free_deptree (deptree);
835 835

Legend:
Removed from v.2556  
changed lines
  Added in v.2569

  ViewVC Help
Powered by ViewVC 1.1.20