/[baselayout]/trunk/src/awk/gendepends.awk
Gentoo

Diff of /trunk/src/awk/gendepends.awk

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

Revision 356 Revision 357
1# Copyright 1999-2003 Gentoo Technologies, Inc. 1# Copyright 1999-2003 Gentoo Technologies, Inc.
2# Distributed under the terms of the GNU General Public License v2 2# Distributed under the terms of the GNU General Public License v2
3# Author: Martin Schlemmer <azarah@gentoo.org> 3# Author: Martin Schlemmer <azarah@gentoo.org>
4# $Header$ 4# $Header$
5 5
6BEGIN { 6# bool check_service(name)
7 7#
8 extension("/lib/rcscripts/filefuncs.so", "dlload") 8# Returns true if the service exists
9 9#
10 NAME = 1
11 NEED = 2
12 USE = 3
13 BEFORE = 4
14 AFTER = 5
15 PROVIDE = 6
16
17 TYPENAMES[NEED] = "need"
18 TYPENAMES[USE] = "use"
19 TYPENAMES[BEFORE] = "before"
20 TYPENAMES[AFTER] = "after"
21 TYPENAMES[PROVIDE] = "provide"
22
23 if (!isdir(SVCDIR))
24 if (!mktree(SVCDIR, 0755)) {
25
26 eerror("Could not create needed directories!")
27 exit 1
28 }
29
30 svcdirs = "softscripts snapshot options broken started provide "
31 svcdirs = svcdirs " " DEPTYPES " " ORDTYPES
32
33 split (svcdirs, svcdirnodes)
34
35 for (x in svcdirnodes) {
36
37 if (!isdir(SVCDIR "/" svcdirnodes[x])) {
38
39 if (!mktree(SVCDIR "/" svcdirnodes[x], 0755)) {
40
41 eerror("Could not create needed directories!")
42 exit 1
43 }
44 }
45 }
46
47 # Cleanup and fix a problem with 'for x in foo/*' if foo/ is empty
48 system("rm -rf " SVCDIR "/need/*")
49 system("rm -rf " SVCDIR "/use/*")
50 system("rm -rf " SVCDIR "/before/*")
51 system("rm -rf " SVCDIR "/after/*")
52 system("rm -rf " SVCDIR "/broken/*")
53 system("rm -rf " SVCDIR "/provide/*")
54}
55
56{
57 if ($1 == "RCSCRIPT") {
58 RCNUMBER++
59
60 DEPTREE[RCNUMBER,NAME] = $2
61 }
62
63 if ($1 == "NEED") {
64 sub(/NEED[[:space:]]*/, "")
65
66 if ($0 != "") {
67
68 if (DEPTREE[RCNUMBER,NEED] != "")
69 DEPTREE[RCNUMBER,NEED] = DEPTREE[RCNUMBER,NEED] " " $0
70 else
71 DEPTREE[RCNUMBER,NEED] = $0
72 }
73 }
74
75 if ($1 == "USE") {
76 sub(/USE[[:space:]]*/, "")
77
78 if ($0 != "") {
79
80 if (DEPTREE[RCNUMBER,USE] != "")
81 DEPTREE[RCNUMBER,USE] = DEPTREE[RCNUMBER,USE] " " $0
82 else
83 DEPTREE[RCNUMBER,USE] = $0
84 }
85 }
86
87 if ($1 == "BEFORE") {
88 sub(/BEFORE[[:space:]]*/, "")
89
90 if ($0 != "") {
91
92 if (DEPTREE[RCNUMBER,BEFORE] != "")
93 DEPTREE[RCNUMBER,BEFORE] = DEPTREE[RCNUMBER,BEFORE] " " $0
94 else
95 DEPTREE[RCNUMBER,BEFORE] = $0
96 }
97 }
98
99 if ($1 == "AFTER") {
100 sub(/AFTER[[:space:]]*/, "")
101
102 if ($0 != "") {
103
104 if (DEPTREE[RCNUMBER,AFTER] != "")
105 DEPTREE[RCNUMBER,AFTER] = DEPTREE[RCNUMBER,AFTER] " " $0
106 else
107 DEPTREE[RCNUMBER,AFTER] = $0
108 }
109 }
110
111 if ($1 == "PROVIDE") {
112 sub(/PROVIDE[[:space:]]*/, "")
113
114 if ($0 != "") {
115
116 if (DEPTREE[RCNUMBER,PROVIDE] != $0)
117 DEPTREE[RCNUMBER,PROVIDE] = DEPTREE[RCNUMBER,PROVIDE] " " $0
118 else
119 DEPTREE[RCNUMBER,PROVIDE] = $0
120 }
121 }
122}
123
124function check_service(name, x) 10function check_service(name, x)
125{ 11{
126 for (x = 1;x <= RCNUMBER;x++) { 12 for (x = 1; x <= RCNUMBER; x++) {
127 if (DEPTREE[x,NAME] == name) 13 if (DEPTREE[x,NAME] == name)
128 return 1 14 return 1
15 else
16 continue
129 } 17 }
130 18
131 return 0 19 return 0
132} 20}
133 21
22# int get_service_position(name)
23#
24# Return the index position in DEPTREE
25#
26function get_service_position(name, x)
27{
28 for (x = 1; x <= RCNUMBER; x++) {
29 if (DEPTREE[x,NAME] == name)
30 return x
31 else
32 continue
33 }
34
35 return 0
36}
37
38# bool check_depend(service1, type, service2)
39#
40# Returns true if 'service1' need/use/is_before/is_after 'service2'
41#
42function check_depend(service1, type, service2, tmpsplit, x)
43{
44 if (get_service_position(service1)) {
45 x = get_service_position(service1)
46
47 if ((x,type) in DEPTREE) {
48 split(DEPTREE[x,type], tmpsplit, " ")
49
50 for (x in tmpsplit) {
51 if (tmpsplit[x] == service2)
52 return 1
53 }
54 }
55 }
56
57 return 0
58}
59
60# bool add_deptree_item(rcnumber, type, item)
61#
62# Add an item(s) 'item' to the DEPTREE array at index [rcnumber,type]
63#
64function add_deptree_item(rcnumber, type, item)
65{
66 if (DEPTREE[rcnumber,type] != "")
67 DEPTREE[rcnumber,type] = DEPTREE[rcnumber,type] " " item
68 else
69 DEPTREE[rcnumber,type] = item
70
71 return 1
72}
73
74# bool add_provide(service, provide)
75#
76# Add a name of a virtual service ('provide') that 'service' Provides
77#
78function add_provide(service, provide)
79{
80 # We cannot have a service Provide a virtual service with the same name as
81 # an existing service ...
82 if (check_service(provide)) {
83 eerror(" Cannot add provide '" provide "', as a service with the same name exists!")
84 return 0
85 }
86
87 if (check_provide(provide)) {
88 # We cannot have more than one service Providing a virtual ...
89 ewarn(" Service '" get_provide(provide) "' already provide '" provide "'!;")
90 ewarn(" Not adding service '" service "'...")
91 } else {
92 # Sanity check
93 if (check_service(service)) {
94 PROVIDE_LIST[provide] = service
95 } else {
96 eerror(" Cannot add provide '" provide "', as service '" service "' do not exist!")
97 return 0
98 }
99 }
100
101 return 1
102}
103
104# string get_provide(provide)
105#
106# Return the name of the service that Provides 'provide'
107#
108function get_provide(provide)
109{
110 if (provide in PROVIDE_LIST)
111 if (check_service(PROVIDE_LIST[provide]))
112 return PROVIDE_LIST[provide]
113
114 return ""
115}
116
117# bool check_provide(provide)
118#
119# Return true if any service Provides the virtual service with name 'provide'
120#
121function check_provide(provide)
122{
123 if (provide in PROVIDE_LIST)
124 return 1
125
126 return 0
127}
128
129# void depend_dbadd(type, service, deplist)
130#
131# Add an DB entry(s) 'deplist' for service 'service' of type 'type'
132#
134function depend_dbadd(type, service, deplist, x, deparray) 133function depend_dbadd(type, service, deplist, x, deparray)
135{ 134{
136 deparray[1] = 1
137
138 if ((type == "") || (service == "") || (deplist == "")) 135 if ((type == "") || (service == "") || (deplist == ""))
139 return 136 return
140 137
138 # If there are no existing service 'service', resolve possible
139 # provided services
141 if (!check_service(service)) 140 if (!check_service(service)) {
141 if (check_provide(service))
142 service = get_provide(service)
143 else
142 return 144 return
143 145 }
146
144 split(deplist, deparray, " ") 147 split(deplist, deparray, " ")
145 148
146 for (x in deparray) { 149 for (x in deparray) {
147 150
151 # If there are no existing service 'deparray[x]', resolve possible
152 # provided services
153 if (!check_service(deparray[x])) {
154 if (check_provide(deparray[x]))
155 deparray[x] = get_provide(deparray[x])
156 }
157
148 # Handle 'need', as it is the only dependency type that 158 # Handle 'need', as it is the only dependency type that
149 # should handle invalid database entries currently. The only 159 # should handle invalid database entries currently.
150 # other type of interest is 'pretend' which *should* add
151 # invalid database entries (no virtual depend should ever
152 # actually have a matching rc-script).
153 if (!check_service(deparray[x])) { 160 if (!check_service(deparray[x])) {
154 161
155 if ((type == NEED) && (deparray[x] != "net") && 162 if ((type == NEED) && (deparray[x] != "net")) {
156 (!isdir(SVCDIR "/provide/" deparray[x]))) {
157 163
158 ewarn("NEED: can't find service \"" deparray[x] "\" needed by \"" service "\";") 164 ewarn(" Can't find service '" deparray[x] "' needed by '" service "'; continuing...")
159 ewarn(" continuing...")
160 165
161 # service is broken due to missing 'need' dependencies 166 # service is broken due to missing 'need' dependencies
162 if (!isdir(SVCDIR "/broken/" service)) 167 if (!isdir(SVCDIR "/broken/" service))
163 assert(mktree(SVCDIR "/broken/" service, 0755), 168 assert(mktree(SVCDIR "/broken/" service, 0755),
164 "mktree(" SVCDIR "/broken/" service ", 0755)") 169 "mktree(" SVCDIR "/broken/" service ", 0755)")
166 assert(dosystem("touch " SVCDIR "/broken/" service "/" deparray[x]), 171 assert(dosystem("touch " SVCDIR "/broken/" service "/" deparray[x]),
167 "system(touch " SVCDIR "/broken/" service "/" deparray[x] ")") 172 "system(touch " SVCDIR "/broken/" service "/" deparray[x] ")")
168 173
169 continue 174 continue
170 } 175 }
171 else if ((type != PROVIDE) && (deparray[x] != "net") && 176 else if (deparray[x] != "net")
172 (!isdir(SVCDIR "/provide/" deparray[x])))
173 continue 177 continue
174 } 178 }
175 179
176 # Ugly bug ... if a service depends on itself, it creates 180 # Ugly bug ... if a service depends on itself, it creates
177 # a 'mini fork bomb' effect, and breaks things... 181 # a 'mini fork bomb' effect, and breaks things...
178 if (deparray[x] == service) { 182 if (deparray[x] == service) {
179 183
180 # Dont work too well with the '*' use and need 184 # Dont work too well with the '*' use and need
181 if ((type != BEFORE) && (type != AFTER)) { 185 if ((type != BEFORE) && (type != AFTER))
182 ewarn("DEPEND: service \"" deparray[x] "\" can't depend on itself;") 186 ewarn(" Service '" deparray[x] "' can't depend on itself; continuing...")
183 ewarn(" continuing...")
184 }
185 187
186 continue 188 continue
187 } 189 }
188 190
189 # NEED and USE override BEFORE and AFTER 191 # Currently only these depend/order types are supported
190 if ((((type == BEFORE) && (!islink(SVCDIR "/need/" deparray[x] "/" service))) &&
191 ((type == BEFORE) && (!islink(SVCDIR "/use/" deparray[x] "/" service)))) ||
192 (((type == AFTER) && (!islink(SVCDIR "/need/" service "/" deparray[x]))) &&
193 ((type == AFTER) && (!islink(SVCDIR "/use/" service "/" deparray[x])))) ||
194 ((type == NEED) || (type == USE) || (type == PROVIDE))) { 192 if ((type == NEED) || (type == USE) || (type == BEFORE) || (type == AFTER)) {
193
194 if (type == BEFORE) {
195 # NEED and USE override BEFORE (service BEFORE deparray[x])
196 if (check_depend(service, NEED, deparray[x]) ||
197 check_depend(service, USE, deparray[x]))
198 continue
195 199
200 # Do not all circular ordering
201 if (check_depend(service, AFTER, deparray[x]))
202 continue
203 }
204
205 if (type == AFTER) {
206 # NEED and USE override AFTER (service AFTER deparray[x])
207 if (check_depend(deparray[x], NEED, service) ||
208 check_depend(deparray[x], USE, service))
209 continue
210
211 # Do not all circular ordering
212 if (check_depend(service, BEFORE, deparray[x]))
213 continue
214 }
215
216 # NEED override USE (service USE deparray[x])
217 if ((type == USE) && (check_depend(deparray[x], NEED, service))) {
218 ewarn(" Service '" deparray[x] "' NEED service '" service "', but service '" service "' wants")
219 ewarn(" to USE service '" deparray[x] "'!")
220 continue
221 }
222
223 # Ok, add our db entry ...
196 if (!isdir(SVCDIR "/" TYPENAMES[type] "/" deparray[x])) 224 if (!isdir(SVCDIR "/" TYPENAMES[type] "/" deparray[x]))
197 assert(mktree(SVCDIR "/" TYPENAMES[type] "/" deparray[x], 0755), 225 assert(mktree(SVCDIR "/" TYPENAMES[type] "/" deparray[x], 0755),
198 "mktree(" SVCDIR "/" TYPENAMES[type] "/" deparray[x] ", 0755)") 226 "mktree(" SVCDIR "/" TYPENAMES[type] "/" deparray[x] ", 0755)")
199 if (!islink(SVCDIR "/" TYPENAMES[type] "/" deparray[x] "/" service)) 227 if (!islink(SVCDIR "/" TYPENAMES[type] "/" deparray[x] "/" service))
200 assert(dosymlink("/etc/init.d/" service, SVCDIR "/" TYPENAMES[type] "/" deparray[x] "/" service), 228 assert(dosymlink("/etc/init.d/" service, SVCDIR "/" TYPENAMES[type] "/" deparray[x] "/" service),
201 "dosymlink(/etc/init.d/" service ", " SVCDIR "/" TYPENAMES[type] "/" deparray[x] "/" service")") 229 "dosymlink(/etc/init.d/" service ", " SVCDIR "/" TYPENAMES[type] "/" deparray[x] "/" service")")
202 } 230 }
203 } 231 }
204} 232}
205 233
234BEGIN {
235
236 extension("/lib/rcscripts/filefuncs.so", "dlload")
237
238 NAME = 1
239 NEED = 2
240 USE = 3
241 BEFORE = 4
242 AFTER = 5
243 PROVIDE = 6
244 RCNUMBER = 0
245
246 TYPENAMES[NEED] = "need"
247 TYPENAMES[USE] = "use"
248 TYPENAMES[BEFORE] = "before"
249 TYPENAMES[AFTER] = "after"
250 TYPENAMES[PROVIDE] = "provide"
251
252 if (!isdir(SVCDIR))
253 if (!mktree(SVCDIR, 0755)) {
254
255 eerror(" Could not create needed directories!")
256 exit 1
257 }
258
259 svcdirs = "softscripts snapshot options broken started"
260 svcdirs = svcdirs " " DEPTYPES " " ORDTYPES
261
262 split (svcdirs, svcdirnodes)
263
264 for (x in svcdirnodes) {
265
266 if (!isdir(SVCDIR "/" svcdirnodes[x])) {
267
268 if (!mktree(SVCDIR "/" svcdirnodes[x], 0755)) {
269
270 eerror(" Could not create needed directories!")
271 exit 1
272 }
273 }
274 }
275
276 # Cleanup and fix a problem with 'for x in foo/*' if foo/ is empty
277 system("rm -rf " SVCDIR "/{need,use,before,after,broken}/*")
278}
279
280{
281 #
282 # Build our DEPTREE array
283 #
284
285 if ($1 == "RCSCRIPT") {
286 RCNUMBER++
287
288 DEPTREE[RCNUMBER,NAME] = $2
289 }
290
291 if ($1 == "NEED") {
292 sub(/NEED[[:space:]]*/, "")
293
294 if ($0 != "")
295 add_deptree_item(RCNUMBER, NEED, $0)
296 }
297
298 if ($1 == "USE") {
299 sub(/USE[[:space:]]*/, "")
300
301 if ($0 != "")
302 add_deptree_item(RCNUMBER, USE, $0)
303 }
304
305 if ($1 == "BEFORE") {
306 sub(/BEFORE[[:space:]]*/, "")
307
308 if ($0 != "")
309 add_deptree_item(RCNUMBER, BEFORE, $0)
310 }
311
312 if ($1 == "AFTER") {
313 sub(/AFTER[[:space:]]*/, "")
314
315 if ($0 != "")
316 add_deptree_item(RCNUMBER, AFTER, $0)
317 }
318
319 if ($1 == "PROVIDE") {
320 sub(/PROVIDE[[:space:]]*/, "")
321
322 if ($0 != "")
323 add_deptree_item(RCNUMBER, PROVIDE, $0)
324 }
325}
326
206END { 327END {
207 # Calculate all the provides ... 328 # Calculate all the provides ...
208 for (x = 1;x <= RCNUMBER;x++) { 329 for (x = 1;x <= RCNUMBER;x++) {
209 330
210 if ((x,PROVIDE) in DEPTREE) 331 if ((x,PROVIDE) in DEPTREE)
211 depend_dbadd(PROVIDE, DEPTREE[x,NAME], DEPTREE[x,PROVIDE]) 332 add_provide(DEPTREE[x,NAME], DEPTREE[x,PROVIDE])
212 } 333 }
213 334
214 # Now do NEED and USE 335 # Now do NEED and USE
215 for (x = 1; x <= RCNUMBER;x++) { 336 for (x = 1; x <= RCNUMBER;x++) {
216 337
245 # Reverse mapping 366 # Reverse mapping
246 for (y in tmpsplit) 367 for (y in tmpsplit)
247 depend_dbadd(BEFORE, tmpsplit[y], DEPTREE[x,NAME]) 368 depend_dbadd(BEFORE, tmpsplit[y], DEPTREE[x,NAME])
248 } 369 }
249 } 370 }
250
251 # Lastly resolve provides
252 dblprovide = 0
253 for (x = 1; x <= RCNUMBER;x++) {
254
255 if ((x,PROVIDE) in DEPTREE) {
256
257 split(DEPTREE[x,PROVIDE], providesplit)
258
259 for (y in providesplit) {
260
261 split(DEPTYPES, typesplit)
262
263 for (z in typesplit) {
264
265 if (isdir(SVCDIR "/" typesplit[z] "/" providesplit[y])) {
266
267 deps = ""
268
269 pipe = "ls " SVCDIR "/" typesplit[z] "/" providesplit[y]
270 while ((pipe | getline tmpstring) > 0)
271 deps = deps " " tmpstring
272 close(pipe)
273
274 split(deps, depsplit)
275
276 for (i in depsplit) {
277
278 provides = ""
279
280 pipe = "ls " SVCDIR "/provide/" providesplit[y]
281 while ((pipe | getline tmpstring) > 0)
282 provides = provides " " tmpstring
283 close(pipe)
284
285 for (j = 1; j <= 6; j++)
286 if (TYPENAMES[j] == typesplit[z])
287 depend_dbadd(j, depsplit[i], provides)
288 }
289
290 assert(dosystem("rm -rf " SVCDIR "/" typesplit[z] "/" providesplit[y]),
291 "system(rm -rf " SVCDIR "/" typesplit[z] "/" providesplit[y] ")")
292 }
293 }
294
295 counter = 0
296 provides = ""
297
298 pipe = "ls " SVCDIR "/provide/" providesplit[y]
299 while ((pipe | getline tmpstring) > 0)
300 provides = provides " " tmpstring
301 close(pipe)
302
303 split(provides, tmpprovidesplit)
304
305 for (i in tmpprovidesplit)
306 counter++
307
308 if ((counter > 1) && (providesplit[y] != "net")) {
309
310 dblprovide = 1
311 errstring = providesplit[y]
312 }
313 }
314 }
315 }
316
317 if (dblprovide) {
318
319 ewarn("PROVIDE: it usually is not a good idea to have more than one")
320 ewarn(" service provide the same virtual service (" errstring ")!")
321 }
322} 371}
323 372
324 373
325# vim:ts=4 374# vim:ts=4

Legend:
Removed from v.356  
changed lines
  Added in v.357

  ViewVC Help
Powered by ViewVC 1.1.20