/var/lib/sorcery/modules/libstate
1 #!/bin/bash
2 #---------------------------------------------------------------------
3 ## Handles storage of state information, incluing depends and package
4 ## files. Also handles looking information up about what is installed
5 ## and what depends on what.
6 ##
7 ## @Copyright Copyright (C) 2002 The Source Mage Team <http://www.sourcemage.org>
8 #---------------------------------------------------------------------
9
10 #---------------------------------------------------------------------
11 ##
12 ## Adds a dependency to the a depends database file. Returns 1 if the
13 ## 3rd or 4th fields are not valid.
14 ##
15 ## @param Depends status file
16 ## @param Name of the "parent" spell
17 ## @param Name of the spell the parent spell depends on
18 ## @param "on" or "off" depending on whether the user installed the dependency
19 ## @param Type of dependency (required or optional)
20 ## @param option to pass to C<configure> if the dependency is installed
21 ## @param option to pass to C<configure> if the dependency is not installed
22 ##
23 ## @Example add_depends kdelibs alsa-driver on optional --with-alsa --without-alsa
24 ##
25 #---------------------------------------------------------------------
26 function add_depends()
27 { # $1=depends file $2=spell, $3=depends, $4=on/off, $5=optional/required, $6=on arg, $7=off arg
28 debug "libstate" "add_depends() - $*"
29
30 #already here for some reason
31 search_depends_status_exact "$@" >/dev/null && return 0
32
33 local depends_status=$1
34 shift
35
36 # ensure the info is valid (perhaps add check that spells exist?)
37 list_find "on off" "$3" || return 1
38 list_find "required optional runtime suggest" "$4" || return 1
39
40 # Allow add_depends to override previous ones for the same pair of spells
41 search_depends_status "$depends_status" "$1" "$2" >/dev/null &&
42 remove_depends_status "$depends_status" "$1" "$2"
43
44 local t_status
45 # lock_start_transaction "$depends_status" t_status
46 echo "$1:$2:$3:$4:$5:$6" >> "$depends_status"
47 # lock_commit_transaction "$depends_status"
48
49 return 0
50
51 }
52
53 #---------------------------------------------------------------------
54 ##
55 ## In case you want to search in all the fields of the $1
56 ##
57 ## Arguments can be regexp
58 ##
59 ## Prints out the matching line(s)
60 ## @Stdout the matching line(s)
61 ## @param depends file
62 ## @param spell
63 ## @param depends
64 ## @param on/off
65 ## @param optional/required
66 ## @param on arg
67 ## @param off arg
68 ##
69 ## @return 0 if entry was found
70 ## @return 1 if entry was not found
71 ## @return 2 on error
72 ##
73 #---------------------------------------------------------------------
74 function search_depends_status_exact()
75 { # $1=depends file $2=spell, $3=depends, $4=on/off, $5=optional/required, $6=on arg, $7=off arg
76
77 local depends_status=$1
78 shift
79
80 local a1 a2 a3 a4 a5 a6
81 esc_str "$1" a1; esc_str "$3" a3
82 esc_str "$4" a4; esc_str "$5" a5; esc_str "$6" a6
83 esc_provider_str "$2" a2
84 debug "libstate" "search_depends_status_exact: [$a1:$a2:$a3:$a4:$a5:$a6]"
85
86 lock_file "$depends_status"
87 grep "^$a1:$a2:$a3:$a4:$a5:$a6$" "$depends_status"
88 rc=$?
89 unlock_file "$depends_status"
90
91 return $rc
92 }
93
94 #---------------------------------------------------------------------
95 ##
96 ## Search depends status, dont do anything escaping.
97 ##
98 ## Arguments can be regexp
99 ##
100 ## Prints out the matching line(s)
101 ## @Stdout the matching line(s)
102 ## @param depends file
103 ## @param spell
104 ## @param depends
105 ## @param on/off (optional)
106 ## @param optional/required (optional)
107 ## @param on arg (optional)
108 ## @param off arg (optional)
109 ##
110 #---------------------------------------------------------------------
111 function search_depends_status_simple()
112 { # $1=depends file $2=spell, $3=depends, $4=on/off, $5=optional/required, $6=on arg, $7=off arg
113
114 local depends_status=$1
115 shift
116
117 local a1 a2 a3 a4 a5 a6
118 esc_str "$1" a1; esc_provider_str "$2" a2
119 a3=${3:-.*} ; a4=${4:-.*}
120 esc_str "$5" a5; esc_str "$6" a6
121 a5=${5:-.*} ; a6=${6:-.*}
122
123 lock_file "$depends_status"
124 grep "^$a1:$a2\(([^:]*)\)\?:$a3:$a4:$a5:$a6$" "$depends_status"
125 unlock_file "$depends_status"
126 }
127
128
129 #---------------------------------------------------------------------
130 ## @param depends file
131 ## @param spell
132 ## @param depends (optional)
133 ## @Stdout matching lines
134 ## In case you want to search by spell or dependency in $1
135 ##
136 ## Arguments can be regexp
137 ##
138 ## Prints out the matching line(s)
139 ##
140 #---------------------------------------------------------------------
141 function search_depends_status()
142 { # $1=depends file $2=spell, $3=(opt)depends
143
144 [[ -z $2 ]] && return 1
145 local depends_status=$1
146 shift
147
148 local spell
149 esc_str "$1" spell
150 # lock_file "$depends_status"
151 if [[ -z $2 ]]; then
152 grep "^$spell:" "$depends_status"
153 else
154 local depends
155 esc_provider_str "$2" depends
156 grep "^$spell:$depends:" "$depends_status"
157 fi
158 # unlock_file "$depends_status"
159 }
160
161
162
163 #---------------------------------------------------------------------
164 ##
165 ## @param depends file
166 ## @param spell
167 ## @param dependency spell
168 ## @Stdout list of options
169 ##
170 ## Returns a list of options for ./configure from $1
171 ## Primarily aimed at generating $OPTS contents
172 ##
173 ## Prints out one line of output
174 #---------------------------------------------------------------------
175 function get_depends_options()
176 { # $1=depends_status $2=spell
177
178 local depends_status=$1
179 shift
180
181 [ -z "$1" ] && {
182 message "${PROBLEM_COLOR}${1:-<null>} is not a spell name${DEFAULT_COLOR}"
183 return
184 }
185
186 local START
187 esc_str "$1" START
188 debug "libstate" "get_depends_options() - START=$START"
189 lock_file "$depends_status"
190 awk -F ':' -v start=$START "{ if (\$1 == start) if (\$3 == \"on\") OPTS = OPTS \" \" \$5; else OPTS = OPTS \" \" \$6; } END { print OPTS; }" $depends_status 2> /dev/null
191 unlock_file "$depends_status"
192 }
193
194
195 #---------------------------------------------------------------------
196 ##
197 ## Arguments can be regexp, and all but the spell are optional
198 ##
199 ## @param depends file
200 ## @param spell
201 ## @param depends
202 ## @param on/off
203 ## @param optional/required
204 ## @param on arg
205 ## @param off arg
206 ##
207 #---------------------------------------------------------------------
208 function remove_depends_status()
209 { # $1=depends file $2=spell, $3=(OPT)depends, $4=(OPT)on/off, $5=(OPT)optional/required, $6=(OPT)on arg, $7=(OPT)off arg
210
211 local depends_status=$1
212 shift
213
214 local a1 a2 a3 a4 a5 a6
215 # arguments 1 and 2 are spell names, which might have characters that
216 # look like regexps, 5 and 6 might like funny too
217 # contrast 3 and 4 which are "on", "off", "required" or "optional"
218 # if they are regexps its probably desired so dont escape those
219 esc_str "$1" a1; esc_str "$2" a2
220 a1=${a1:-.*}; a2=${a2:-.*}
221
222 a3=${3:-.*} ; a4=${4:-.*}
223
224 esc_str "$5" a5; esc_str "$6" a6
225 a5=${a5:-.*}; a6=${a6:-.*}
226 [[ "$a5" == "[none]" ]] && a5="\\[none\\]"
227
228 local t_status
229 lock_start_transaction "$depends_status" t_status
230 sedit "/^$a1:$a2:$a3:$a4:$a5:$a6$/D" "$t_status"
231 lock_commit_transaction "$depends_status"
232 }
233
234 #---------------------------------------------------------------------
235 ## Toggle optional and suggested dependencies on/off
236 ##
237 ## @param depends file
238 ## @param spell
239 ## @param dependency
240 ##
241 #---------------------------------------------------------------------
242 function toggle_depends_status() {
243 local depends_status=$1
244 shift
245
246 local spell dependency
247 esc_str "$1" spell; esc_str "$2" dependency
248
249 local t_status
250 lock_start_transaction "$depends_status" t_status
251 awk -F ':' -v OFS=':' \
252 '/^'$spell:$dependency':(on|off):(optional|suggest):/ \
253 { if ($3 == "on") $3 = "off"; else $3 = "on"; }
254 { print; }' $depends_status > $t_status
255 lock_commit_transaction "$depends_status"
256 }
257
258 #---------------------------------------------------------------------
259 ## Changes the $spell's provider of $feature to a $new one. Can also
260 ## toggle it to be enabled or disabled.
261 ##
262 ## @param depends file
263 ## @param spell
264 ## @param new provider
265 ## @param feature
266 ## @param on/off
267 ##
268 #---------------------------------------------------------------------
269 function change_spell_provider() {
270 local depends_status=$1
271 shift
272
273 local spell new_provider feature enabled
274 esc_str "$1" spell
275 esc_str "$2" new_provider
276 esc_str "$3" feature
277 enabled=$4
278
279 local t_status
280 lock_start_transaction "$depends_status" t_status
281 if [[ -z $enabled ]]; then
282 sed -i "s/^$spell:[^:]*($feature):/$spell:$new_provider($feature):/" $t_status
283 else
284 sed -i "s/^$spell:[^:]*($feature):[^:]*:/$spell:$new_provider($feature):$enabled:/" $t_status
285 fi
286 lock_commit_transaction "$depends_status"
287 }
288
289 #---------------------------------------------------------------------
290 ## Sets up the uncommitted depends file. If the name isn't
291 ## found in the hash table create it. If the file already exists
292 ## move it to the abandoned depends directory and start with a new one.
293 ## The uncommitted_hash hash table should be hash_export'ed to
294 ## make it through the call to make.
295 ##
296 ## @param spell
297 ## @param variable name to put the filename name in (pass by reference)
298 ##
299 #---------------------------------------------------------------------
300 function get_uncommitted_depends_file() {
301 local SPELL=$1
302 local temp_spell_depends
303 hash_get_ref "uncommitted_hash" $SPELL temp_spell_depends
304
305 if ! [[ $temp_spell_depends ]] ; then
306 temp_spell_depends="$UNCOMMITTED_DEPENDS/$SPELL"
307 hash_put "uncommitted_hash" "$SPELL" "$temp_spell_depends"
308
309 mkdir -p "$ABANDONED_DEPENDS"
310 mv "$temp_spell_depends" "$ABANDONED_DEPENDS" &>/dev/null
311 mv "$temp_spell_depends:*" "$ABANDONED_DEPENDS" &>/dev/null
312
313 mkdir -p "$UNCOMMITTED_DEPENDS"
314 touch "$temp_spell_depends"
315 fi
316 eval "$2=\"$temp_spell_depends\""
317 }
318
319 #---------------------------------------------------------------------
320 ## Get the uncommitted sub-depends file. Uses get_uncommitted_depends_file.
321 ## This file is intended for use by the sub-dependee.
322 ##
323 ## @param spell
324 ## @param variable name to put the filename in
325 #---------------------------------------------------------------------
326 function get_uncommitted_sub_depends_file() {
327 local SPELL=$1
328 local upvar=$2
329 local __tmp
330 get_uncommitted_depends_file "$SPELL" __tmp
331 # : cannot be in spell names, so we can take advantage of the namespace
332 __tmp=${__tmp}:s
333 # we can assume that the parent directory exists because
334 # get_uncommitted_depends_file creates it
335 touch "$__tmp"
336 eval "$2=\"$__tmp\""
337 }
338
339 #---------------------------------------------------------------------
340 ## Get the uncommitted sub-depends file. Uses get_uncommitted_depends_file
341 ## This file is intended for use by the requester.
342 ##
343 ## @param spell
344 ## @param variable name to put the filename in
345 #---------------------------------------------------------------------
346 function get_uncommitted_rsub_depends_file() {
347 local SPELL=$1
348 local upvar=$2
349 local __tmp
350 get_uncommitted_depends_file "$SPELL" __tmp
351 # : cannot be in spell names, so we can take advantage of the namespace
352 __tmp=${__tmp}:rs
353 # we can assume that the parent directory exists because
354 # get_uncommitted_depends_file creates it
355 touch "$__tmp"
356 eval "$2=\"$__tmp\""
357 }
358
359 #---------------------------------------------------------------------
360 ## Add a sub-dependency.
361 ##
362 ## @param sub-depends file
363 ## @param requester file
364 ## @param sub-dependee
365 ## @param sub-depends
366 #---------------------------------------------------------------------
367 function add_sub_depends() {
368 $STD_DEBUG
369 remove_sub_depends "$@" || return 1
370 local file=$1
371 shift
372
373 local t_file
374 lock_start_transaction "$file" t_file
375 echo "$1:$2:$3" >> "$t_file"
376 lock_commit_transaction "$file"
377 }
378
379 #---------------------------------------------------------------------
380 ## Search in sub-depends file.
381 ##
382 ## @param sub-depends file
383 ## @param requester file (optional)
384 ## @param sub-dependee (optional)
385 ## @param sub-depends (optional)
386 #---------------------------------------------------------------------
387 function search_sub_depends() {
388 $STD_DEBUG
389 local file=$1
390 shift
391 local a1 a2 a3
392 esc_str "$1" a1; esc_str "$2" a2; esc_str "$3" a3
393 a1=${a1:-.*}
394 a2=${a2:-.*}
395 a3=${a3:-.*}
396
397 lock_file "$file"
398 grep "^$a1:$a2:$a3$" "$file"
399 unlock_file "$file"
400 }
401
402 #---------------------------------------------------------------------
403 ## Remove a sub-depends.
404 ##
405 ## @param sub-depends file
406 ## @param requester
407 ## @param sub-dependee
408 ## @param sub-depends
409 #---------------------------------------------------------------------
410 function remove_sub_depends() {
411 $STD_DEBUG
412 local file=$1
413 shift
414
415 test -f $file || return
416
417 local a1 a2 a3
418 esc_str "$1" a1; esc_str "$2" a2; esc_str "$3" a3
419 a1=${a1:-.*}; a2=${a2:-.*}; a3=${a3:-.*}
420
421 local t_file
422 lock_start_transaction "$file" t_file
423 sedit "/^$a1:$a2:$a3$/D" "$t_file"
424 lock_commit_transaction "$file"
425 }
426
427 #---------------------------------------------------------------------
428 ## Default depends and default provider api
429 ## default depends examples:
430 ##
431 ## default xfree86 provider to ImageMagick is xfree86
432 ## ImageMagick:X11-LIBS:xfree86
433 ##
434 ## default answer to optional_depends graphviz for ImageMagick is "no"
435 ## ImageMagick:graphviz:off
436 ##
437 ##
438 ## default provider examples:
439 ## use xorg as X11-LIBS even if its optional
440 ## xorg:X11-LIBS:on
441 ##
442 ## use xfree86 as X11-LIBS unless the [none] option exists (and use that instead)
443 ## xfree86:X11-LIBS:off
444 #---------------------------------------------------------------------
445
446 #---------------------------------------------------------------------
447 ##
448 ## add default depends entry, if $3 is a spell $4 must be on/off
449 ## if $3 is a PROVIDER $4 must be a spell
450 ##
451 ## @param depends file
452 ## @param spell
453 ## @param depends/PROVIDER
454 ## @param on/off
455 ##
456 #---------------------------------------------------------------------
457 function add_default_depends() {
458 debug "libstate" "add_default_depends() - $*"
459
460 #already here
461 search_default_depends "$@" >/dev/null && return 0
462
463 local file=$1
464 shift
465 # ensure the info is valid... (this is redundant if calling
466 # from sorcery, but that may not always be the case...
467 if [[ $3 != on ]] && [[ $3 != off ]] ; then
468 return 1
469 fi
470
471 { [[ ! $1 ]] && [[ ! $2 ]] ; } && return 1
472
473 if [[ $1 ]] && ! codex_does_spell_exist $1 &>/dev/null; then
474 return 1
475 fi
476
477 if [[ $2 ]] && ! codex_does_spell_exist $2; then
478 return 1
479 fi
480
481 lock_start_transaction "$file" tfile
482 remove_default_depends $tfile $1 $2
483 echo "$1:$2:$3" >> $tfile
484 lock_commit_transaction $file
485
486 return 0
487
488 }
489
490 #---------------------------------------------------------------------
491 ##
492 ## Arguments can be regexp, $2, $3 and $4 are optional
493 ## Caller must lock the file
494 ##
495 ## @param depends file
496 ## @param spell
497 ## @param depends/PROVIDER
498 ## @param on/off/spell
499 ##
500 #---------------------------------------------------------------------
501 function remove_default_depends() {
502
503 local file=$1
504 shift
505 test -e $file || return
506
507 local a1 a2 a3
508 esc_str "$1" a1; esc_str "$2" a2; esc_str "$3" a3
509
510 a3=${a3:-.*}
511
512 local t_file
513 lock_start_transaction "$file" t_file
514 sedit "/^$a1:$a2:$a3$/D" $t_file
515 lock_commit_transaction "$file"
516 }
517
518 #---------------------------------------------------------------------
519 ##
520 ## Arguments can be regexp, $2 $3 and $4 are optional
521 ##
522 ## @param depends file
523 ## @param spell
524 ## @param depends/PROVIDER
525 ## @param on/off/spell
526 ##
527 #---------------------------------------------------------------------
528 function search_default_depends() {
529
530 local default_depends=$1
531 shift
532 [[ -s $default_depends ]] || return
533
534 local a1 a2 a3
535 esc_str "$1" a1; esc_str "$2" a2; esc_str "$3" a3
536 a3=${a3:-.*}
537
538 debug "libstate" "search_default_depends: [$a1:$a2:$a3]"
539 lock_file "$default_depends"
540 grep "^$a1:$a2:$a3$" $default_depends
541 rc=$?
542 unlock_file "$default_depends"
543
544 return $rc
545 }
546
547
548 #---------------------------------------------------------------------
549 ##
550 ## Arguments can be regexp, $3 and $4 are optional
551 ##
552 ## @param depends file
553 ## @param spell
554 ## @param PROVIDER
555 ## @param on/off
556 ##
557 #---------------------------------------------------------------------
558 function add_default_provider() {
559 debug "libstate" "add_default_depends() - $*"
560
561 #already here
562 search_default_provider "$@" >/dev/null && return 0
563
564 local file=$1
565 shift
566
567 #ensure the info is valid...
568 { [[ ! $1 ]] && [[ ! $2 ]] ; } && return 1
569 { [[ $3 != on ]] && [[ $3 != off ]] ; } && return 1
570
571 if [[ $1 ]] && ! codex_does_spell_exist $1 &>/dev/null ; then
572 return 1
573 fi
574 if [[ $2 ]] && ! codex_does_service_exist $2 &>/dev/null ; then
575 return 1
576 fi
577
578 lock_start_transaction "$file" tfile
579 remove_default_provider $tfile "" $2
580 echo "$1:$2:$3" >> $tfile
581 lock_commit_transaction $file
582
583 return 0
584 }
585
586 # these are the same, as their countparts but are here for completeness
587 # and incase they do someday diverge
588 function remove_default_provider() {
589 remove_default_depends "$@"
590 }
591
592 function search_default_provider() {
593 search_default_depends "$@"
594 }
595
596 #---------------------------------------------------------------------
597 ## @param cache file
598 ## @param spell name
599 ##
600 ## Removes the spell info from the passed file ($VERSION_STATUS)
601 ##
602 #---------------------------------------------------------------------
603 function remove_version_cache() {
604 local file=$1
605 lock_start_transaction "$file" t_file
606 sed -i "/^$2 /d" $t_file
607 lock_commit_transaction $file
608 }
609
610 #---------------------------------------------------------------------
611 ## @param cache file
612 ## @param spell name
613 ## @param version
614 ## @param patchlevel
615 ## @param security patch
616 ## @param updated
617 ##
618 ## Given a spell and the factors that affect queuing, this function
619 ## adds the info to the passed file (usually $VERSION_STATUS)
620 ##
621 #---------------------------------------------------------------------
622 function add_version_cache() {
623 local file=$1
624 shift
625 remove_version_cache "$file" $1
626
627 lock_start_transaction "$file" t_file
628 echo "$1 ${2:-0} ${3:-0} ${4:-0} ${5:-0}" >> $t_file
629 lock_commit_transaction $file
630 }
631
632 #---------------------------------------------------------------------
633 ##
634 ## Adds an entry to the SPELL_STATUS file
635 ##
636 ## Arguments may either be SPELL, ACTION, VERSIONS, or just
637 ## ACTION if there exists SPELL and VERSIONS variables already
638 ## set.
639 ## @param spell OR action
640 ## @param (if spell) action
641 ## @param (if spell) version
642 ##
643 #---------------------------------------------------------------------
644 function add_spell_status()
645 { #$1=spell, $2=action, $3=version, OR $1=action.
646
647 local spell action version date
648 if [ $# -eq 1 ] ; then
649 spell="$SPELL"
650 action="$1"
651 version="$VERSION"
652 else
653 spell=$1
654 action=$2
655 version=$3
656 fi
657 [[ $spell ]] && [[ $action ]] && [[ $version ]] || return 1
658 date=`date +%Y%m%d`
659 lock_start_transaction "$SPELL_STATUS" tSPELL_STATUS
660 echo "$spell:$date:$action:$version" >> $tSPELL_STATUS
661 lock_commit_transaction $SPELL_STATUS
662
663 }
664
665 #---------------------------------------------------------------------
666 ## @param spell name
667 ##
668 ## Given a spell, status (installed, held, etc), and version, add_spell
669 ## adds the spell to the /var/state/sorcery/packages file
670 ##
671 #---------------------------------------------------------------------
672 function add_spell() {
673 remove_spell $1
674 add_spell_status $1 $2 $3
675 }
676
677 #---------------------------------------------------------------------
678 ## @param spell status file
679 ## @param spell
680 ## @param version (optional)
681 ## @Stdout matching lines
682 ##
683 ## Arguments can be regexp
684 ##
685 ## Prints out the matching line(s)
686 ##
687 #---------------------------------------------------------------------
688 function search_spell_status() {
689 [[ -z $2 ]] && return 1
690 local spell_status=$1
691 shift
692
693 local spell
694 esc_str "$1" spell
695 lock_file "$spell_status"
696 if [[ -z $2 ]]; then
697 grep "^$spell:" $spell_status
698 else
699 local version
700 esc_str "$2" version
701 grep "^$spell:$version:" $spell_status
702 fi
703 unlock_file "$spell_status"
704 }
705
706 #---------------------------------------------------------------------
707 ##
708 ## @param spell ( [A-Za-z0-9_-] )
709 ## @param version (optional and may not contain spaces or colons; '.' and '*' have special meaning)
710 ## @param variable to set
711 ## @Stdout last matching line ( only one even if there are more )
712 ##
713 ## Searches the SPELL_STATUS file for a spell and optionally
714 ## a version.
715 ##
716 ## Prints out the matching spell's status
717 ## @return 1 only for critical problems ( missing SPELL_STATUS file )
718 ## @return 0 for all other cases ( even when spell is not found )
719 ##
720 #---------------------------------------------------------------------
721 function query_spell_status()
722 { #$1=spell, $2=(OPT)version
723
724 local return_var __status
725 [[ -e $SPELL_STATUS ]] || return 1
726
727 lock_file "$SPELL_STATUS"
728 if [[ -z $3 ]]; then
729 [[ -z $2 ]] && return 0
730 return_var="$2"
731 __status=$(awk -F: -v spell="$1" '{ if (spell == $1) status=$3 } END{print status}' "$SPELL_STATUS" 2>/dev/null)
732 else
733 return_var="$3"
734 __status=$(awk -F: -v spell="$1" -v version="$2" '{ if (spell == $1 && version == $4) status=$3 } END{print status}' "$SPELL_STATUS" 2>/dev/null)
735 fi
736 unlock_file "$SPELL_STATUS"
737
738 eval "$return_var=\"\$__status\""
739 return 0
740 }
741
742 #---------------------------------------------------------------------
743 ## @Type API
744 ## @param spell name
745 ##
746 ## @return 0 if the given spell's status is "installed"
747 #---------------------------------------------------------------------
748 function real_spell_installed() {
749 local status
750 query_spell_status "$1" status
751 [[ $status == installed ]]
752 }
753
754
755 #---------------------------------------------------------------------
756 ## @param spell name
757 ##
758 ## @return 0 if the given spell's status is "held"
759 ##
760 #---------------------------------------------------------------------
761 function real_spell_held() {
762 local status
763 query_spell_status "$1" status
764 [[ $status == held ]]
765 }
766
767 #---------------------------------------------------------------------
768 ## @Type API
769 ## @param spell name
770 ##
771 ## @return 0 if the given spell's status is "installed" or "held"
772 #---------------------------------------------------------------------
773 function real_spell_ok() {
774 local status
775 query_spell_status "$1" status
776 [[ $status == installed ]] || [[ $status == held ]]
777 }
778
779
780 #---------------------------------------------------------------------
781 ## @Type API
782 ## @param Provider name
783 ##
784 ## @return 0 if any provider of $1 is installed
785 #---------------------------------------------------------------------
786 function real_provider_ok() {
787 for spell in $(search_depends_status_exact $DEPENDS_STATUS '.*' ".*($1)" \
788 'on' '.*' '.*' |cut -f2 -d:|cut -f1 -d\(|sort -u); do
789 spell_ok $spell && return 0
790 done
791 return 1
792 }
793
794 #---------------------------------------------------------------------
795 ## @Type API
796 ## @param Spell name
797 ## @param Provider name
798 ## @param If empty get the uncommited spell info, if anything else get info from the committed ($DEPENDS_STATUS) database. If the uncommited db doesnt exist (maybe we're not casting) use DEPENDS_STATUS
799 ##
800 ## @return 0 if a provider could be found 1 if not
801 ## @return 0 if a dependency from $1 on $2 is enabled, 1 otherwise.
802 ## @stdout the provider name(s)
803 #---------------------------------------------------------------------
804 function real_get_spell_provider() {
805 local dep_status
806 if [[ $3 ]] ; then
807 dep_status=$DEPENDS_STATUS
808 else
809 hash_get_ref uncommitted_hash $1 dep_status
810 [[ $dep_status ]] || dep_status=$DEPENDS_STATUS
811 fi
812 search_depends_status_exact $dep_status "$1" ".*($2)" \
813 'on' '.*' '.*' '.*' |cut -f2 -d:|cut -f1 -d\(|sort -u
814 }
815
816 #---------------------------------------------------------------------
817 ## @Type API
818 ## @param Spell name
819 ## @param Target spell name
820 ## @param If empty get the uncommited spell info, if anything else get info from the committed ($DEPENDS_STATUS) database. If the uncommited db doesnt exist (maybe we're not casting) use DEPENDS_STATUS
821 ##
822 ## @return 0 if a dependency from $1 on $2 is enabled, 1 otherwise.
823 ## @stdout the provider name(s)
824 #---------------------------------------------------------------------
825 function real_is_depends_enabled() {
826 local dep_status
827 if [[ $3 ]] ; then
828 dep_status=$DEPENDS_STATUS
829 else
830 hash_get_ref uncommitted_hash $1 dep_status
831 [[ $dep_status ]] || dep_status=$DEPENDS_STATUS
832 fi
833 [[ -n $(search_depends_status_simple $dep_status "$1" "$2" 'on' ) ]]
834 }
835
836
837 #---------------------------------------------------------------------
838 ## @param spell name
839 ##
840 ## @return 0 if the given spell's status is "exiled"
841 ##
842 #---------------------------------------------------------------------
843 function real_spell_exiled() {
844 local status
845 query_spell_status "$1" status
846 [[ $status == exiled ]]
847 }
848
849
850 #---------------------------------------------------------------------
851 ## @param spell to remove status of
852 ## Removes all specified offending entries in SPELL_STATUS
853 ##
854 #---------------------------------------------------------------------
855 function remove_spell_status()
856 { #$1=spell to remove status of
857
858 lock_start_transaction "$SPELL_STATUS" tSPELL_STATUS
859 grep -v "^$1:" $SPELL_STATUS > $tSPELL_STATUS
860 lock_commit_transaction $SPELL_STATUS
861
862 }
863
864 #---------------------------------------------------------------------
865 ## @param spell name
866 ##
867 ## Removes the given spell from the /var/state/sorcery/packages file.
868 ## if C<EXILE> is set, the spell is changed to "exiled" in the file.
869 ##
870 #---------------------------------------------------------------------
871 function remove_spell() {
872 debug "libsorcery" "Running remove_spell() on $1"
873 remove_spell_status $1
874 if [ -n "$EXILE" ]; then
875 add_spell_status $1 "exiled" "0.0"
876 fi
877 }
878
879
880 #---------------------------------------------------------------------
881 ## @Stdout All spell stati
882 ## Just here to round out the SPELL_STATUS functions so that
883 ## SPELL_STATUS doesn't have to mentioned in libsorcery
884 ##
885 #---------------------------------------------------------------------
886 function all_spell_status()
887 {
888 lock_file "$SPELL_STATUS"
889 cat $SPELL_STATUS
890 unlock_file "$SPELL_STATUS"
891 }
892
893
894 #---------------------------------------------------------------------
895 ## @param spells
896 ## sets <spells>'s status to held
897 ##
898 #---------------------------------------------------------------------
899 function set_held() {
900 local t_status
901 lock_start_transaction "$SPELL_STATUS" t_status
902 for to_hold in $@; do
903 sedit 's/\(^'$(esc_str $to_hold)':[^:]*:\)installed/\1held/' $t_status
904 done
905 lock_commit_transaction $SPELL_STATUS
906 }
907
908
909 #---------------------------------------------------------------------
910 ## @param spells
911 ## sets <spells>'s status to exiled
912 ##
913 #---------------------------------------------------------------------
914 function set_exiled() {
915 local TO_DISPELL=""
916 local TO_EXILE
917 local MY_STATUS
918
919 for TO_EXILE in $@; do
920 query_spell_status "$TO_EXILE" MY_STATUS
921 case "$MY_STATUS" in
922 "" )
923 add_spell_status $TO_EXILE exiled 0.0
924 message "Spell '$TO_EXILE' exiled."
925 ;;
926 "exiled" )
927 message "${MESSAGE_COLOR}Spell ${DEFAULT_COLOR}'$TO_EXILE'" \
928 "${MESSAGE_COLOR}is allready exiled.${DEFAULT_COLOR}"
929 ;;
930 "installed" )
931 local ask="'$TO_EXILE' is installed."
932 ask="${ask} Do you want to dispel and exile it ?"
933 query "$ask" &&
934 TO_DISPELL="$TO_DISPELL $TO_EXILE"
935 ;;
936 * )
937 message "${PROBLEM_COLOR}Can't exile spell" \
938 "${DEFAULT_COLOR}'$TO_EXILE'${PROBLEM_COLOR}" \
939 "which has status '$MY_STATUS'${DEFAULT_COLOR}"
940 ;;
941 esac
942 done
943 if [ -n "$TO_DISPELL" ]; then
944 dispel -e $TO_DISPELL
945 fi
946 }
947
948
949 #---------------------------------------------------------------------
950 ## @param spells
951 ## resets <spells>'s 'exiled' status
952 ##
953 #---------------------------------------------------------------------
954 function set_unexiled() {
955 local MY_STATUS
956 local TO_UNEXILE
957 for TO_UNEXILE in $@; do
958 query_spell_status "$TO_UNEXILE" MY_STATUS
959 if [ x"$MY_STATUS" == x"exiled" ]; then
960 remove_spell $TO_UNEXILE
961 else
962 message "${MESSAGE_COLOR}Can't unexile spell${DEFAULT_COLOR}" \
963 "'$TO_UNEXILE'${MESSAGE_COLOR}, it's not exiled${DEFAULT_COLOR}"
964 fi
965 done
966 }
967
968
969 #---------------------------------------------------------------------
970 ## @param spells
971 ## sets <spells>'s status to installed
972 ##
973 #---------------------------------------------------------------------
974 function set_unheld() {
975 local t_status
976 lock_start_transaction "$SPELL_STATUS" t_status
977 for to_hold in $@; do
978 sedit 's/\(^'$(esc_str $to_hold)':[^:]*:\)held/\1installed/' $t_status
979 done
980 lock_commit_transaction $SPELL_STATUS
981 }
982
983
984 #---------------------------------------------------------------------
985 ## @param status (installed, held, exiled or ok[for the first two])
986 ## @Stdout spells
987 ## returns all spells that are in that status
988 ##
989 #---------------------------------------------------------------------
990 function get_all_spells_with_status() {
991 local status=$1
992 lock_file $SPELL_STATUS
993 if [[ $status != ok ]]; then
994 gawk -F: 'BEGIN { status="'$status'" }
995 ($3 == status) { print $1 }' $SPELL_STATUS
996 else
997 awk -F: '{ if ($3 == "installed" || $3 == "held") print $1 }' $SPELL_STATUS
998 fi
999 unlock_file $SPELL_STATUS
1000 }
1001
1002
1003 #---------------------------------------------------------------------
1004 ## @param variable
1005 ## @param value
1006 ## @param command (optional)
1007 ##
1008 ## Modifies (or adds) an entry in the local/config.
1009 ## If "command" is the third argument, a space will separate the
1010 ## variable and value rather than the equals sign.
1011 ##
1012 #---------------------------------------------------------------------
1013 function modify_local_config() {
1014 debug "libstate" "modify_local_config() - $*"
1015 modify_config $LOCAL_CONFIG "$@"
1016 }
1017
1018
1019 #---------------------------------------------------------------------
1020 ## @param Filename
1021 ## @param variable
1022 ## @param value
1023 ## @param command (optional)
1024 ##
1025 ## Modifies (or adds) an entry in the local/config.
1026 ## If "command" is the third argument, a space will separate the
1027 ## variable and value rather than the equals sign.
1028 ##
1029 #---------------------------------------------------------------------
1030 function modify_config() {
1031
1032 debug "libstate" "modify_config() - $*"
1033 local FILE=$1
1034 shift;
1035
1036 if ! [[ $1 ]]; then
1037 debug "libstate" "modify_config() - Warning: No name given for config option."
1038 return 1
1039 fi
1040
1041 local TEMP separator EQUALS_COL VARIABLE
1042
1043 if ! test -f $FILE; then
1044 if ! test -d $(smgl_dirname $FILE); then
1045 if test -e $(smgl_dirname $FILE); then
1046 message "Trying to modify $FILE, but $(smgl_dirname $FILE) is not a directory"
1047 return 1
1048 fi
1049 mkdir -p $(smgl_dirname $FILE)
1050 fi &&
1051 touch $FILE || {
1052 message "Failed to create $FILE"
1053 return 1
1054 }
1055 fi
1056
1057 # remove previous reference
1058 lock_start_transaction "$FILE" tFILE
1059 grep -v "^[[:blank:]]*${1}${separator}" $FILE > $tFILE
1060
1061 # justifying...
1062 EQUALS_COL=$((20-${#1}))
1063 [ $EQUALS_COL -lt 0 ] && EQUALS_COL=0
1064 TEMP=""
1065 for (( ; EQUALS_COL>0 ; EQUALS_COL-- )) ; do
1066 TEMP="$TEMP "
1067 done
1068
1069 debug "libstate" "modify_config() - entering new value $VARIABLE $seperator $@ into $tFILE"
1070 # put the new value and justification in
1071 # assign the value in a way that can be overriden from the environment #14454
1072 if [[ $3 == command ]]; then
1073 echo "${TEMP}${1} \"$2\""
1074 else
1075 echo "${TEMP}${1}=\"\${$1:-$2}\""
1076 fi >> $tFILE
1077
1078 lock_commit_transaction $FILE
1079
1080 }
1081
1082 #---------------------------------------------------------------------
1083 ## @param Filename
1084 ## @param variable
1085 ## @param command (optional)
1086 ##
1087 ## Removes an entry in the local/config.
1088 ## If "command" is the third argument, a space will separate the
1089 ## variable and value rather than the equals sign.
1090 ##
1091 #---------------------------------------------------------------------
1092 function remove_config() {
1093
1094 debug "libstate" "remove_config() - $*"
1095 local FILE=$1
1096 shift;
1097
1098 if ! [[ $1 ]]; then
1099 debug "libstate" "remove_config() - Warning: No name given for config option."
1100 return 1
1101 fi
1102
1103 local separator
1104
1105 # what to use as separator?
1106 if [[ $2 == command ]]
1107 then separator=" "
1108 else separator="=" ; fi
1109
1110 # remove previous reference
1111 lock_start_transaction "$FILE" tFILE
1112 grep -v "^[[:blank:]]*${1}${separator}" $FILE > $tFILE
1113 lock_commit_transaction $FILE
1114
1115 }
1116
1117 #---------------------------------------------------------------------
1118 ##
1119 ## This software is free software; you can redistribute it and/or modify
1120 ## it under the terms of the GNU General Public License as published by
1121 ## the Free Software Foundation; either version 2 of the License, or
1122 ## (at your option) any later version.
1123 ##
1124 ## This software is distributed in the hope that it will be useful,
1125 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
1126 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1127 ## GNU General Public License for more details.
1128 ##
1129 ## You should have received a copy of the GNU General Public License
1130 ## along with this software; if not, write to the Free Software
1131 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1132 ##
1133 #---------------------------------------------------------------------
1134 # vim: filetype=sh:tabstop=4:shiftwidth=4:expandtab