/[vps]/baselayout-vserver/branches/baselayout-1_12/src/awk/gendepends.awk
Gentoo

Contents of /baselayout-vserver/branches/baselayout-1_12/src/awk/gendepends.awk

Parent Directory Parent Directory | Revision Log Revision Log


Revision 276 - (show annotations) (download)
Thu Mar 9 10:07:19 2006 UTC (12 years, 2 months ago) by phreak
File size: 13722 byte(s)
Merging r1939
1 # Copyright 1999-2004 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Header$
4
5 # bool check_service(name)
6 #
7 # Returns true if the service exists
8 #
9 function check_service(name, x)
10 {
11 for (x = 1; x <= RC_NUMBER; x++) {
12 if (DEPTREE[x,NAME] == name)
13 return 1
14 }
15
16 return 0
17 }
18
19 # int get_service_index(name)
20 #
21 # Return the index position in DEPTREE
22 #
23 function get_service_index(name, x)
24 {
25 for (x = 1; x <= RC_NUMBER; x++) {
26 if (DEPTREE[x,NAME] == name)
27 return x
28 }
29
30 return 0
31 }
32
33 # bool check_depend(service1, type, service2)
34 #
35 # Returns true if 'service1' need/use/is_before/is_after 'service2'
36 #
37 function check_depend(service1, type, service2, tmpsplit, x)
38 {
39 if (check_service(service1)) {
40 x = get_service_index(service1)
41
42 if ((x,type) in DEPTREE) {
43 split(DEPTREE[x,type], tmpsplit)
44
45 for (x in tmpsplit) {
46 if (tmpsplit[x] == service2)
47 return 1
48 }
49 }
50 }
51
52 return 0
53 }
54
55 # bool check_resolved_depend(service1, type, service2)
56 #
57 # Returns true if 'service1' need/use/is_before/is_after 'service2'
58 # It should only be trusted if we do the BEFORE/AFTER loop
59 #
60 function check_resolved_depend(service1, type, service2, tmpsplit, x)
61 {
62 if (check_service(service1)) {
63 x = get_service_index(service1)
64
65 if ((x,type) in RESOLVED_DEPTREE) {
66 split(RESOLVED_DEPTREE[x,type], tmpsplit)
67
68 for (x in tmpsplit) {
69 if (tmpsplit[x] == service2)
70 return 1
71 }
72 }
73 }
74
75 return 0
76 }
77
78 # string get_resolved_depends(service, type)
79 #
80 # Return the services that depend of type on service
81 # It should only be trusted if we do the BEFORE/AFTER loop
82 #
83 function get_resolved_depends(service, type, x)
84 {
85 if (check_service(service)) {
86 x = get_service_index(service)
87
88 if ((x,type) in RESOLVED_DEPTREE)
89 return RESOLVED_DEPTREE[x,type]
90 }
91
92 return ""
93 }
94
95 # bool check_recursive_depend(service1, service2, bool checkuse)
96 #
97 # Return true if service1 USE/NEED a service that NEEDS/USES
98 # service2
99 # It should only be trusted if we do the BEFORE/AFTER loop
100 #
101 function check_recursive_depend(service1, service2, checkuse, x, deps, deplist)
102 {
103 deps = get_resolved_depends(service2, NEEDME)
104 if (deps != "") {
105 split(deps, deplist)
106 for (x in deplist)
107 if (check_resolved_depend(service1, NEED, deplist[x]))
108 return 1
109 if (checkuse && check_resolved_depend(service1, USE, deplist[x]))
110 return 1
111 }
112
113 if (!checkuse)
114 return 0
115
116 deps = get_resolved_depends(service2, USEME)
117 if (deps != "") {
118 split(deps, deplist)
119 for (x in deplist)
120 if (check_resolved_depend(service1, NEED, deplist[x]) ||
121 check_resolved_depend(service1, USE, deplist[x])) {
122 return 1
123 }
124 }
125
126 return 0
127 }
128
129 # bool add_deptree_item(rcnumber, type, item)
130 #
131 # Add an item(s) 'item' to the DEPTREE array at index [rcnumber,type]
132 #
133 function add_deptree_item(rcnumber, type, item)
134 {
135 if (DEPTREE[rcnumber,type] != "")
136 DEPTREE[rcnumber,type] = DEPTREE[rcnumber,type] " " item
137 else
138 DEPTREE[rcnumber,type] = item
139
140 return 1
141 }
142
143 # bool add_provide(service, provide)
144 #
145 # Add a name of a virtual service ('provide') that 'service' Provides
146 #
147 function add_provide(service, provide)
148 {
149 # We cannot have a service Provide a virtual service with the same name as
150 # an existing service ...
151 if (check_service(provide)) {
152 eerror(" Cannot add provide '" provide "', as a service with the same name exists!")
153 return 0
154 }
155
156 if (check_provide(provide)) {
157 # We cannot have more than one service Providing a virtual ...
158 ewarn(" Service '" get_provide(provide) "' already provided by '" provide "'!;")
159 ewarn(" Not adding service '" service "'...")
160 # Do not fail here as we do have a service that resolves the virtual
161 } else {
162 # Sanity check
163 if (check_service(service)) {
164 PROVIDE_LIST[provide] = service
165 } else {
166 eerror(" Cannot add provide '" provide "', as service '" service "' does not exist!")
167 return 0
168 }
169 }
170
171 return 1
172 }
173
174 # string get_provide(provide)
175 #
176 # Return the name of the service that Provides 'provide'
177 #
178 function get_provide(provide)
179 {
180 if (provide in PROVIDE_LIST)
181 if (check_service(PROVIDE_LIST[provide]))
182 return PROVIDE_LIST[provide]
183
184 return ""
185 }
186
187 # bool check_provide(provide)
188 #
189 # Return true if any service Provides the virtual service with name 'provide'
190 #
191 function check_provide(provide)
192 {
193 if (provide in PROVIDE_LIST)
194 return 1
195
196 return 0
197 }
198
199 # bool add_db_entry(service, type, item)
200 #
201 # Add a entry to RESOLVED_DEPTREE
202 #
203 function add_db_entry(service, type, item, x, sindex, tmpsplit)
204 {
205 if (!check_service(service)) {
206 eerror(" Service '" service "' do not exist!")
207 return 0
208 }
209
210 sindex = get_service_index(service)
211
212 if ((sindex,type) in RESOLVED_DEPTREE) {
213 split(RESOLVED_DEPTREE[sindex,type], tmpsplit)
214
215 for (x in tmpsplit) {
216 if (tmpsplit[x] == item)
217 return 1
218 }
219
220 RESOLVED_DEPTREE[sindex,type] = RESOLVED_DEPTREE[sindex,type] " " item
221 } else {
222 RESOLVED_DEPTREE[sindex,type] = item
223 }
224
225 return 1
226 }
227
228 # void resolve_depend(type, service, deplist)
229 #
230 # Verify a depend entry(s) 'deplist' for service 'service' of type 'type',
231 # and then add it to the DB.
232 #
233 function resolve_depend(type, service, deplist, x, deparray)
234 {
235 if ((type == "") || (service == "") || (deplist == ""))
236 return
237
238 # If there are no existing service 'service', resolve possible
239 # provided services
240 if (!check_service(service)) {
241 if (check_provide(service))
242 service = get_provide(service)
243 else
244 return
245 }
246
247 split(deplist, deparray)
248
249 for (x in deparray) {
250
251 # If there are no existing service 'deparray[x]', resolve possible
252 # provided services
253 if (!check_service(deparray[x])) {
254 if (check_provide(deparray[x]))
255 deparray[x] = get_provide(deparray[x])
256 }
257
258 # Handle 'need', as it is the only dependency type that
259 # should handle invalid database entries currently.
260 if (!check_service(deparray[x])) {
261
262 if (((type == NEED) || (type == NEEDME)) && (deparray[x] != "net")) {
263
264 ewarn(" Can't find service '" deparray[x] "' needed by '" service "'; continuing...")
265
266 # service is broken due to missing 'need' dependencies
267 add_db_entry(service, BROKEN, deparray[x])
268
269 continue
270 }
271 else if (deparray[x] != "net")
272 continue
273 }
274
275 # Ugly bug ... if a service depends on itself, it creates
276 # a 'mini fork bomb' effect, and breaks things...
277 if (deparray[x] == service) {
278
279 # Dont work too well with the '*' use and need
280 if ((type != BEFORE) && (type != AFTER))
281 ewarn(" Service '" deparray[x] "' can't depend on itself; continuing...")
282
283 continue
284 }
285
286 # Currently only these depend/order types are supported
287 if ((type == NEED) || (type == USE) || (type == BEFORE) || (type == AFTER)) {
288
289 if (type == BEFORE) {
290 # NEED and USE override BEFORE (service BEFORE deparray[x])
291 if (check_resolved_depend(service, NEED, deparray[x]) ||
292 check_resolved_depend(service, USE, deparray[x]))
293 continue
294
295 if (check_recursive_depend(service, deparray[x], 1)) {
296 ewarn(" Service '" service "' should be BEFORE service '" deparray[x] "', but one of")
297 ewarn(" the services '" service "' depends on, depends on '" deparray[x] "'!")
298 continue
299 }
300 }
301
302 if (type == AFTER) {
303 # NEED and USE override AFTER (service AFTER deparray[x])
304 if (check_resolved_depend(deparray[x], NEED, service) ||
305 check_resolved_depend(deparray[x], USE, service))
306 continue
307
308 if (check_recursive_depend(deparray[x], service, 1)) {
309 ewarn(" Service '" service "' should be AFTER service '" deparray[x] "', but one of")
310 ewarn(" the services '" deparray[x] "' depends on, depends on '" service "'!")
311 continue
312 }
313 }
314
315 # NEED override USE (service USE deparray[x])
316 if (type == USE && (check_resolved_depend(deparray[x], NEED, service) ||
317 check_recursive_depend(deparray[x], service, 0))) {
318 ewarn(" Service '" deparray[x] "' NEED service '" service "', but service '" service "' wants")
319 ewarn(" to USE service '" deparray[x] "'!")
320 continue
321 }
322
323 # We do not want to add circular depends ...
324 if (check_depend(deparray[x], type, service) ||
325 check_resolved_depend(deparray[x], type, service)) {
326
327 if ((service,deparray[x],type) in CIRCULAR_DEPEND)
328 continue
329
330 if ((deparray[x],service,type) in CIRCULAR_DEPEND)
331 continue
332
333 ewarn(" Services '" service "' and '" deparray[x] "' have circular")
334 ewarn(" dependency of type '" TYPE_NAMES[type] "'; continuing...")
335
336 CIRCULAR_DEPEND[service,deparray[x],type] = "yes"
337
338 continue
339 }
340
341 add_db_entry(service, type, deparray[x])
342
343 # Reverse mapping
344 if (type == NEED)
345 add_db_entry(deparray[x], NEEDME, service)
346
347 # Reverse mapping
348 if (type == USE)
349 add_db_entry(deparray[x], USEME, service)
350
351 # Reverse mapping
352 if (type == BEFORE)
353 add_db_entry(deparray[x], AFTER, service)
354
355 # Reverse mapping
356 if (type == AFTER)
357 add_db_entry(deparray[x], BEFORE, service)
358 }
359 }
360 }
361
362 BEGIN {
363 NAME = 1
364 RC_NUMBER = 0
365
366 # Types ...
367 NEED = 2
368 NEEDME = 3
369 USE = 4
370 USEME = 5
371 BEFORE = 6
372 AFTER = 7
373 BROKEN = 8
374 MTIME = 9
375 PROVIDE = 10 # Not part of Types as when finally printed ...
376 TYPES_MIN = 2
377 TYPES_MAX = 9
378
379 TYPE_NAMES[NEED] = "ineed"
380 TYPE_NAMES[NEEDME] = "needsme"
381 TYPE_NAMES[USE] = "iuse"
382 TYPE_NAMES[USEME] = "usesme"
383 TYPE_NAMES[BEFORE] = "ibefore"
384 TYPE_NAMES[AFTER] = "iafter"
385 TYPE_NAMES[BROKEN] = "broken"
386 TYPE_NAMES[PROVIDE] = "provide"
387 TYPE_NAMES[MTIME] = "mtime"
388
389 # Get our environment variables
390 SVCDIR = ENVIRON["SVCDIR"]
391 if (SVCDIR == "") {
392 eerror("Could not get SVCDIR!")
393 exit 1
394 }
395
396 # There we do not really use yet
397 DEPTYPES = ENVIRON["DEPTYPES"]
398 ORDTYPES = ENVIRON["ORDTYPES"]
399
400 #CACHEDTREE = SVCDIR "/deptree"
401 ORIGCACHEDTREE = SVCDIR "/deptree"
402
403 # Since this could be called more than once simultaneously, use a
404 # temporary cache and rename when finished. See bug 48303
405 ("/bin/mktemp "SVCDIR"/treecache.XXXXXXX") | getline CACHEDTREE
406 if (CACHEDTREE == "") {
407 eerror("Failed to create temporary cache!")
408 exit 1
409 }
410
411 # We remove it below now only before moving the temp one over.
412 #assert(dosystem("rm -f " CACHEDTREE ), "system(rm -f " CACHEDTREE ")")
413 }
414
415 {
416 #
417 # Build our DEPTREE array
418 #
419
420 if ($1 == "RCSCRIPT") {
421 RC_NUMBER++
422
423 DEPTREE[RC_NUMBER,NAME] = $2
424 }
425
426 if ($1 == "NEED") {
427 sub(/NEED[[:space:]]*/, "")
428
429 if ($0 != "")
430 add_deptree_item(RC_NUMBER, NEED, $0)
431 }
432
433 if ($1 == "USE") {
434 sub(/USE[[:space:]]*/, "")
435
436 if ($0 != "")
437 add_deptree_item(RC_NUMBER, USE, $0)
438 }
439
440 if ($1 == "BEFORE") {
441 sub(/BEFORE[[:space:]]*/, "")
442
443 if ($0 != "")
444 add_deptree_item(RC_NUMBER, BEFORE, $0)
445 }
446
447 if ($1 == "AFTER") {
448 sub(/AFTER[[:space:]]*/, "")
449
450 if ($0 != "")
451 add_deptree_item(RC_NUMBER, AFTER, $0)
452 }
453
454 if ($1 == "PROVIDE") {
455 sub(/PROVIDE[[:space:]]*/, "")
456
457 if ($0 != "")
458 add_deptree_item(RC_NUMBER, PROVIDE, $0)
459 }
460
461 if ($1 == "MTIME") {
462 sub(/MTIME[[:space:]]*/, "")
463
464 if ($0 != "") {
465 # We add this directly to RESOLVED_DEPTREE
466 add_db_entry(DEPTREE[RC_NUMBER,NAME], MTIME, $0)
467 }
468 }
469 }
470
471 END {
472 # Add the 'net' service if it do not exist ...
473 if (!check_service("net")) {
474 RC_NUMBER++
475 DEPTREE[RC_NUMBER,NAME] = "net"
476 }
477
478 # Calculate all the provides ...
479 for (x = 1;x <= RC_NUMBER;x++) {
480 if ((x,PROVIDE) in DEPTREE)
481 add_provide(DEPTREE[x,NAME], DEPTREE[x,PROVIDE])
482 }
483
484 # Now do NEED
485 for (x = 1;x <= RC_NUMBER;x++) {
486 if ((x,NEED) in DEPTREE)
487 resolve_depend(NEED, DEPTREE[x,NAME], DEPTREE[x,NEED])
488 }
489
490 # Now do USE
491 for (x = 1;x <= RC_NUMBER;x++) {
492 if ((x,USE) in DEPTREE)
493 resolve_depend(USE, DEPTREE[x,NAME], DEPTREE[x,USE])
494 }
495
496 # Now do BEFORE and AFTER
497 for (x = 1;x <= RC_NUMBER;x++) {
498
499 if ((x,BEFORE) in DEPTREE)
500 resolve_depend(BEFORE, DEPTREE[x,NAME], DEPTREE[x,BEFORE])
501
502 if ((x,AFTER) in DEPTREE)
503 resolve_depend(AFTER, DEPTREE[x,NAME], DEPTREE[x,AFTER])
504 }
505
506 for (x = TYPES_MIN; x <= TYPES_MAX; x++)
507 print "declare -r rc_type_" TYPE_NAMES[x] "=" x >> (CACHEDTREE)
508 print "declare -r rc_index_scale=" (TYPES_MAX + 1) >> (CACHEDTREE)
509 print "" >> (CACHEDTREE)
510 print "declare -a RC_DEPEND_TREE" >> (CACHEDTREE)
511 print "" >> (CACHEDTREE)
512 print "RC_DEPEND_TREE[0]=" RC_NUMBER >> (CACHEDTREE)
513 print "" >> (CACHEDTREE)
514
515 # Generate the resolved CACHEDTREE
516 #
517 # NOTE: We used to use depinfo_<scriptname>() function to resolve our
518 # rc_<type> variables, but that do not scale when the names of
519 # the scripts include invalid bash variable characters (+,.,etc).
520 #
521 for (x = 1;x <= RC_NUMBER;x++) {
522
523 print "RC_DEPEND_TREE[" (x * (TYPES_MAX + 1)) "]=\"" DEPTREE[x,NAME] "\"" >> (CACHEDTREE)
524
525 for (y = TYPES_MIN; y <= TYPES_MAX; y++) {
526
527 tmpname = "RC_DEPEND_TREE[" (x * (TYPES_MAX + 1)) "+" y "]"
528
529 if ((x,y) in RESOLVED_DEPTREE) {
530
531 split(RESOLVED_DEPTREE[x,y], tmparray1)
532 count = asort(tmparray1, tmparray2)
533 tmpstr = tmparray2[1]
534
535 for (i = 2;i <= count;i++)
536 tmpstr = tmpstr " " tmparray2[i]
537
538 print tmpname "=\"" tmpstr "\"" >> (CACHEDTREE)
539 } else
540 print tmpname "=" >> (CACHEDTREE)
541 }
542
543 print "" >> (CACHEDTREE)
544 }
545 # Ensure that no-one changes our tree
546 print "declare -r RC_DEPEND_TREE" >> (CACHEDTREE)
547
548 # Do not export these, as we want them local
549 print "declare -r RC_GOT_DEPTREE_INFO=\"yes\"" >> (CACHEDTREE)
550 print "" >> (CACHEDTREE)
551
552 if (check_provide("logger"))
553 print "declare -r LOGGER_SERVICE=\"" get_provide("logger") "\"" >> (CACHEDTREE)
554 else
555 print "declare -r LOGGER_SERVICE=" >> (CACHEDTREE)
556
557 close(CACHEDTREE)
558
559 assert(dosystem("rm -f "ORIGCACHEDTREE), "system(rm -f "ORIGCACHEDTREE")")
560 assert(dosystem("mv "CACHEDTREE" "ORIGCACHEDTREE), "system(mv "CACHEDTREE" "ORIGCACHEDTREE")")
561 }
562
563
564 # vim:ts=4

  ViewVC Help
Powered by ViewVC 1.1.20