Magellan Linux

Annotation of /branches/mage-next/src/mage4.functions.sh.in

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2811 - (hide annotations) (download)
Wed Sep 3 12:01:21 2014 UTC (9 years, 8 months ago) by niro
File size: 80186 byte(s)
-use the highest_magefile program
1 niro 226 #!/bin/bash
2     # Magellan Linux Installer Functions (mage.functions.sh)
3 niro 2268 # $Id$
4 niro 226
5     mage_setup()
6     {
7     [ ! -d ${MROOT}${INSTALLDB} ] && \
8     install -d ${MROOT}${INSTALLDB}
9     [ ! -f ${MROOT}${VIRTUALDB_FILE} ] && \
10     touch ${MROOT}${VIRTUALDB_FILE}
11     [ ! -d ${PKGDIR} ] && install -d ${PKGDIR}
12     [ ! -d ${BUILDDIR} ] && install -d ${BUILDDIR}
13     [ ! -d ${MAGEDIR} ] && install -d ${MAGEDIR}
14    
15     return 0
16     }
17    
18 niro 1549 mchecksum()
19     {
20     local i
21     local rundir
22     local file
23     local method
24     local cmd
25     local retval
26 niro 2225 local sum
27     local dest
28 niro 1549
29     # very basic getops
30     for i in $*
31     do
32     case $1 in
33     --rundir|-r) shift; rundir="$1" ;;
34     --file|-f) shift; file="$1" ;;
35     --method|-m) shift; method="$1" ;;
36     esac
37     shift
38     done
39    
40     # sanity checks
41     [[ -z ${rundir} ]] && die "mchecksum(): rundir missing"
42     [[ -z ${file} ]] && die "mchecksum(): file missing"
43     [[ -z ${method} ]] && die "mchecksum(): method missing"
44    
45     case ${method} in
46     md5) cmd="md5sum" ;;
47     sha256) cmd="sha256sum" ;;
48 niro 1625 *) die "mchecksum(): unknown method '${method}'" ;;
49 niro 1549 esac
50    
51     if [[ -d ${rundir} ]]
52     then
53     pushd ${rundir} &> /dev/null
54 niro 2225
55     # all file must be non-zero
56     retval=0
57     while read sum dest
58     do
59 niro 2232 if [ ! -s ${dest} ]
60 niro 2225 then
61     echo "${dest}: file is empty ;("
62     retval=127
63     fi
64     done < ${file}
65     if [[ ${retval} != 127 ]]
66     then
67     # be verbose here
68     ${cmd} -c ${file} #&> /dev/null
69     retval="$?"
70     fi
71    
72 niro 1549 popd &> /dev/null
73     else
74     retval=1
75     fi
76    
77     return "${retval}"
78     }
79    
80 niro 1653 mcheckemptydir()
81     {
82     local dir="$1"
83     local retval=1
84    
85     if [[ ! -d ${dir} ]]
86     then
87     echo "mcheckemptydir(): '${dir}' is not a directory!"
88     retval=3
89     else
90     shopt -s nullglob dotglob
91     files=( ${dir}/* )
92     (( ${#files[*]} )) || retval=0
93     shopt -u nullglob dotglob
94     fi
95    
96     return ${retval}
97     }
98    
99 niro 2156 unpack_package()
100     {
101     local magefile="$1"
102 niro 2271 local pkgname
103     local pkgfile
104 niro 2156 local pkgtype
105     local tar_opts
106    
107 niro 2271 pkgname="$(get_value_from_magefile PKGNAME ${magefile})"
108     pkgfile="${pkgname}.${PKGSUFFIX}"
109 niro 2156 pkgtype="$(get_value_from_magefile PKGTYPE ${magefile})"
110    
111     xtitle "[ Unpacking ${pkg} ]"
112    
113     # abort on virtual pkg
114     if [[ ${pkgtype} = virtual ]]
115     then
116     echo -ne " ${COLBLUE}---${COLDEFAULT}"
117 niro 2271 echo " !unpack virtual ${pkgname} ... "
118 niro 2156 continue
119     fi
120    
121     # abort on sources pkg
122     if [[ ${pkgtype} = sources ]]
123     then
124     echo -ne " ${COLBLUE}---${COLDEFAULT}"
125 niro 2271 echo " !unpack sources ${pkgname} ... "
126 niro 2156 continue
127     fi
128    
129     # busybox?
130     if need_busybox_support tar
131     then
132     tar_opts="xjf"
133     else
134     tar_opts="xjmf"
135     fi
136    
137 niro 2271 echo -e " ${COLBLUE}***${COLDEFAULT} unpacking ${pkgfile} ... "
138     tar ${tar_opts} ${PKGDIR}/${pkgfile} -C ${BUILDDIR} || die "Unpacking package ${pkgfile}"
139 niro 2156 }
140    
141 niro 226 unpack_packages()
142     {
143     local list="$@"
144     local magefile
145     local count_current
146     local count_total
147 niro 1273 local tar_opts
148 niro 226
149     # get count of total packages
150     declare -i count_current=0
151     declare -i count_total=0
152    
153     for i in ${list}; do (( count_total++ )); done
154    
155     for magefile in ${list}
156     do
157 niro 2156 unpack_package "${magefile}"
158 niro 226 (( count_current++ ))
159     done
160    
161     # add a crlf for a better view
162     if [ ${count_total} -gt 1 ]; then echo; fi
163     }
164    
165     # fix_mtime path/to/$mtime/reffile $pathto/file
166     # creates a given reference file and fixes given file
167     # returns new mtime
168     fix_mtime()
169     {
170     local reference="$1"
171     local pathto="$2"
172     local mtime
173    
174     mtime=$(stat -c %Y "${reference}")
175     touch \
176     --no-create \
177 niro 1690 --no-dereference \
178 niro 226 --time=mtime \
179 niro 1690 --reference="${reference}" \
180 niro 226 "${pathto}"
181    
182     echo "${mtime}"
183     }
184    
185     # fix_descriptor pkgname/.dir "foo1" "foo2"
186     fix_descriptor()
187     {
188     local descriptor="$1"
189     local output
190     local i
191     shift
192    
193     for i in $@
194     do
195     if [[ -z ${output} ]]
196     then
197     output="${i}"
198     else
199     output="${output}§${i}"
200     fi
201     done
202    
203     echo "${output}" >> ${BUILDDIR}/${descriptor}_fixed
204     }
205    
206     ###################################################
207     # function install_direcories #
208     # install_direcories $PKGNAME #
209     ###################################################
210     install_directories()
211     {
212     local pkgname="$1"
213     local pathto
214     local posix
215     local user
216     local group
217     local IFS
218    
219     # sanity checks; abort if not given
220     [ -z "${pkgname}" ] && die "install_directories() \$pkgname not given."
221    
222     # check needed global vars
223     [ -z "${BUILDDIR}" ] && die "install_directories() \$BUILDDIR not set."
224    
225     [ ! -f ${BUILDDIR}/${pkgname}/.dirs ] && die "install_directories() .dirs not found"
226    
227     # sets fieldseperator to "§" instead of " "
228     IFS=§
229    
230     while read pathto posix user group
231     do
232     [ -z "${pathto}" ] && continue
233 niro 1584 mqueryfeature "verbose" && echo -e "\t>>> DIR: ${MROOT}${pathto}"
234 niro 226
235     # monitors /etc/env.d -> env-rebuild
236     [[ ${pathto} = /etc/env.d ]] && export MAGE_ENV_REBUILD=true
237    
238     # monitors /usr/share/info -> info-rebuild
239     [[ ${pathto} = /usr/share/info ]] && export MAGE_INFO_REBUILD=true
240    
241     install -m "${posix}" -o "${user}" -g "${group}" -d "${MROOT}${pathto}"
242     done < ${BUILDDIR}/${pkgname}/.dirs
243    
244     # very important: unsetting the '§' fieldseperator
245     IFS=$'\n'
246     }
247    
248    
249     ###################################################
250     # function install_files #
251     # install_files $PKGNAME #
252     ###################################################
253     install_files()
254     {
255    
256     local pkgname="$1"
257     local pathto
258     local posix
259     local user
260     local group
261     local mtime
262     local md5sum
263    
264     local retval
265     local counter
266     local filename
267     local dest_dirname
268     local dest_protected
269     local IFS
270    
271     # sanity checks; abort if not given
272     [ -z "${pkgname}" ] && die "install_files() \$pkgname not given."
273    
274     # check needed global vars
275     [ -z "${BUILDDIR}" ] && die "install_files() \$BUILDDIR not set."
276    
277     [ ! -f ${BUILDDIR}/${pkgname}/.files ] && die "install_files() .files not found"
278    
279     # delete old files
280     [ -f ${BUILDDIR}/${pkgname}/.files_fixed ] && rm ${BUILDDIR}/${pkgname}/.files_fixed
281    
282     # sets fieldseperator to "§" instead of " "
283     IFS=§
284    
285     while read pathto posix user group mtime md5sum
286     do
287     [ -z "${pathto}" ] && continue
288    
289     # final destination dir of file ${pathto}
290     dest_dirname="$(dirname "${MROOT}${pathto}")"
291    
292     ### small hotfix fix ###
293     [ ! -d "${dest_dirname}" ] && install -d "${dest_dirname}"
294    
295     # check if the file is config_protected
296     # ${MROOT} will automatically added if set !!
297     is_config_protected "${pathto}"
298     retval="$?"
299    
300 niro 942 # 0 - not protected #
301     # 1 - error #
302     # 2 - protected #
303     # 3 - protected but masked #
304     # 4 - protected but ignored #
305 niro 226
306     case ${retval} in
307     # file is not protected - (over)write it
308     0|3)
309 niro 1584 mqueryfeature "verbose" && echo -e "\t>>> FILE: ${MROOT}${pathto}"
310 niro 226 install -m "${posix}" -o "${user}" -g "${group}" \
311     ${BUILDDIR}/${pkgname}/binfiles/"${pathto}" \
312     "${MROOT}${pathto}"
313    
314     # fix mtime and db
315     fix_descriptor ${pkgname}/.files \
316     "${pathto}" \
317     "${posix}" \
318     "${user}" \
319     "${group}" \
320     "$(fix_mtime "${BUILDDIR}/${pkgname}"/.mtime \
321 niro 1289 "${MROOT}${pathto}")" \
322 niro 226 "${md5sum}"
323     ;;
324    
325     # file is protected, write backup file
326     2)
327 niro 1584 if mqueryfeature "verbose"
328 niro 226 then
329     echo -en "${COLRED}"
330     echo -n "! prot "
331     echo -en "${COLDEFAULT}"
332     echo " === FILE: ${MROOT}${pathto}"
333     fi
334     filename="$(basename "${pathto}")"
335     counter=$(count_protected_files "${pathto}")
336     dest_protected="${dest_dirname}/._cfg${counter}_${filename}"
337     install -m "${posix}" -o "${user}" -g "${group}" \
338     ${BUILDDIR}/${pkgname}/binfiles/"${pathto}" \
339     "${dest_protected}"
340    
341     # fix mtime and db
342     fix_descriptor ${pkgname}/.files \
343     "${pathto}" \
344     "${posix}" \
345     "${user}" \
346     "${group}" \
347     "$(fix_mtime "${BUILDDIR}/${pkgname}"/.mtime \
348 niro 1289 "${dest_protected}")" \
349 niro 226 "${md5sum}"
350    
351     # update global MAGE_PROTECT_COUNTER
352     (( MAGE_PROTECT_COUNTER++ ))
353     export MAGE_PROTECT_COUNTER
354     ;;
355 niro 942
356     # file is protected but ignored, delete the update/do nothing
357     4)
358 niro 1584 if mqueryfeature "verbose"
359 niro 942 then
360     echo -en "${COLRED}"
361     echo -n "! ignr "
362     echo -en "${COLDEFAULT}"
363     echo " === FILE: ${MROOT}${pathto}"
364     fi
365 niro 1289 # simply do nothing here - only fix mtime
366     fix_descriptor ${pkgname}/.files \
367     "${pathto}" \
368     "${posix}" \
369     "${user}" \
370     "${group}" \
371     "$(fix_mtime "${BUILDDIR}/${pkgname}"/.mtime \
372     "${MROOT}${pathto}")" \
373     "${md5sum}"
374 niro 942 ;;
375 niro 226 esac
376     done < ${BUILDDIR}/${pkgname}/.files
377    
378     # now copy the fixed file over the old one
379     [ -f ${BUILDDIR}/${pkgname}/.files_fixed ] && \
380     cp ${BUILDDIR}/${pkgname}/.files{_fixed,}
381    
382     # very important: unsetting the '§' fieldseperator
383     IFS=$'\n'
384     }
385    
386    
387     ###################################################
388     # function install_symlinks #
389     # install_symlinks $PKGNAME #
390     ###################################################
391     install_symlinks()
392     {
393     local pkgname="$1"
394     local pathto
395     local posix
396     local link
397     local mtime
398     local IFS
399    
400     # sanity checks; abort if not given
401     [ -z "${pkgname}" ] && die "install_symlinks() \$pkgname not given."
402    
403     # check needed global vars
404     [ -z "${BUILDDIR}" ] && die "install_symlinks() \$BUILDDIR not set."
405    
406     [ ! -f ${BUILDDIR}/${pkgname}/.symlinks ] && die "install_symlinks() .symlinks not found"
407    
408     # delete old files
409     [ -f ${BUILDDIR}/${pkgname}/.symlinks_fixed ] && rm ${BUILDDIR}/${pkgname}/.symlinks_fixed
410    
411     # sets fieldseperator to "§" instead of " "
412     IFS=§
413    
414     while read pathto posix link mtime
415     do
416     [ -z "${pathto}" ] && continue
417 niro 1584 mqueryfeature "verbose" && echo -e "\t>>> LINK: ${MROOT}${pathto}"
418 niro 226
419     ln -snf "${link}" "${MROOT}${pathto}"
420    
421 niro 1690 # fix mtime and db
422     fix_descriptor ${pkgname}/.symlinks \
423     "${pathto}" \
424     "${posix}" \
425     "${link}" \
426     "$(fix_mtime "${BUILDDIR}/${pkgname}"/.mtime \
427     "${MROOT}${pathto}")"
428 niro 226
429     done < ${BUILDDIR}/${pkgname}/.symlinks
430    
431 niro 858 # # now copy the fixed file over the old one
432     # [ -f ${BUILDDIR}/${pkgname}/.symlinks_fixed ] && \
433     # cp -f ${BUILDDIR}/${pkgname}/.symlinks{_fixed,}
434 niro 226
435     # very important: unsetting the '§' fieldseperator
436     IFS=$'\n'
437     }
438    
439    
440     ###################################################
441     # function install_blockdevices #
442     # install_blockdevices $PKGNAME #
443     ###################################################
444     install_blockdevices()
445     {
446     local pkgname="$1"
447     local pathto
448     local posix
449 niro 1209 local user
450     local group
451 niro 226 local IFS
452    
453     # sanity checks; abort if not given
454     [ -z "${pkgname}" ] && die "install_blockdevices() \$pkgname not given."
455    
456     # check needed global vars
457     [ -z "${BUILDDIR}" ] && die "install_blockdevices() \$BUILDDIR not set."
458    
459     [ ! -f ${BUILDDIR}/${pkgname}/.pipes ] && die "install_blockdevices() .pipes not found"
460    
461     # sets fieldseperator to "§" instead of " "
462     IFS=§
463    
464 niro 1271 while read pathto posix major minor user group
465 niro 226 do
466     [ -z "${pathto}" ] && continue
467 niro 1584 mqueryfeature "verbose" && echo -e "\t>>> PIPE: ${MROOT}${pathto}"
468 niro 226
469 niro 1271 mknod -m "${posix}" "${MROOT}${pathto}"
470 niro 1211 # make it optional atm !!
471     if [[ ! -z ${user} ]] && [[ ! -z ${group} ]]
472     then
473 niro 1271 chown "${user}:${group}" "${MROOT}${pathto}" b "${major}" "${minor}"
474 niro 1211 fi
475 niro 226 done < ${BUILDDIR}/${pkgname}/.pipes
476    
477     # very important: unsetting the '§' fieldseperator
478     IFS=$'\n'
479     }
480    
481    
482     ###################################################
483     # function install_characterdevices #
484     # install_characterdevices $PKGNAME #
485     ###################################################
486     install_characterdevices()
487     {
488     local pkgname="$1"
489     local pathto
490     local posix
491 niro 312 local major
492     local minor
493 niro 1209 local user
494     local group
495 niro 226 local IFS
496    
497     # sanity checks; abort if not given
498     [ -z "${pkgname}" ] && die "install_characterdevices() \$pkgname not given."
499    
500     # check needed global vars
501     [ -z "${BUILDDIR}" ] && die "install_characterdevices() \$BUILDDIR not set."
502    
503     [ ! -f ${BUILDDIR}/${pkgname}/.char ] && die "install_characterdevices() .char not found"
504    
505     # sets fieldseperator to "§" instead of " "
506     IFS=§
507    
508 niro 1209 while read pathto posix major minor user group
509 niro 226 do
510     [ -z "${pathto}" ] && continue
511 niro 1584 mqueryfeature "verbose" && echo -e "\t>>> CHAR: ${MROOT}${pathto}"
512 niro 226
513 niro 1271 mknod -m ${posix} "${MROOT}${pathto}" b "${major}" "${minor}"
514 niro 1211
515     # make it optional atm !!
516     if [[ ! -z ${user} ]] && [[ ! -z ${group} ]]
517     then
518     chown "${user}:${group}" "${MROOT}${pathto}"
519     fi
520 niro 226 done < ${BUILDDIR}/${pkgname}/.char
521    
522     # very important: unsetting the '§' fieldseperator
523     IFS=$'\n'
524     }
525    
526 niro 1209 ###################################################
527     # function install_fifos #
528     # install_fifos $PKGNAME #
529     ###################################################
530     install_fifos()
531     {
532     local pkgname="$1"
533     local pathto
534     local posix
535     local user
536     local group
537     local IFS
538 niro 226
539 niro 1209 # sanity checks; abort if not given
540     [ -z "${pkgname}" ] && die "install_fifos() \$pkgname not given."
541    
542     # check needed global vars
543     [ -z "${BUILDDIR}" ] && die "install_fifos() \$BUILDDIR not set."
544    
545 niro 1211 # make it optional atm !!
546     #[ ! -f ${BUILDDIR}/${pkgname}/.fifo ] && die "install_fifos() .fifo not found"
547     [ ! -f ${BUILDDIR}/${pkgname}/.fifo ] && return
548 niro 1209
549     # sets fieldseperator to "§" instead of " "
550     IFS=§
551    
552     while read pathto posix user group
553     do
554     [ -z "${pathto}" ] && continue
555 niro 1584 mqueryfeature "verbose" && echo -e "\t>>> FIFO: ${MROOT}${pathto}"
556 niro 1209
557     mkfifo -m "${posix}" "${MROOT}${pathto}"
558     chown "${user}:${group}" "${MROOT}${pathto}"
559     done < ${BUILDDIR}/${pkgname}/.fifo
560    
561     # very important: unsetting the '§' fieldseperator
562     IFS=$'\n'
563     }
564    
565    
566 niro 226 ###################################################
567     # function build_doinstall #
568     # build_doinstall $PKGNAME #
569 niro 1209 # NOTE: this is an wrapper to install packages #
570 niro 226 ###################################################
571     build_doinstall()
572     {
573     local pkgname="$1"
574    
575     # sanity checks; abort if not given
576     [ -z "${pkgname}" ] && die "build_doinstall() \$pkgname not given."
577 niro 1289
578 niro 226 # this is only a wrapper
579    
580     # NOTE:
581     # !! we use § as field seperator !!
582     # doing so prevent us to get errors by filenames with spaces
583    
584     # create a new mtime reference file
585     touch ${BUILDDIR}/${pkgname}/.mtime
586    
587     install_directories ${pkgname} || die "install directories ${pkgname}"
588     install_files ${pkgname} || die "install files ${pkgname}"
589     install_symlinks ${pkgname} || die "install symlinks ${pkgname}"
590     install_blockdevices ${pkgname} || die "install blockdevices ${pkgname}"
591     install_characterdevices ${pkgname} || die "install chardevices ${pkgname}"
592 niro 1209 install_fifos ${pkgname} || die "install fifos ${pkgname}"
593 niro 226 }
594    
595    
596     ###################################################
597     # function install_database_entry #
598     # install_database_entry $PKGNAME $PKGTYPE #
599     # PKGTYPE can be "virtual", "sources" or nothing #
600     ###################################################
601     install_database_entry()
602     {
603     local pcat
604     local pname
605     local pver
606     local pbuild
607     local pkgtype
608     local pkgname
609     local magefile
610     local dbrecorddir
611     local provide
612 niro 273 local i
613 niro 226
614     # very basic getops
615     for i in $*
616     do
617     case $1 in
618     --pcat|-c) shift; pcat="$1" ;;
619     --pname|-n) shift; pname="$1" ;;
620     --pver|-v) shift; pver="$1" ;;
621     --pbuild|-b) shift; pbuild="$1" ;;
622     --pkgname|-a) shift; pkgname="$1" ;;
623     --pkgtype|-t) shift; pkgtype="$1" ;;
624     esac
625     shift
626     done
627    
628     # sanity checks; abort if not given
629     [ -z "${pcat}" ] && die "install_database_entry() \$pcat not given."
630     [ -z "${pname}" ] && die "install_database_entry() \$pname not given."
631     [ -z "${pver}" ] && die "install_database_entry() \$pver not given."
632     [ -z "${pbuild}" ] && die "install_database_entry() \$pbuild not given."
633     [ -z "${pkgname}" ] && die "install_database_entry() \$pkgname not given."
634    
635     # check needed global vars
636     [ -z "${MAGEDIR}" ] && die "install_database_entry() \$MAGEDIR not set."
637     [ -z "${INSTALLDB}" ] && die "install_database_entry() \$INSTALLDB not set."
638    
639     # set needed vars
640     magefile="${MAGEDIR}/${pcat}/${pname}/${pname}-${pver}-${pbuild}.mage"
641     dbrecorddir="${MROOT}${INSTALLDB}/${pcat}/${pname}-${pver}-${pbuild}"
642    
643     # abort if mage file not exists
644     [ ! -f ${magefile} ] && die "install_database_entry() ${magefile} not exist."
645    
646     # add package to database
647     install -d ${dbrecorddir}
648    
649     # install mage-file to database
650     install -m 0644 -o root -g root ${magefile} ${dbrecorddir}
651    
652     # create fake file descriptors
653     # used by virtual and source packages
654 niro 1209 for i in .dirs .symlinks .files .pipes .char .fifo
655 niro 226 do
656     touch ${dbrecorddir}/${i}
657     done
658    
659     # put the category to database
660     echo ${pcat} > ${dbrecorddir}/.categorie
661    
662     # now install PKGTYPE specific files
663     case ${pkgtype} in
664     virtual) touch ${dbrecorddir}/.virtual ;;
665     sources) touch ${dbrecorddir}/.sources ;;
666     *)
667     # !move! .mtime to database (only mv modifies not the mtime!!)
668     mv ${BUILDDIR}/${pkgname}/.mtime ${dbrecorddir}/.mtime
669    
670     # normal packages needs these files
671     local i
672 niro 1209 for i in .char .dirs .files .pipes .symlinks .fifo
673 niro 226 do
674 niro 1214 # make .fifo optional atm
675     if [[ -f ${BUILDDIR}/${pkgname}/${i} ]]
676     then
677     install -m 0644 ${BUILDDIR}/${pkgname}/${i} ${dbrecorddir}/${i}
678     fi
679 niro 226 done
680     ;;
681     esac
682    
683     # last but not least register virtuals
684     provide="$(get_value_from_magefile PROVIDE ${magefile})"
685     if [ -n "${provide}" ]
686     then
687 niro 273 for i in ${provide}
688     do
689     virtuals_add "${i}" "${pcat}/${pname}"
690     done
691 niro 226 fi
692     }
693    
694    
695     ###################################################
696     # function remove_database_entry #
697     # remove_database_entry $PKGNAME $PKGTYPE #
698     # PKGTYPE can be "virtual", "sources" or nothing #
699     ###################################################
700     remove_database_entry()
701     {
702     local pcat
703     local pname
704     local pver
705     local pbuild
706     local magefile
707     local dbrecorddir
708     local provide
709 niro 273 local i
710 niro 226
711     # very basic getops
712     for i in $*
713     do
714     case $1 in
715     --pcat|-c) shift; pcat="$1" ;;
716     --pname|-n) shift; pname="$1" ;;
717     --pver|-v) shift; pver="$1" ;;
718     --pbuild|-b) shift; pbuild="$1" ;;
719     esac
720     shift
721     done
722    
723     # sanity checks; abort if not given
724     [ -z "${pcat}" ] && die "remove_database_entry() \$pcat not given."
725     [ -z "${pname}" ] && die "remove_database_entry() \$pname not given."
726     [ -z "${pver}" ] && die "remove_database_entry() \$pver not given."
727     [ -z "${pbuild}" ] && die "remove_database_entry() \$pbuild not given."
728    
729     # check needed global vars
730     [ -z "${INSTALLDB}" ] && die "remove_database_entry() \$INSTALLDB not set."
731    
732     # set needed vars
733     magefile="${MROOT}${INSTALLDB}/${pcat}/${pname}-${pver}-${pbuild}/${pname}-${pver}-${pbuild}.mage"
734     dbrecorddir="${MROOT}${INSTALLDB}/${pcat}/${pname}-${pver}-${pbuild}"
735    
736     # abort if mage file not exists
737     [ ! -f ${magefile} ] && die "remove_database_entry() ${magefile} not exist."
738    
739 niro 294 # remove virtuals only if no other exist
740 niro 2753 if [[ $(count_installed_pkgs --pcat=${pcat} --pname=${pname}) -le 1 ]]
741 niro 226 then
742 niro 294 # first unregister virtuals
743     provide="$(get_value_from_magefile PROVIDE ${magefile})"
744     if [ -n "${provide}" ]
745     then
746     for i in ${provide}
747     do
748     virtuals_del "${i}" "${pcat}/${pname}"
749     done
750     fi
751 niro 226 fi
752    
753     # removes database entry
754     if [ -d ${dbrecorddir} ]
755     then
756     rm -rf ${dbrecorddir}
757     fi
758     }
759    
760 niro 294 # get the number of installed packages
761     count_installed_pkgs()
762     {
763     local pcat
764     local pname
765     local pkg
766     local i
767 niro 226
768 niro 294 # very basic getops
769 niro 2753 for i in $@
770 niro 294 do
771 niro 2753 case ${i} in
772     --pcat*) pcat="${i#*=}" ;;
773     --pname*) pname="${i#*=}" ;;
774     esac
775 niro 294 done
776    
777     # sanity checks; abort if not given
778     [ -z "${pcat}" ] && die "pkg_count() \$pcat not given."
779     [ -z "${pname}" ] && die "pkg_count() \$pname not given."
780    
781     declare -i i=0
782     for pkg in $(get_uninstall_candidates --pcat ${pcat} --pname ${pname})
783     do
784     (( i++ ))
785     #echo "$i ${pkg}"
786     done
787    
788     # return the value
789     echo "${i}"
790     }
791    
792    
793 niro 226 ###################################################
794     # function compare_mtime #
795     # compare_mtime $pcat/$PKGNAME /path/to/file #
796     # #
797     # returns: #
798     # 0=delete me #
799     # 1=keep me #
800     # #
801     # compares mtime of given files in packages #
802     ###################################################
803     compare_mtime()
804     {
805     local pfull="$1"
806     local pathto="$2"
807     local mtime
808     local pcat
809     local x
810    
811     mtime="$(stat -c %Y ${MROOT}${INSTALLDB}/${pfull}/.mtime)"
812    
813 niro 1690 # no extra handlink for symlinks anymore as fix_mtime
814     # uses --no-dereference, compare directly
815     x=$(stat -c %Y "${MROOT}${pathto}")
816 niro 226
817     [[ ${mtime} = ${x} ]] && return 0
818    
819     # echo "keep me : ${pathto}"
820     return 1
821     }
822    
823    
824     ###################################################
825     # function remove_symlinks #
826     # remove_symlinks $PKGNAME #
827     ###################################################
828     remove_symlinks()
829     {
830     local pathto
831     local posix
832     local link
833     local mtime
834     local IFS
835     local retval
836     local pcat
837     local pname
838     local pver
839     local pbuild
840     local i
841     local pfull
842    
843     IFS=$'\n'
844    
845     # very basic getops
846     for i in $*
847     do
848     case $1 in
849     --pcat|-c) shift; pcat="$1" ;;
850     --pname|-n) shift; pname="$1" ;;
851     --pver|-v) shift; pver="$1" ;;
852     --pbuild|-b) shift; pbuild="$1" ;;
853     esac
854     shift
855     done
856    
857     # sanity checks; abort if not given
858     [ -z "${pcat}" ] && die "remove_symlinks() \$pcat not given."
859     [ -z "${pname}" ] && die "remove_symlinks() \$pname not given."
860     [ -z "${pver}" ] && die "remove_symlinks() \$pver not given."
861     [ -z "${pbuild}" ] && die "remove_symlinks() \$pbuild not given."
862     pfull="${pcat}/${pname}-${pver}-${pbuild}"
863    
864     # check needed global vars
865     [ -z "${BUILDDIR}" ] && die "remove_symlinks() \$BUILDDIR not set."
866    
867     [ ! -f ${MROOT}${INSTALLDB}/${pfull}/.symlinks ] && die "remove_symlinks() .symlinks not found"
868    
869     # sets fieldseperator to "§" instead of " "
870     IFS=§
871    
872     while read pathto posix link mtime
873     do
874     [ -z "${pathto}" ] && continue
875     if [ ! -L "${MROOT}${pathto}" ]
876     then
877 niro 1584 mqueryfeature "verbose" && \
878 niro 226 echo -e "${COLRED}! exist${COLDEFAULT} === LINK: ${MROOT}${pathto}"
879     continue
880     fi
881    
882     # *no* ${MROOT}, will be set internal
883     compare_mtime "${pfull}" "${pathto}"
884     retval=$?
885     # 0=delete me #
886     # 1=keep me #
887     case ${retval} in
888     0)
889 niro 1584 mqueryfeature "verbose" && echo -e "\t<<< LINK: ${MROOT}${pathto}"
890 niro 226 rm "${MROOT}${pathto}"
891     ;;
892    
893     1)
894 niro 1584 mqueryfeature "verbose" && \
895 niro 226 echo -e "${COLRED}! mtime${COLDEFAULT} === LINK: ${MROOT}${pathto}"
896     ;;
897     esac
898     done < ${MROOT}${INSTALLDB}/${pfull}/.symlinks
899    
900     # very important: unsetting the '§' fieldseperator
901     IFS=$'\n'
902     }
903    
904    
905     ###################################################
906     # function remove_files #
907     # remove_files $PKGNAME #
908     ###################################################
909     remove_files()
910     {
911     local pathto
912     local posix
913     local user
914     local group
915     local mtime
916     local md5sum
917     local IFS
918     local retval
919     local pcat
920     local pname
921     local pver
922     local pbuild
923     local i
924     local pfull
925    
926     IFS=$'\n'
927    
928     # very basic getops
929     for i in $*
930     do
931     case $1 in
932     --pcat|-c) shift; pcat="$1" ;;
933     --pname|-n) shift; pname="$1" ;;
934     --pver|-v) shift; pver="$1" ;;
935     --pbuild|-b) shift; pbuild="$1" ;;
936     esac
937     shift
938     done
939    
940     # sanity checks; abort if not given
941 niro 1209 [ -z "${pcat}" ] && die "remove_files() \$pcat not given."
942     [ -z "${pname}" ] && die "remove_files() \$pname not given."
943     [ -z "${pver}" ] && die "remove_files() \$pver not given."
944     [ -z "${pbuild}" ] && die "remove_files() \$pbuild not given."
945 niro 226 pfull="${pcat}/${pname}-${pver}-${pbuild}"
946    
947     # check needed global vars
948     [ -z "${BUILDDIR}" ] && die "remove_files() \$BUILDDIR not set."
949    
950     [ ! -f ${MROOT}${INSTALLDB}/${pfull}/.files ] && die "remove_files() .files not found"
951    
952     # sets fieldseperator to "§" instead of " "
953     IFS=§
954    
955     while read pathto posix user group mtime md5sum
956     do
957     [ -z "${pathto}" ] && continue
958    
959 niro 240 if [ ! -e "${MROOT}${pathto}" ]
960 niro 226 then
961 niro 1584 mqueryfeature "verbose" && \
962 niro 226 echo -e "${COLRED}! exist${COLDEFAULT} === FILE: ${MROOT}${pathto}"
963     continue
964     fi
965    
966     # *no* ${MROOT}, will be set internal
967     compare_mtime "${pfull}" "${pathto}"
968     retval=$?
969     # 0=delete me #
970     # 1=keep me #
971     case ${retval} in
972     0)
973 niro 280 # check if the file is config_protected
974     # ${MROOT} will automatically added if set !!
975     is_config_protected "${pathto}"
976     retval="$?"
977    
978 niro 942 # 0 - not protected #
979     # 1 - error #
980     # 2 - protected #
981     # 3 - protected but masked #
982     # 4 - protected but ignored #
983 niro 280
984     case ${retval} in
985     # file is not protected - delete it
986     0|3)
987 niro 1584 mqueryfeature "verbose" && echo -e "\t<<< FILE: ${MROOT}${pathto}"
988 niro 280 rm "${MROOT}${pathto}"
989     ;;
990    
991     # file is protected, do not delete
992     2)
993 niro 1584 if mqueryfeature "verbose"
994 niro 280 then
995     echo -en "${COLRED}"
996     echo -n "! prot "
997     echo -en "${COLDEFAULT}"
998     echo " === FILE: ${MROOT}${pathto}"
999     fi
1000     ;;
1001 niro 942
1002     # file is protected but ignored, delete the update/do nothing
1003     4)
1004 niro 1584 if mqueryfeature "verbose"
1005 niro 942 then
1006     echo -en "${COLRED}"
1007     echo -n "! ignr "
1008     echo -en "${COLDEFAULT}"
1009     echo " === FILE: ${MROOT}${pathto}"
1010     fi
1011     # simply do nothing here
1012     ;;
1013 niro 280 esac
1014 niro 226 ;;
1015     1)
1016 niro 1584 mqueryfeature "verbose" && \
1017 niro 226 echo -e "${COLRED}! mtime${COLDEFAULT} === FILE: ${MROOT}${pathto}"
1018     ;;
1019     esac
1020     done < ${MROOT}${INSTALLDB}/${pfull}/.files
1021    
1022     # very important: unsetting the '§' fieldseperator
1023     IFS=$'\n'
1024     }
1025    
1026    
1027     ###################################################
1028     # function remove_blockdevices #
1029     # remove_blockdevices $PKGNAME #
1030     ###################################################
1031     remove_blockdevices()
1032     {
1033     local pathto
1034     local posix
1035 niro 1209 local user
1036     local group
1037 niro 226 local IFS
1038     local pcat
1039     local pname
1040     local pver
1041     local pbuild
1042     local i
1043     local pfull
1044    
1045     IFS=$'\n'
1046    
1047     # very basic getops
1048     for i in $*
1049     do
1050     case $1 in
1051     --pcat|-c) shift; pcat="$1" ;;
1052     --pname|-n) shift; pname="$1" ;;
1053     --pver|-v) shift; pver="$1" ;;
1054     --pbuild|-b) shift; pbuild="$1" ;;
1055     esac
1056     shift
1057     done
1058    
1059     # sanity checks; abort if not given
1060 niro 1209 [ -z "${pcat}" ] && die "remove_blockdevices() \$pcat not given."
1061     [ -z "${pname}" ] && die "remove_blockdevices() \$pname not given."
1062     [ -z "${pver}" ] && die "remove_blockdevices() \$pver not given."
1063     [ -z "${pbuild}" ] && die "remove_blockdevices() \$pbuild not given."
1064 niro 226 pfull="${pcat}/${pname}-${pver}-${pbuild}"
1065    
1066     # check needed global vars
1067     [ -z "${BUILDDIR}" ] && die "remove_blockdevices() \$BUILDDIR not set."
1068    
1069     [ ! -f ${MROOT}${INSTALLDB}/${pfull}/.pipes ] && die "remove_blockdevices() .pipes not found"
1070    
1071     # sets fieldseperator to "§" instead of " "
1072     IFS=§
1073    
1074 niro 1209 while read pathto posix user group
1075 niro 226 do
1076     [ -z "${pathto}" ] && continue
1077    
1078 niro 1584 mqueryfeature "verbose" && echo -e "\t<<< PIPE: ${MROOT}${pathto}"
1079 niro 226 rm "${MROOT}${pathto}"
1080     done < ${MROOT}${INSTALLDB}/${pfull}/.pipes
1081    
1082     # very important: unsetting the '§' fieldseperator
1083     IFS=$'\n'
1084     }
1085    
1086    
1087     ###################################################
1088     # function remove_characterdevices #
1089     # remove_characterdevices $PKGNAME #
1090     ###################################################
1091     remove_characterdevices()
1092     {
1093     local pathto
1094     local posix
1095 niro 1209 local user
1096     local group
1097 niro 226 local IFS
1098     local pcat
1099     local pname
1100     local pver
1101     local pbuild
1102     local i
1103     local pfull
1104    
1105     IFS=$'\n'
1106    
1107     # very basic getops
1108     for i in $*
1109     do
1110     case $1 in
1111     --pcat|-c) shift; pcat="$1" ;;
1112     --pname|-n) shift; pname="$1" ;;
1113     --pver|-v) shift; pver="$1" ;;
1114     --pbuild|-b) shift; pbuild="$1" ;;
1115     esac
1116     shift
1117     done
1118    
1119     # sanity checks; abort if not given
1120 niro 1209 [ -z "${pcat}" ] && die "remove_characterdevices() \$pcat not given."
1121     [ -z "${pname}" ] && die "remove_characterdevices() \$pname not given."
1122     [ -z "${pver}" ] && die "remove_characterdevices() \$pver not given."
1123     [ -z "${pbuild}" ] && die "remove_characterdevices() \$pbuild not given."
1124 niro 226 pfull="${pcat}/${pname}-${pver}-${pbuild}"
1125    
1126     # check needed global vars
1127     [ -z "${BUILDDIR}" ] && die "remove_characterdevices() \$BUILDDIR not set."
1128    
1129     [ ! -f ${MROOT}${INSTALLDB}/${pfull}/.char ] && die "remove_characterdevices() .char not found"
1130    
1131     # sets fieldseperator to "§" instead of " "
1132     IFS=§
1133    
1134 niro 1209 while read pathto posix user group
1135 niro 226 do
1136     [ -z "${pathto}" ] && continue
1137    
1138 niro 1584 mqueryfeature "verbose" && echo -e "\t<<< CHAR: ${MROOT}${pathto}"
1139 niro 226 rm "${MROOT}${pathto}"
1140     done < ${MROOT}${INSTALLDB}/${pfull}/.char
1141    
1142     # very important: unsetting the '§' fieldseperator
1143     IFS=$'\n'
1144     }
1145    
1146    
1147     ###################################################
1148 niro 1209 # function remove_fifos #
1149     # remove_fifos $PKGNAME #
1150     ###################################################
1151     remove_fifos()
1152     {
1153     local pathto
1154     local posix
1155     local user
1156     local group
1157     local IFS
1158     local pcat
1159     local pname
1160     local pver
1161     local pbuild
1162     local i
1163     local pfull
1164    
1165     IFS=$'\n'
1166    
1167     # very basic getops
1168     for i in $*
1169     do
1170     case $1 in
1171     --pcat|-c) shift; pcat="$1" ;;
1172     --pname|-n) shift; pname="$1" ;;
1173     --pver|-v) shift; pver="$1" ;;
1174     --pbuild|-b) shift; pbuild="$1" ;;
1175     esac
1176     shift
1177     done
1178    
1179     # sanity checks; abort if not given
1180     [ -z "${pcat}" ] && die "remove_fifos() \$pcat not given."
1181     [ -z "${pname}" ] && die "remove_fifos() \$pname not given."
1182     [ -z "${pver}" ] && die "remove_fifos() \$pver not given."
1183     [ -z "${pbuild}" ] && die "remove_fifos() \$pbuild not given."
1184     pfull="${pcat}/${pname}-${pver}-${pbuild}"
1185    
1186     # check needed global vars
1187     [ -z "${BUILDDIR}" ] && die "remove_fifos() \$BUILDDIR not set."
1188    
1189 niro 1211 # make it optional atm !!
1190     #[ ! -f ${MROOT}${INSTALLDB}/${pfull}/.fifo ] && die "remove_fifos() .fifo not found"
1191     [ ! -f ${MROOT}${INSTALLDB}/${pfull}/.fifo ] && return
1192 niro 1209
1193     # sets fieldseperator to "§" instead of " "
1194     IFS=§
1195    
1196     while read pathto posix user group
1197     do
1198     [ -z "${pathto}" ] && continue
1199    
1200 niro 1584 mqueryfeature "verbose" && echo -e "\t<<< FIFO: ${MROOT}${pathto}"
1201 niro 1209 rm "${MROOT}${pathto}"
1202     done < ${MROOT}${INSTALLDB}/${pfull}/.fifo
1203    
1204     # very important: unsetting the '§' fieldseperator
1205     IFS=$'\n'
1206     }
1207    
1208    
1209     ###################################################
1210 niro 226 # function remove_direcories #
1211     # remove_direcories $PKGNAME #
1212     ###################################################
1213     remove_directories()
1214     {
1215     local pathto
1216     local posix
1217     local IFS
1218     local pcat
1219     local pname
1220     local pver
1221     local pbuild
1222     local i
1223     local pfull
1224    
1225     IFS=$'\n'
1226    
1227     # very basic getops
1228     for i in $*
1229     do
1230     case $1 in
1231     --pcat|-c) shift; pcat="$1" ;;
1232     --pname|-n) shift; pname="$1" ;;
1233     --pver|-v) shift; pver="$1" ;;
1234     --pbuild|-b) shift; pbuild="$1" ;;
1235     esac
1236     shift
1237     done
1238    
1239     # sanity checks; abort if not given
1240 niro 1209 [ -z "${pcat}" ] && die "remove_directories() \$pcat not given."
1241     [ -z "${pname}" ] && die "remove_directories() \$pname not given."
1242     [ -z "${pver}" ] && die "remove_directories() \$pver not given."
1243     [ -z "${pbuild}" ] && die "remove_directories() \$pbuild not given."
1244 niro 226 pfull="${pcat}/${pname}-${pver}-${pbuild}"
1245    
1246     # check needed global vars
1247     [ -z "${BUILDDIR}" ] && die "remove_directories() \$BUILDDIR not set."
1248    
1249     [ ! -f ${MROOT}${INSTALLDB}/${pfull}/.char ] && die "remove_directories() .dirs not found"
1250    
1251     # sets fieldseperator to "§" instead of " "
1252     IFS=§
1253    
1254 niro 240 # reversed order is mandatory !
1255     tac ${MROOT}${INSTALLDB}/${pfull}/.dirs | while read pathto posix
1256 niro 226 do
1257     [ -z "${pathto}" ] && continue
1258    
1259     if [ ! -d "${MROOT}${pathto}" ]
1260     then
1261 niro 1584 mqueryfeature "verbose" && \
1262 niro 226 echo -e "${COLRED}! exist${COLDEFAULT} === DIR: ${MROOT}${pathto}"
1263     continue
1264     fi
1265    
1266     # exclude .keep directories
1267     if [ -f "${MROOT}${pathto}/.keep" ]
1268     then
1269 niro 1584 mqueryfeature "verbose" && \
1270 niro 240 echo -e "${COLRED}! .keep${COLDEFAULT} === DIR: ${MROOT}${pathto}"
1271 niro 226 continue
1272     fi
1273    
1274     # monitors /etc/env.d -> env-rebuild
1275     [[ ${pathto} = /etc/env.d ]] && export MAGE_ENV_REBUILD=true
1276    
1277     # monitors /usr/share/info -> info-rebuild
1278     [[ ${pathto} = /usr/share/info ]] && export MAGE_INFO_REBUILD=true
1279    
1280     if rmdir "${MROOT}${pathto}" &> /dev/null
1281     then
1282 niro 1584 mqueryfeature "verbose" && echo -e "\t<<< DIR: ${MROOT}${pathto}"
1283 niro 226 else
1284 niro 1584 mqueryfeature "verbose" && \
1285 niro 226 echo -e "${COLRED}! empty${COLDEFAULT} === DIR: ${MROOT}${pathto}"
1286     fi
1287 niro 240 done
1288 niro 226
1289     # very important: unsetting the '§' fieldseperator
1290     IFS=$'\n'
1291     }
1292    
1293    
1294     ###################################################
1295     # function build_douninstall #
1296     # build_douninstall $PKGNAME #
1297 niro 1209 # NOTE: this is an wrapper to remove packages #
1298 niro 226 ###################################################
1299     build_douninstall()
1300     {
1301     local pcat
1302     local pname
1303     local pver
1304     local pbuild
1305     local i
1306    
1307     # very basic getops
1308     for i in $*
1309     do
1310     case $1 in
1311     --pcat|-c) shift; pcat="$1" ;;
1312     --pname|-n) shift; pname="$1" ;;
1313     --pver|-v) shift; pver="$1" ;;
1314     --pbuild|-b) shift; pbuild="$1" ;;
1315     esac
1316     shift
1317     done
1318    
1319     # sanity checks; abort if not given
1320     [ -z "${pcat}" ] && die "build_douninstall() \$pcat not given."
1321     [ -z "${pname}" ] && die "build_douninstall() \$pname not given."
1322     [ -z "${pver}" ] && die "build_douninstall() \$pver not given."
1323     [ -z "${pbuild}" ] && die "build_douninstall() \$pbuild not given."
1324    
1325     # this is only a wrapper
1326    
1327     # NOTE:
1328     # !! we use § as field seperator !!
1329     # doing so prevent us to get errors by filenames with spaces
1330    
1331 niro 1209 for i in symlinks files blockdevices characterdevices directories fifos
1332 niro 226 do
1333     remove_${i} \
1334     --pcat "${pcat}" \
1335     --pname "${pname}" \
1336     --pver "${pver}" \
1337     --pbuild "${pbuild}" \
1338     || die "remove ${i} ${pcat}/${pname}-${pver}-${pbuild}"
1339     done
1340     }
1341    
1342 niro 1549 # convertmirrors [uri]
1343     convertmirrors()
1344     {
1345     local uri="$1"
1346     local scheme
1347     local mirror
1348     local mirrors
1349     local addon
1350     local real_uri
1351     local output
1352    
1353     # needs
1354     [[ -z ${MIRRORS} ]] && die "convertmirrors(): no mirrors defined!"
1355     [[ -z ${SOURCEFORGE_MIRRORS} ]] && die "convertmirrors(): no sourceforge mirrors defined!"
1356     [[ -z ${GNU_MIRRORS} ]] && die "convertmirrors(): no gnu mirrors defined!"
1357     [[ -z ${GNOME_MIRRORS} ]] && die "convertmirrors(): no gnome mirrors defined!"
1358     [[ -z ${KDE_MIRRORS} ]] && die "convertmirrors(): no kde mirrors defined!"
1359    
1360     # check known uri schemes
1361     case ${uri} in
1362     http://*|https://*|ftp://*|ftps://*) mirrors="" ;;
1363     mirror://*) mirrors="${MIRRORS}"; scheme="mirror://"; addon="/sources" ;;
1364     package://*) mirrors="${MIRRORS}"; scheme="package://"; addon="/${PACKAGES_SERVER_PATH}" ;;
1365     gnu://*) mirrors="${GNU_MIRRORS}"; scheme="gnu://" ;;
1366     sourceforge://*) mirrors="${SOURCEFORGE_MIRRORS}"; scheme="sourceforge://" ;;
1367     gnome://*) mirrors="${GNOME_MIRRORS}"; scheme="gnome://" ;;
1368     kde://*) mirrors="${KDE_MIRRORS}"; scheme="kde://" ;;
1369     *) die "convertmirror(): unsupported uri scheme in '${uri}'!" ;;
1370     esac
1371    
1372     if [[ ! -z ${mirrors} ]]
1373     then
1374     for mirror in ${mirrors}
1375     do
1376     # add a whitespace to the output
1377     [[ -z ${output} ]] || output+=" "
1378     output+="${mirror}${addon}/${uri/${scheme}/}"
1379     done
1380     else
1381 niro 2270 output="${uri}"
1382 niro 1549 fi
1383    
1384     echo "${output}"
1385     }
1386    
1387     mdownload()
1388     {
1389     local i
1390     local uri
1391     local real_uris
1392     local mirror
1393     local outputfile
1394     local outputdir
1395     local retval
1396     local wget_opts
1397    
1398     # very basic getops
1399     for i in $*
1400     do
1401     case $1 in
1402     --uri|-u) shift; uri="$1" ;;
1403     --dir|-d) shift; outputdir="$1" ;;
1404     esac
1405     shift
1406     done
1407    
1408     # sanity checks; abort if not given
1409     [[ -z ${uri} ]] && die "mdownload(): no uri given!"
1410     [[ -z ${outputdir} ]] && die "mdownload(): no dir given!"
1411    
1412     # convert mirrored uris to the real ones
1413     real_uris="$(convertmirrors ${uri})"
1414    
1415     # verbose or not
1416 niro 1626 mqueryfeature "!verbose" && wget_opts+=" --quiet"
1417 niro 1549
1418     # filter wget options if busybox was found
1419 niro 1626 wget_opts+=" $(busybox_filter_wget_options ${WGET_FETCH_OPTIONS})"
1420 niro 1549
1421     # create outputdir
1422     [[ ! -d ${outputdir} ]] && install -d "${outputdir}"
1423    
1424     for mirror in ${real_uris}
1425     do
1426     # get the name of the output file
1427     outputfile="${mirror##*/}"
1428    
1429     wget ${wget_opts} --output-document="${outputdir}/${outputfile}" "${mirror}"
1430     retval="$?"
1431     if [[ ${retval} = 0 ]]
1432     then
1433     break
1434     else
1435     continue
1436     fi
1437     done
1438    
1439     # return wget retval
1440     return "${retval}"
1441     }
1442    
1443 niro 226 # fetch_packages /path/to/mage/file1 /path/to/mage/file2
1444     fetch_packages()
1445     {
1446 niro 1549 local i
1447 niro 226 local list="$@"
1448 niro 2271 local pkgname
1449     local pkgfile
1450 niro 2272 local pcat
1451     local pname
1452 niro 226 local mirr
1453     local magefile
1454     local md5file
1455     local opt
1456     local count_current
1457     local count_total
1458 niro 1273 local wget_opts
1459 niro 2272 local fetching
1460 niro 226
1461 niro 419 [ -z "${MIRRORS}" ] && die "You have no mirrors defined. Please edit your ${MAGERC}."
1462 niro 226
1463 niro 1273 # filter wget command if busybox was found
1464     wget_opts="$(busybox_filter_wget_options ${WGET_FETCH_OPTIONS})"
1465    
1466 niro 226 # get count of total packages
1467     declare -i count_current=0
1468     declare -i count_total=0
1469    
1470     for i in ${list}; do (( count_total++ )); done
1471    
1472     for magefile in ${list}
1473     do
1474 niro 2271 pkgname="$(get_value_from_magefile PKGNAME ${magefile})"
1475     pkgfile="${pkgname}.${PKGSUFFIX}"
1476 niro 226 pkgtype="$(get_value_from_magefile PKGTYPE ${magefile})"
1477    
1478 niro 2272 pcat=$(magename2pcat ${magefile})
1479     pname=$(magename2pname ${magefile})
1480     md5file="${MAGEDIR}/${pcat}/${pname}/md5/${pkgname}.md5"
1481    
1482 niro 226 (( count_current++ ))
1483 niro 2271 xtitle "[ (${count_current}/${count_total}) Fetching ${pkgfile} ]"
1484 niro 226
1485     # abort on virtual pkg
1486     if [[ ${pkgtype} = virtual ]]
1487     then
1488     echo -ne " ${COLBLUE}---${COLDEFAULT}"
1489 niro 2271 echo " !fetch virtual (${count_current}/${count_total}): ${pkgname} ... "
1490 niro 226 continue
1491     fi
1492    
1493     # abort on sources pkg
1494     if [[ ${pkgtype} = sources ]]
1495     then
1496     echo -ne " ${COLBLUE}---${COLDEFAULT}"
1497 niro 2271 echo " !fetch sources (${count_current}/${count_total}): ${pkgname} ... "
1498 niro 226 continue
1499     fi
1500    
1501 niro 2272 # check if FETCHING is required
1502     if [ ! -f "${md5file}" ]
1503 niro 226 then
1504 niro 2272 fetching=true
1505     else
1506     if mchecksum --rundir "${PKGDIR}" --file "${md5file}" --method md5 &> /dev/null
1507     then
1508     # md5's ok, no fetching required
1509     fetching=false
1510     else
1511     fetching=true
1512     fi
1513     fi
1514    
1515     if [[ ${fetching} = false ]]
1516     then
1517 niro 226 echo -ne " ${COLBLUE}***${COLDEFAULT}"
1518 niro 2271 echo " fetch complete (${count_current}/${count_total}): ${pkgfile} ... "
1519 niro 226 continue
1520 niro 2272 else
1521     echo -ne " ${COLBLUE}***${COLDEFAULT}"
1522     echo -e " fetching (${count_current}/${count_total}): ${pkgfile} ... "
1523     mdownload --uri "package://${pkgfile}" --dir "${PKGDIR}" || die "Could not download ${pkgfile}"
1524 niro 226 fi
1525    
1526 niro 2272 # sanity check, not really needed but to be sure
1527 niro 2271 if [ ! -f ${PKGDIR}/${pkgfile} ]
1528 niro 226 then
1529 niro 2271 die "Package '${pkgfile}' after download not found in '${PKGDIR}'"
1530 niro 226 fi
1531     done
1532    
1533     # add a crlf for a better view
1534     if [ ${count_total} -gt 1 ]; then echo; fi
1535     }
1536    
1537     syncmage()
1538     {
1539     if [ -z "${RSYNC}" ]
1540     then
1541 niro 419 die "You have no rsync-mirrors defined. Please edit your ${MAGERC}."
1542 niro 226 fi
1543    
1544     local i
1545     for i in ${RSYNC}
1546     do
1547 niro 386 rsync ${RSYNC_FETCH_OPTIONS} ${i} ${MAGEDIR}
1548 niro 226 if [[ $? = 0 ]]
1549     then
1550     break
1551     else
1552     continue
1553     fi
1554     done
1555    
1556     # clean up backup files (foo~)
1557 niro 1438 find ${MAGEDIR} -name \*~ -exec rm '{}' ';'
1558 niro 226
1559 niro 966 # check if a newer mage version is available
1560 niro 226 is_newer_mage_version_available
1561     }
1562    
1563 niro 739 syncmage_tarball()
1564     {
1565     local latest_tarball
1566 niro 1083 local latest_md5
1567 niro 739 local temp="$(mktemp -d)"
1568     local mirr mymirr
1569 niro 1087 local opt
1570 niro 1273 local tar_opts
1571 niro 1293 local wget_opts
1572 niro 739
1573 niro 1083 # try to get the md5 marked as latest on the server
1574     latest_md5="mage-latest.md5"
1575    
1576 niro 739 # try to get the tarball marked as latest on the server
1577     latest_tarball="mage-latest.tar.bz2"
1578    
1579 niro 1293 # filter wget command if busybox was found
1580     wget_opts="$(busybox_filter_wget_options ${WGET_FETCH_OPTIONS})"
1581    
1582 niro 739 for mirr in ${MIRRORS}
1583     do
1584 niro 1675 # path without distribution
1585     # (only for stable|testing|unstable and not DISTROTAG)
1586     case ${mirr##*/} in
1587     stable|testing|unstable) mymirr="${mirr%/*}";;
1588     *) mymirr="${mirr}";;
1589     esac
1590 niro 739
1591     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
1592 niro 1083 echo "fetching latest md5 from ${mymirr} ..."
1593 niro 1584 mqueryfeature "!verbose" && opt="--quiet"
1594 niro 1083 wget \
1595 niro 1293 ${wget_opts} \
1596 niro 1083 --directory-prefix=${temp} \
1597 niro 1087 ${opt} ${mymirr}/rsync/tarballs/${latest_md5}
1598 niro 1083
1599     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
1600 niro 739 echo "fetching latest tarball from ${mymirr} ..."
1601     wget \
1602 niro 1293 ${wget_opts} \
1603 niro 739 --directory-prefix=${temp} \
1604 niro 1087 ${opt} ${mymirr}/rsync/tarballs/${latest_tarball}
1605 niro 739 if [[ $? = 0 ]]
1606     then
1607     break
1608     else
1609     continue
1610     fi
1611     done
1612    
1613     if [[ -f ${temp}/${latest_tarball} ]]
1614     then
1615 niro 1083 # check md5
1616     if [[ ! -f ${temp}/${latest_md5} ]]
1617     then
1618     die "md5 is missing ... aborting"
1619     else
1620 niro 1087 echo -ne "${COLBLUE} --- ${COLDEFAULT}"
1621     echo -n "checking md5sum... "
1622 niro 1652 mchecksum --rundir "${temp}" --file "${latest_md5}" --method md5 || die "md5 for ${latest_tarball} failed"
1623 niro 1083 fi
1624    
1625 niro 739 if [[ -d ${MAGEDIR} ]]
1626     then
1627     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
1628     echo "cleaning old mage-tree ${MAGEDIR}..."
1629 niro 1654 # honor mountpoints and empty dirs
1630     if mountpoint -q ${MAGEDIR}
1631     then
1632     if ! mcheckemptydir ${MAGEDIR}
1633     then
1634 niro 1963 find ${MAGEDIR} -mindepth 1 -maxdepth 1 | xargs --no-run-if-empty rm -r
1635 niro 1654 fi
1636     else
1637     rm -rf ${MAGEDIR}
1638     fi
1639 niro 739 fi
1640    
1641 niro 1273 if need_busybox_support tar
1642     then
1643     tar_opts="xjf"
1644     else
1645     tar_opts="xjmf"
1646     fi
1647    
1648 niro 739 echo -ne "${COLBLUE} --- ${COLDEFAULT}"
1649     echo "updating mage-tree from tarball ..."
1650     # unpack in dirname of MAGEDIR, as the tarball has already the mage
1651 niro 1273 tar ${tar_opts} ${temp}/${latest_tarball} -C ${MAGEDIR%/*} || die "Unpacking tarball"
1652 niro 739
1653     if [[ -d ${temp} ]]
1654     then
1655     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
1656 niro 972 echo "cleaning temp-files ..."
1657 niro 739 rm -rf ${temp}
1658     fi
1659 niro 966
1660     # check if a newer mage version is available
1661     is_newer_mage_version_available
1662 niro 739 else
1663     die "Could not fetch the latest tarball ... aborting"
1664     fi
1665     }
1666    
1667 niro 226 cleanpkg()
1668     {
1669     if [ -d "${PKGDIR}" ]
1670     then
1671     echo -n "Removing downloaded packages... "
1672     rm -rf ${PKGDIR}/*
1673     echo "done."
1674     fi
1675     }
1676    
1677 niro 1650 # unused?
1678     #
1679     # # cuts full pathnames or versionized names down to basename
1680     # choppkgname()
1681     # {
1682     # #we want this only if full name was used
1683     # if [ -n "$(echo ${MAGENAME}|fgrep .mage)" ]
1684     # then
1685     # #cuts ARCH and PBUILD
1686     # #ARCH comes from ${MAGERC}
1687     # MAGENAME=$(echo ${MAGENAME} |sed -e "s:-${ARCH}$(print_distrotag)-r*.::g")
1688     #
1689     # #cuts version number
1690     # MAGENAME=$(basename ${MAGENAME%-*} .mage)
1691     # fi
1692     # }
1693 niro 226
1694    
1695     # get_categorie $PNAME, returns CATEGORIE
1696     # $1=pname
1697     # ret 0=ok, 1=not_found
1698     pname2pcat()
1699     {
1700     local pname="$1"
1701     local repo="$2"
1702     local pcat
1703     local categorie
1704    
1705     for pcat in ${MAGEDIR}/*
1706     do
1707     if [ -d ${pcat}/${pname} ]
1708     then
1709     categorie=$(basename ${pcat})
1710     fi
1711     done
1712    
1713     echo "${categorie}"
1714     }
1715    
1716     # get_highest_magefile ${PCAT} ${PNAME}
1717 niro 2811 # returns $HIGHEST_MAGEFILE
1718 niro 226 get_highest_magefile()
1719     {
1720 niro 2811 local pcat="$1"
1721     local pname="$2"
1722 niro 226
1723 niro 2811 ${MLIBDIR}/highest_magefile ${MAGEDIR}/${pcat}/${pname}
1724 niro 226 return 0
1725     }
1726    
1727     ###################################################
1728     # function is_config_protected #
1729     # is_config_protected /path/to/file #
1730     # #
1731     # returns: #
1732     # 0 - not protected #
1733     # 1 - error #
1734     # 2 - protected #
1735     # 3 - protected but masked #
1736 niro 942 # 4 - protected but ignored #
1737 niro 226 # #
1738     ###################################################
1739     is_config_protected()
1740     {
1741     local EXPFILE
1742     local TEST
1743     local PROTECTED
1744     local IFS
1745 niro 942 local i
1746     local x
1747 niro 226
1748     EXPFILE="${MROOT}$1"
1749    
1750     # file does not exist; it can be written
1751 niro 451 [[ ! -e ${EXPFILE} ]] && return 0
1752 niro 226
1753     # to be safe; it may be '§'
1754     IFS=' '
1755    
1756 niro 942 # check if config protected
1757 niro 226 for i in ${CONFIG_PROTECT}
1758     do
1759 niro 942 # only replace $i in the beginning of the variable
1760 niro 226 TEST="${EXPFILE/#${MROOT}${i}/Protected}"
1761 niro 451 if [[ ${TEST} != ${EXPFILE} ]]
1762 niro 226 then
1763 niro 942 # file is config proteced
1764 niro 226 PROTECTED=TRUE
1765    
1766 niro 942 # check if not masked
1767 niro 226 for x in ${CONFIG_PROTECT_MASK}
1768     do
1769     TEST="${EXPFILE/#${MROOT}${x}/Protect_Masked}"
1770 niro 451 if [[ ${TEST} != ${EXPFILE} ]]
1771 niro 226 then
1772     PROTECTED=MASKED
1773     fi
1774     done
1775 niro 942
1776     # check if not ignored
1777     for x in ${CONFIG_PROTECT_IGNORE}
1778     do
1779     TEST="${EXPFILE/#${MROOT}${x}/Protect_Ignored}"
1780     if [[ ${TEST} != ${EXPFILE} ]]
1781     then
1782     PROTECTED=IGNORED
1783     fi
1784     done
1785 niro 226 fi
1786     done
1787    
1788     unset IFS
1789    
1790     case ${PROTECTED} in
1791     TRUE)
1792     #echo "I'm protected"
1793     return 2
1794     ;;
1795     MASKED)
1796     #echo "I'm protected, but masked - delete me"
1797     return 3
1798     ;;
1799 niro 942 IGNORED)
1800     #echo "I'm protected, but ignored - keep me, del update"
1801     return 4
1802     ;;
1803 niro 226 *)
1804     #echo "delete me"
1805     return 0
1806     ;;
1807     esac
1808     }
1809    
1810    
1811     ###################################################
1812     # function count_protected_files #
1813     # count_protected_files /path/to/file #
1814     # #
1815     # note: prints number of protected files #
1816     # exp: 0012 #
1817     ###################################################
1818     count_protected_files()
1819     {
1820 niro 603 local file="$1"
1821     local dirname="${file%/*}"
1822     local filename="${file##*/}"
1823     local count
1824     local output
1825 niro 1758 local oldprotected
1826 niro 603 local i
1827 niro 1758 local x
1828 niro 603
1829 niro 1758 # hack; do not honor a global set IFS like '§'
1830     local IFS
1831 niro 603
1832 niro 1758 count=0
1833    
1834 niro 603 # check if there are already protected files
1835 niro 1758 for oldprotected in $(find ${dirname} -iname "._cfg????_${filename}" |
1836 niro 603 sed -e "s:\(^.*/\)\(._cfg*_\)\(/.*$\):\1\2\3\%\2\%\3:" |
1837     sort -t'%' -k3 -k2 | cut -f1 -d'%')
1838     do
1839 niro 1758 count="$(echo ${oldprotected} | sed 's:.*\/._cfg\(.*\)_.*:\1:')"
1840 niro 603 done
1841    
1842 niro 1962 # convert 0001 -> 1; 0120 -> 120 etc
1843     # use bash internal base functions to this task
1844     x="$((10#${count}))"
1845 niro 1758 for (( i=0; i<x; i++ ))
1846     do
1847     if [[ ${count:${i}:1} != 0 ]]
1848     then
1849     count="${count:${i}}"
1850     break
1851     fi
1852     done
1853    
1854 niro 1762 count="$(( ${count}+1 ))"
1855 niro 1758
1856 niro 603 # fill output up with zeros
1857     for (( i=${#count}; i < 4; i++ )); do output="${output}0"; done
1858     output="${output}${count}"
1859    
1860     echo "${output}"
1861 niro 226 }
1862    
1863     # call with
1864     # 'get_uninstall_candidates (--pcat cat --protected pcat/pfull) --pname PNAME'
1865     # returns /path/to/magefile(s)
1866     get_uninstall_candidates()
1867     {
1868     local search_pname
1869     local pkg
1870     local pcat
1871     local pname
1872     local pver
1873     local pbuild
1874     local list
1875     local pcatdir
1876     local protected
1877 niro 449 local i
1878 niro 226
1879     # very basic getops
1880     for i in $*
1881     do
1882     case $1 in
1883     --pcat|-c) shift; pcatdir="$1" ;;
1884     --pname|-n) shift; search_pname="$1" ;;
1885     --protected|-p) shift; protected="$1" ;;
1886     esac
1887     shift
1888     done
1889    
1890 niro 329 # it's not good to complain here about empty pnames; better to continue later anyway
1891     # # sanity checks; abort if not given
1892     # [ -z "${search_pname}" ] && die "get_uninstall_candidates() \$search_pname not given."
1893 niro 226
1894    
1895     # check needed global vars
1896     [ -z "${INSTALLDB}" ] && die "get_uninstall_candidates() \$INSTALLDB not set."
1897    
1898     # set pcatdir to '*' if empty
1899 niro 329 [ -z "${pcatdir}" ] && pcatdir='*'
1900 niro 226
1901     for pkg in ${MROOT}${INSTALLDB}/${pcatdir}/*
1902     do
1903     # abort if not a dir
1904     [ ! -d ${pkg} ] && continue
1905    
1906     pname="$(magename2pname ${pkg})"
1907    
1908     if [[ ${search_pname} = ${pname} ]]
1909     then
1910     pcat="$(magename2pcat ${pkg} installdb)"
1911     pver="$(magename2pver ${pkg})"
1912     pbuild="$(magename2pbuild ${pkg})"
1913    
1914     # exclude proteced
1915     [[ ${protected} = ${pcat}/${pname}-${pver}-${pbuild} ]] && continue
1916    
1917     list="${list} ${pcat}/${pname}-${pver}-${pbuild}"
1918     fi
1919     done
1920    
1921     echo "${list}"
1922     }
1923    
1924     # reads virtualdb file
1925     #$1 = virtualname; $2 commands: showpkgs, showline
1926     #return 0 == installed -> shows installed pkg as well
1927     #return 1 == not installed
1928     virtuals_read()
1929     {
1930     local virtualname="$1"
1931     local command="$2"
1932     local virtline
1933     local line x i
1934    
1935     # parse file to get virtual_name line
1936     IFS=$'\n'
1937     for line in $(< ${MROOT}${VIRTUALDB_FILE})
1938     do
1939     IFS=$' '
1940     for x in ${line}
1941     do
1942     if [[ ${x} = ${virtualname} ]]
1943     then
1944     virtline="${line}"
1945     [[ ${command} = showline ]] && echo "${line}"
1946     fi
1947     done
1948     IFS=$'\n'
1949     done
1950    
1951     unset IFS
1952    
1953     # now read the packages linked to VIRTUAL_NAME and output them
1954     if [ -n "${virtline}" ]
1955     then
1956     if [[ ${command} = showpkgs ]]
1957     then
1958     declare -i x=0
1959     for i in ${virtline}
1960     do
1961     if [ ${x} -ge 1 ]
1962     then
1963     echo "${i}"
1964     fi
1965     ((x++))
1966     done
1967     fi
1968     return 0
1969     fi
1970     return 1
1971     }
1972    
1973    
1974     #add pkg to virtualdb
1975     # $1 == virtualname $2= pkgname
1976     # retvals: 0=ok,added; 1=error; 3=pkg already in virtual
1977     virtuals_add()
1978     {
1979     local virtualname="$1"
1980     local pkgname="$2"
1981     local oldline
1982     local line i
1983     local installed_file
1984 niro 273 local OLDIFS
1985 niro 226
1986     if virtuals_read ${virtualname}
1987     then
1988 niro 329 # make sure ${PKG_NAME} is *not* in ${VIRTUAL_NAME} already
1989 niro 226 for i in $(virtuals_read ${virtualname} showpkgs)
1990     do
1991     if [[ ${i} = ${pkgname} ]]
1992     then
1993     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
1994     echo "${pkgname} already linked as ${virtualname} ..."
1995     #return 3
1996     return 0
1997     fi
1998     done
1999    
2000     echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2001     echo "updating ${virtualname} entry with ${pkgname} ..."
2002     oldline="$(virtuals_read ${virtualname} showline)"
2003    
2004     # make a backup
2005     mv ${MROOT}${VIRTUALDB_FILE} ${MROOT}${VIRTUALDB_FILE}.old
2006    
2007 niro 273 OLDIFS="${IFS}"
2008 niro 226 IFS=$'\n'
2009     for line in $(< ${MROOT}${VIRTUALDB_FILE}.old)
2010     do
2011     # if the right line, append ${pkgname}, else do nothing
2012     if [[ ${line} = ${oldline} ]]
2013     then
2014     echo "${line} ${pkgname}" >> ${MROOT}${VIRTUALDB_FILE}
2015     else
2016     echo "${line}" >> ${MROOT}${VIRTUALDB_FILE}
2017     fi
2018     done
2019 niro 273 # unset IFS
2020     IFS="${OLDIFS}"
2021 niro 226 else
2022 niro 273 echo -ne "${COLBLUE} >>> ${COLDEFAULT}"
2023 niro 226 echo "register ${pkgname} as ${virtualname} ..."
2024     echo "${virtualname} ${pkgname}" >> ${MROOT}${VIRTUALDB_FILE}
2025     fi
2026    
2027     return 0
2028     }
2029    
2030     #deletes pakages from virtual database
2031     #$1 virtualname; $2 pkgname
2032 niro 1209 virtuals_del()
2033     {
2034 niro 226
2035 niro 273 local virtualname="$1"
2036     local pkgname="$2"
2037     local oldline
2038     local method
2039     local line i x
2040     local pkg_installed
2041     local OLDIFS
2042    
2043     # first check if exists
2044     if virtuals_read ${virtualname}
2045 niro 226 then
2046 niro 273 # get method -> delall or update and check if ${PKG_NAME} exists in ${VIRTUAL_NAME}
2047 niro 226 declare -i x=0
2048 niro 273 for i in $(virtuals_read ${virtualname} showpkgs)
2049 niro 226 do
2050 niro 273 if [[ ${i} = ${pkgname} ]]
2051 niro 226 then
2052 niro 273 pkg_installed=true
2053 niro 226 fi
2054     ((x++))
2055     done
2056 niro 273
2057     # abort if not installed
2058     if [[ ${pkg_installed} != true ]]
2059 niro 226 then
2060 niro 273 echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2061     echo "${pkgname} does not exists in ${virtualname}."
2062 niro 226 return 0
2063     fi
2064 niro 273
2065 niro 226 if [ ${x} -ge 2 ]
2066     then
2067 niro 273 method=update
2068 niro 226 else
2069 niro 273 method=delall
2070 niro 226 fi
2071 niro 273
2072     # get the complete line
2073     oldline="$(virtuals_read ${virtualname} showline)"
2074    
2075     # make a backup of the db
2076 niro 226 mv ${VIRTUALDB_FILE} ${VIRTUALDB_FILE}.old
2077 niro 273
2078     # parse virtualdb
2079     OLDIFS="${IFS}"
2080 niro 226 IFS=$'\n'
2081     for line in $(< ${VIRTUALDB_FILE}.old)
2082     do
2083 niro 273 if [[ ${line} = ${oldline} ]]
2084 niro 226 then
2085     #delall or update?
2086 niro 273 case ${method} in
2087 niro 226 update)
2088 niro 273 echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2089     echo "Unlinking ${pkgname} from ${virtualname} in virtual database ..."
2090     # del PKG_NAME from line
2091     echo "${line/ ${pkgname}/}" >> ${VIRTUALDB_FILE}
2092 niro 226 ;;
2093     delall)
2094 niro 273 echo -ne "${COLBLUE} <<< ${COLDEFAULT}"
2095     echo "Deleting ${virtualname} in virtual database ..."
2096     # continue; do not write anything
2097 niro 226 continue
2098     ;;
2099     esac
2100     else
2101     echo "${line}" >> ${VIRTUALDB_FILE}
2102     fi
2103     done
2104 niro 273 # unset IFS
2105     IFS="${OLDIFS}"
2106 niro 226 else
2107 niro 273 echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2108     echo "${virtualname} does not exists in virtual database."
2109 niro 226 fi
2110     }
2111    
2112     # gets real pkgname from virtuals.default
2113     #$1=VIRTUAL_NAME; returns PKG_NAME
2114     default_virtualname_to_pkgname()
2115     {
2116     local VIRTUAL_NAME PKG_NAME db_virtualname db_pkgname
2117    
2118     VIRTUAL_NAME=$1
2119    
2120     while read db_virtualname db_pkgname
2121     do
2122     if [ "${db_virtualname}" == "${VIRTUAL_NAME}" ]
2123     then
2124     PKG_NAME="${db_pkgname}"
2125     fi
2126     done << EOF
2127     $(< ${VIRTUALDB_DEFAULTS})
2128     EOF
2129    
2130     if [ -n "${PKG_NAME}" ]
2131     then
2132     echo "${PKG_NAME}"
2133     fi
2134     }
2135    
2136     minclude()
2137     {
2138     local i
2139    
2140 niro 437 if [[ -n $* ]]
2141 niro 226 then
2142 niro 437 for i in $*
2143 niro 226 do
2144 niro 1584 mqueryfeature "debug" && \
2145 niro 226 echo "--- Including ${MAGEDIR}/include/${i}.minc"
2146     source ${MAGEDIR}/include/${i}.minc
2147     done
2148 niro 1584 mqueryfeature "debug" && echo
2149 niro 226 fi
2150     }
2151    
2152     sminclude()
2153     {
2154     local i
2155    
2156 niro 437 if [[ -n $* ]]
2157 niro 226 then
2158 niro 437 for i in $*
2159 niro 226 do
2160 niro 2364 [[ ${SILENT} = 1 ]] || echo "--- Including ${SMAGESCRIPTSDIR}/include/${i}.sminc"
2161 niro 226 source ${SMAGESCRIPTSDIR}/include/${i}.sminc
2162     done
2163 niro 2364 [[ ${SILENT} = 1 ]] || echo
2164 niro 226 fi
2165     }
2166    
2167     # checks if an newer mage version is available
2168     is_newer_mage_version_available()
2169     {
2170     local newest_mage
2171     local installed_mage
2172    
2173 niro 252 newest_mage="$(basename $(get_highest_magefile app-mage mage) .mage)"
2174 niro 226 installed_mage="$(magequery -n mage | cut -d' ' -f5)"
2175    
2176     if [[ ${newest_mage} > ${installed_mage} ]]
2177     then
2178     echo
2179     echo -en ${COLRED}"An update for your packetmanager is available. "${COLDEFAULT}
2180     echo -e ${COLBLUE}"[ ${newest_mage} ]"${COLDEFAULT}
2181     echo "It is recommened to install this newer version"
2182 niro 373 echo "or your current system installation may break."
2183 niro 226 echo
2184     echo -en "Please update mage by running "
2185     echo -e ${COLGREEN}"'mage install mage'"${COLDEFAULT}
2186     echo
2187     fi
2188     }
2189    
2190     # returns pname from pkgname
2191     # pkgname2pname $PKGNAME
2192     pkgname2pname()
2193     {
2194     local pname
2195    
2196     pname="${1%-*-*-*}"
2197     echo "${pname}"
2198     }
2199    
2200     # returns pver from pkgname
2201     # pkgname2pver $PKGNAME
2202     pkgname2pver()
2203     {
2204     local i pver
2205    
2206     i="${1/$(pkgname2pname $1)-/}"
2207     pver="${i%-*-*}"
2208     echo "${pver}"
2209     }
2210    
2211     # returns pbuild from pkgname
2212     # pkgname2pbuild $PKGNAME
2213     pkgname2pbuild()
2214     {
2215     local pbuild
2216    
2217     pbuild="${1##*-}"
2218     echo "${pbuild}"
2219     }
2220    
2221     # returns parch from pkgname
2222     # pkgname2parch $PKGNAME
2223     pkgname2parch()
2224     {
2225     local i x parch
2226    
2227     i="${1%-*-*}-"
2228     x="${1%-*}"
2229     parch="${x/${i}/}"
2230     echo "${parch}"
2231     }
2232    
2233     # returns pname from magename
2234     # magename2pname /PATH/TO/MAGE/FILE
2235     magename2pname()
2236     {
2237     local i pname
2238    
2239     i="$(basename $1 .mage)"
2240     pname="${i%-*-*}"
2241     echo "${pname}"
2242     }
2243    
2244     # returns pver from magename
2245     # magename2pver /PATH/TO/MAGE/FILE
2246     magename2pver()
2247     {
2248     local i pver
2249    
2250     i="$(basename $1 .mage)"
2251     i="${i/$(magename2pname $1)-/}"
2252     pver="${i%-*}"
2253     echo "${pver}"
2254     }
2255    
2256     # returns pbuild from magename
2257     # magename2pbuild /PATH/TO/MAGE/FILE
2258     magename2pbuild()
2259     {
2260     local i pbuild
2261    
2262     i="$(basename $1 .mage)"
2263     pbuild="${i##*-}"
2264     echo "${pbuild}"
2265     }
2266    
2267     # returns pcat from magename
2268     # magename2pcat /PATH/TO/MAGE/FILE
2269     magename2pcat()
2270     {
2271     local i pcat
2272    
2273     if [[ ${2} = installdb ]]
2274     then
2275     # go 1 dir back
2276     i="${1%/*}"
2277     else
2278     # go 2 dirs back
2279     i="${1%/*/*}"
2280     fi
2281    
2282     # get basename
2283     pcat="${i##*/}"
2284     echo "${pcat}"
2285     }
2286    
2287     # returns pcat from DEPEND (without operand ! PCAT/PNAME-VERSION)
2288     # dep2pcat DEPEND
2289     dep2pcat()
2290     {
2291     local pcat
2292    
2293     pcat="${1%/*}"
2294     echo "${pcat}"
2295     }
2296    
2297     # returns pname from DEPEND (without operand ! PCAT/PNAME-VERSION)
2298     # $2=virtual is used to resolv VDEPEND from virtual packages
2299     # dep2pcat DEPEND (virtual)
2300     dep2pname()
2301     {
2302     local pname
2303    
2304     pname="${1##*/}"
2305    
2306     # cut version only if not virtual or it will cut the name
2307     if [[ $(dep2pcat $1) != virtual ]] && \
2308     [[ $2 != virtual ]]
2309     then
2310     pname="${pname%-*}"
2311     fi
2312    
2313     echo "${pname}"
2314     }
2315    
2316     dep2highest_magefile()
2317     {
2318     local pcat
2319     local pname
2320     local magefile
2321     local installed_virtuals
2322    
2323     pcat="$(dep2pcat $1)"
2324     pname="$(dep2pname $1)"
2325    
2326     if [[ ${pcat} = virtual ]]
2327     then
2328     # first check if virtual is already installed
2329     installed_virtuals="$(virtuals_read ${pcat}/${pname} showpkgs)"
2330     if [ -n "${installed_virtuals}" ]
2331     then
2332     for vpkg in ${installed_virtuals}
2333     do
2334     realpkgname="${vpkg}"
2335     virtualpkgname="${pcat}/${pname}"
2336     pcat="$(dep2pcat ${realpkgname})"
2337     pname="$(dep2pname ${realpkgname} virtual)"
2338     done
2339     else
2340     # choose one from virtualdb defaults (virtuals.defaults)
2341     realpkgname="$(default_virtualname_to_pkgname ${pcat}/${pname})"
2342     virtualpkgname="${pcat}/${pname}"
2343     pcat="$(dep2pcat ${realpkgname})"
2344     pname="$(dep2pname ${realpkgname} virtual)"
2345     fi
2346     fi
2347    
2348     magefile="$(get_highest_magefile ${pcat} ${pname})"
2349     echo "${magefile}"
2350     }
2351    
2352     # is_installed ${PCAT}/${PNAME}-${PVER}-${PBUILD}
2353     is_installed()
2354     {
2355     local fullpkgname="$1"
2356    
2357     # return 0 if installed
2358     [ -d ${MROOT}${INSTALLDB}/${fullpkgname} ] && return 0
2359    
2360     return 1
2361     }
2362    
2363     install_packages()
2364     {
2365     local list="$@"
2366     local pkg
2367     local pcat
2368     local pname
2369     local pver
2370     local pbuild
2371     local total_pkgs
2372     local current_pkg
2373     local src_install
2374     local uninstall_list
2375    
2376     # check for --src-install
2377     if [[ $1 = --src-install ]]
2378     then
2379     # remove --src-install from list
2380     list=${list/--src-install/}
2381     # enable src-install
2382     src_install="--src-install"
2383     fi
2384    
2385     # reset MAGE_PROTECT_COUNTER
2386     declare -i MAGE_PROTECT_COUNTER=0
2387     export MAGE_PROTECT_COUNTER
2388    
2389     # get count of total packages
2390     declare -i total_pkgs=0
2391     declare -i current_pkg=0
2392     for i in ${list}; do (( total_pkgs++ )); done
2393    
2394     echo
2395    
2396     if [[ -n ${MROOT} ]]
2397     then
2398     echo -ne ${COLRED}
2399     echo "!! installing in MROOT=${MROOT}"
2400     echo -ne ${COLDEFAULT}
2401     echo
2402     fi
2403    
2404     for pkg in ${list}
2405     do
2406     (( current_pkg++ ))
2407     pcat=$(magename2pcat ${pkg})
2408     pname=$(magename2pname ${pkg})
2409     pver=$(magename2pver ${pkg})
2410     pbuild=$(magename2pbuild ${pkg})
2411    
2412     mage_install \
2413     --pcat ${pcat} \
2414     --pname ${pname} \
2415     --pver ${pver} \
2416     --pbuild ${pbuild} \
2417     --count-total ${total_pkgs} \
2418     --count-current ${current_pkg} \
2419     ${src_install}
2420    
2421     # check for allready installed packages and remove them
2422     # except the package we have installed
2423     uninstall_list="$(get_uninstall_candidates \
2424     --pcat "${pcat}" \
2425     --pname "${pname}" \
2426     --protected ${pcat}/${pname}-${pver}-${pbuild})"
2427    
2428     # uninstall all packges in uninstall_list if not empty
2429     if [ -n "${uninstall_list}" ]
2430     then
2431     echo
2432     uninstall_packages ${uninstall_list} \
2433     || die "install_packges() uninstalling not-needed."
2434     fi
2435    
2436     # crlf for better view in VERBOSE mode
2437     #if [[ ${VERBOSE} = on ]]; then echo; fi
2438     echo
2439     done
2440    
2441     #echo "DEBUG MAGE_PROTECT_COUNTER=${MAGE_PROTECT_COUNTER}"
2442     show_etc_update_mesg
2443     }
2444    
2445     # get_value_from_magefile VARIABLE
2446     # returns the content of this VAR
2447     get_value_from_magefile()
2448     {
2449     local var="$1"
2450     local magefile="$2"
2451     local value
2452    
2453 niro 370 [[ -z ${var} ]] && return 1
2454     [[ -z ${magefile} ]] && return 1
2455    
2456 niro 226 # local all possible vars of a mage file
2457     # to prevent bad issues
2458     local PKGNAME
2459     local STATE
2460     local DESCRIPTION
2461     local HOMEPAGE
2462     local DEPEND
2463     local SDEPEND
2464     local PROVIDE
2465     local PKGTYPE
2466 niro 943 local SPLIT_PACKAGE_BASE
2467 niro 226 local preinstall
2468     local postinstall
2469 niro 248 local preremove
2470     local postremove
2471 niro 226
2472     # sanity checks
2473     [ -f ${magefile} ] && source ${magefile} || \
2474     die "get_value_from_magefile: ${magefile} not found."
2475     [ -z "${var}" ] && die "get_value_from_magefile: \$var not given."
2476    
2477     source ${magefile}
2478     eval value=\$$(echo ${var})
2479     echo "${value}"
2480 niro 248
2481 niro 258 # unset these functions
2482     unset -f preinstall
2483     unset -f postinstall
2484     unset -f preremove
2485     unset -f postremove
2486 niro 226 }
2487    
2488     mage_install()
2489     {
2490     # local all possible vars of a mage file
2491     # to prevent bad issues
2492     local PKGNAME
2493     local STATE
2494     local DESCRIPTION
2495     local HOMEPAGE
2496     local DEPEND
2497     local SDEPEND
2498     local PROVIDE
2499     local PKGTYPE
2500     local preinstall
2501     local postinstall
2502 niro 248 local preremove
2503     local postremove
2504 niro 226
2505     local pcat
2506     local pname
2507     local pver
2508     local pbuild
2509     local count_total
2510     local count_current
2511     local magefile
2512     local src_install
2513 niro 876 local i
2514 niro 226
2515     # very basic getops
2516     for i in $*
2517     do
2518     case $1 in
2519     --pcat|-c) shift; pcat="$1" ;;
2520     --pname|-n) shift; pname="$1" ;;
2521     --pver|-v) shift; pver="$1" ;;
2522     --pbuild|-b) shift; pbuild="$1" ;;
2523     --count-total) shift; count_total="$1" ;;
2524     --count-current) shift; count_current="$1" ;;
2525     --src-install|-s) shift; src_install=true ;;
2526     esac
2527     shift
2528     done
2529    
2530     # sanity checks; abort if not given
2531     [ -z "${pcat}" ] && die "mage_install() \$pcat not given."
2532     [ -z "${pname}" ] && die "mage_install() \$pname not given."
2533     [ -z "${pver}" ] && die "mage_install() \$pver not given."
2534     [ -z "${pbuild}" ] && die "mage_install() \$pbuild not given."
2535    
2536     # check needed global vars
2537     [ -z "${MAGEDIR}" ] && die "mage_install() \$MAGEDIR not set."
2538     [ -z "${INSTALLDB}" ] && die "mage_install() \$INSTALLDB not set."
2539     [ -z "${BUILDDIR}" ] && die "mage_install() \$BUILDDIR not set."
2540    
2541     xtitle "[ (${count_current}/${count_total}) Installing ${pcat}/${pname}-${pver}-${pbuild} ]"
2542     echo -ne "${COLBLUE} >>> ${COLDEFAULT}"
2543     echo -n "installing (${count_current}/${count_total}): "
2544     echo -ne "${COLBLUE}${pcat}/${COLDEFAULT}"
2545     echo -e "${COLGREEN}${pname}-${pver}-${pbuild}${COLDEFAULT}"
2546    
2547     magefile="${MAGEDIR}/${pcat}/${pname}/${pname}-${pver}-${pbuild}.mage"
2548     source ${magefile}
2549    
2550     # abort on sources if no srcinstall
2551     if [[ ${PKGTYPE} = sources ]] && [[ ${src_install} != true ]]
2552     then
2553     echo
2554     echo -e "This Package is a Source Package."
2555     echo
2556     echo -e "Only 'srcinstall' works with this type of packages"
2557     echo -en "If you have done a srcinstall before, "
2558     echo -e "you will find the files in /usr/src."
2559     echo
2560     exit 1
2561     fi
2562    
2563     ## preinstall scripts
2564     if [ -n "$(typeset -f preinstall)" ]
2565     then
2566     echo -e " ${COLBLUE}***${COLDEFAULT} running preinstall ... "
2567     preinstall
2568     unset preinstall
2569     fi
2570    
2571     if [[ ${src_install} = true ]]
2572     then
2573     local smage2file
2574     # check needed global vars
2575     [ -z "${SMAGESCRIPTSDIR}" ] && die "\$SMAGESCRIPTSDIR not set."
2576     [ -z "${SOURCEDIR}" ] && die "\$SOURCEDIR not set."
2577     [ -z "${BINDIR}" ] && die "\$BINDIR not set."
2578    
2579     # build the package first
2580     if [[ ${MAGEDEBUG} = on ]]
2581     then
2582     echo M:${pname}
2583     echo V:${pver}
2584     echo B:${pbuild}
2585     fi
2586    
2587 niro 2365 if [[ -n ${SPLIT_PACKAGE_BASE} ]]
2588 niro 675 then
2589 niro 876 # basic svn compat
2590 niro 1502 if [[ -d ${SMAGESCRIPTSDIR}/.svn ]]
2591 niro 876 then
2592 niro 1502 for i in ${SMAGESCRIPTSDIR}/*/${SPLIT_PACKAGE_BASE}/${SPLIT_PACKAGE_BASE}-${pver}-${pbuild}.smage2
2593 niro 943 do
2594     smage2file="${i}"
2595     done
2596     else
2597     smage2file=${SMAGESCRIPTSDIR}/${SPLIT_PACKAGE_BASE}/${SPLIT_PACKAGE_BASE}-${pver}-${pbuild}.smage2
2598     fi
2599    
2600 niro 675 else
2601 niro 876 # basic svn compat
2602 niro 1502 if [[ -d ${SMAGESCRIPTSDIR}/.svn ]]
2603 niro 876 then
2604 niro 1502 for i in ${SMAGESCRIPTSDIR}/*/${pname}/${pname}-${pver}-${pbuild}.smage2
2605 niro 876 do
2606     smage2file="${i}"
2607     done
2608     else
2609 niro 943 smage2file=${SMAGESCRIPTSDIR}/${pname}/${pname}-${pver}-${pbuild}.smage2
2610 niro 876 fi
2611 niro 675 fi
2612 niro 943
2613 niro 226 if [ -f "${smage2file}" ]
2614     then
2615 niro 385 echo -e " ${COLBLUE}***${COLDEFAULT} building package from source ... "
2616 niro 226 smage2 ${smage2file} || die "compile failed"
2617     else
2618     echo
2619     echo "$(basename ${SMAGEFILE}) not found."
2620     echo "update your smage-tree and try it again."
2621     echo
2622     die
2623     fi
2624     fi
2625    
2626     if [[ ${PKGTYPE} != virtual ]] && \
2627     [[ ${PKGTYPE} != sources ]]
2628     then
2629 niro 2156 unpack_package "${magefile}"
2630 niro 385 echo -e " ${COLBLUE}***${COLDEFAULT} merging files into system ... "
2631 niro 226 build_doinstall ${PKGNAME}
2632     fi
2633    
2634     ## postinstall scripts
2635     if [ -n "$(typeset -f postinstall)" ]
2636     then
2637     echo -e " ${COLBLUE}***${COLDEFAULT} running postinstall ... "
2638     postinstall
2639     unset postinstall
2640     fi
2641    
2642     # install a database entry
2643     install_database_entry \
2644     --pcat "${pcat}" \
2645     --pname "${pname}" \
2646     --pver "${pver}" \
2647     --pbuild "${pbuild}" \
2648     --pkgname "${PKGNAME}" \
2649     --pkgtype "${PKGTYPE}" \
2650     || die "error in mage_install() running install_database_entry()."
2651    
2652     # remove the package dir now
2653     if [ -d ${BUILDDIR}/${PKGNAME} ]
2654     then
2655     rm -rf ${BUILDDIR}/${PKGNAME}
2656     fi
2657    
2658     # rebuilds toplevel info node
2659     if [[ ${MAGE_INFO_REBUILD} = true ]]
2660     then
2661     echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2662     echo -n "rebuilding top-level info node ... "
2663     ${MLIBDIR}/mkinfodir ${MROOT}/usr/share/info \
2664     > ${MROOT}/usr/share/info/dir && \
2665     echo "done." || echo "failure."
2666     unset MAGE_INFO_REBUILD
2667     fi
2668    
2669     # rebuilds the enviroment with the content of /etc/env.d
2670     if [[ ${MAGE_ENV_REBUILD} = true ]]
2671     then
2672     echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2673     echo -n "rebuilding environment ... "
2674 niro 2606 ${MLIBDIR}/env-rebuild > /dev/null && \
2675 niro 226 echo "done." || echo "failure."
2676     unset MAGE_ENV_REBUILD
2677     fi
2678    
2679     xtitleclean
2680    
2681     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2682     echo -n "package "
2683     # echo -ne "${COLBLUE}${pcat}/${COLDEFAULT}"
2684     # echo -ne "${COLGREEN}${pname}-${pver}-${pbuild}${COLDEFAULT} "
2685     echo "successfully installed."
2686 niro 248
2687 niro 258 # unset these functions
2688     unset -f preinstall
2689     unset -f postinstall
2690     unset -f preremove
2691     unset -f postremove
2692 niro 226 }
2693    
2694     md5sum_packages()
2695     {
2696     local list="$@"
2697     local magefile
2698     local pcat
2699     local pname
2700     local pkgname
2701     local pkgfile
2702     local pkgtype
2703     local count_current
2704     local count_total
2705    
2706     # get count of total packages
2707     declare -i count_current=0
2708     declare -i count_total=0
2709    
2710     for i in ${list}; do (( count_total++ )); done
2711    
2712     for magefile in ${list}
2713     do
2714     pcat=$(magename2pcat ${magefile})
2715     pname=$(magename2pname ${magefile})
2716     pkgname="$(get_value_from_magefile PKGNAME ${magefile})"
2717     md5file="${MAGEDIR}/${pcat}/${pname}/md5/${pkgname}.md5"
2718 niro 2271 pkgfile="${pkgname}.${PKGSUFFIX}"
2719 niro 226 pkgtype="$(get_value_from_magefile PKGTYPE ${magefile})"
2720    
2721     (( count_current++ ))
2722     xtitle "[ (${count_current}/${count_total}) MD5SUM: ${pkgfile} ]"
2723    
2724     # abort on virtual pkg
2725     if [[ ${pkgtype} = virtual ]]
2726     then
2727     echo -ne " ${COLBLUE}---${COLDEFAULT}"
2728 niro 2271 echo " !md5sum virtual (${count_current}/${count_total}): ${pkgname} ... "
2729 niro 226 continue
2730     fi
2731    
2732     # abort on sources pkg
2733     if [[ ${pkgtype} = sources ]]
2734     then
2735     echo -ne " ${COLBLUE}---${COLDEFAULT}"
2736 niro 2271 echo " !md5sum sources (${count_current}/${count_total}): ${pkgname} ... "
2737 niro 226 continue
2738     fi
2739    
2740     if [ -f "${md5file}" ]
2741     then
2742     echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2743     echo -ne "checking md5sum (${count_current}/${count_total}): "
2744 niro 1652 mchecksum --rundir "${PKGDIR}" --file "${md5file}" --method md5 || die "md5 for ${pkgfile} failed"
2745 niro 226 else
2746     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2747     echo -e "!! no md5sum file found for ${pkgfile} :("
2748     fi
2749     done
2750    
2751     # add a crlf for a better view
2752     if [ ${count_total} -gt 1 ]; then echo; fi
2753     }
2754    
2755     ## uninstall_packages ulist
2756     uninstall_packages()
2757     {
2758     local list="$@"
2759     local pcat
2760     local pname
2761     local pver
2762     local pbuild
2763     local can_pcat
2764     local can_pname
2765     local can_ver_list
2766    
2767     if [[ -n ${MROOT} ]]
2768     then
2769     echo -ne ${COLRED}
2770     echo "!! uninstalling from MROOT=${MROOT}"
2771     echo -ne ${COLDEFAULT}
2772     echo
2773     fi
2774    
2775     # generate a candidates list
2776     for pkg in ${list}
2777     do
2778     pcat=$(dep2pcat ${pkg})
2779     pname=$(magename2pname ${pkg})
2780     pver=$(magename2pver ${pkg})
2781     pbuild=$(magename2pbuild ${pkg})
2782     can_pcat="${pcat}"
2783     can_pname="${pname}"
2784 niro 2270
2785 niro 226 if [ -z "${can_ver_list}" ]
2786     then
2787     can_ver_list=" ${pver}-${pbuild}"
2788     else
2789     can_ver_list="${can_ver_list}, ${pver}-${pbuild}"
2790     fi
2791     done
2792    
2793     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2794     echo "following candidate(s) will be removed:"
2795     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2796 niro 240 echo -ne "${COLBOLD}${can_pcat}/${can_pname}:${COLDEFAULT}"
2797 niro 226 echo -e "${COLRED} ${can_ver_list} ${COLDEFAULT}"
2798 niro 501 echo
2799 niro 240 if [ ${MAGE_UNINSTALL_TIMEOUT} -gt 0 ]
2800     then
2801     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2802     echo "( Press [CTRL+C] to abort )"
2803     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2804     echo -n "Waiting ${MAGE_UNINSTALL_TIMEOUT} seconds ..."
2805     for ((i=MAGE_UNINSTALL_TIMEOUT; i >= 0; i--))
2806     do
2807     echo -ne "${COLRED} ${i}${COLDEFAULT}"
2808     sleep 1
2809     done
2810     echo
2811     echo
2812     fi
2813 niro 226
2814     for pkg in ${list}
2815     do
2816     pcat=$(dep2pcat ${pkg})
2817     pname=$(magename2pname ${pkg})
2818     pver=$(magename2pver ${pkg})
2819     pbuild=$(magename2pbuild ${pkg})
2820    
2821     mage_uninstall \
2822     --pcat ${pcat} \
2823     --pname ${pname} \
2824     --pver ${pver} \
2825     --pbuild ${pbuild} \
2826     --count-total ${total_pkgs} \
2827     --count-current ${current_pkg} \
2828     ${src_install}
2829    
2830     # crlf for better view in VERBOSE mode
2831     #if [[ ${VERBOSE} = on ]]; then echo; fi
2832     echo
2833     done
2834     }
2835    
2836     mage_uninstall()
2837     {
2838     # local all possible vars of a mage file
2839     # to prevent bad issues
2840     local PKGNAME
2841     local STATE
2842     local DESCRIPTION
2843     local HOMEPAGE
2844     local DEPEND
2845     local SDEPEND
2846     local PROVIDE
2847     local PKGTYPE
2848     local preinstall
2849     local postinstall
2850 niro 248 local preremove
2851     local postremove
2852 niro 226
2853     local pcat
2854     local pname
2855     local pver
2856     local pbuild
2857     local magefile
2858     local i
2859    
2860     # very basic getops
2861     for i in $*
2862     do
2863     case $1 in
2864 niro 501 --pcat|-c) shift; pcat="$1" ;;
2865 niro 226 --pname|-n) shift; pname="$1" ;;
2866     --pver|-v) shift; pver="$1" ;;
2867 niro 501 --pbuild|-b) shift; pbuild="$1" ;;
2868 niro 226 esac
2869     shift
2870 niro 501 done
2871 niro 226
2872     # sanity checks; abort if not given
2873 niro 501 [ -z "${pcat}" ] && die "mage_uninstall() \$pcat not given."
2874 niro 226 [ -z "${pname}" ] && die "mage_uninstall() \$pname not given."
2875     [ -z "${pver}" ] && die "mage_uninstall() \$pver not given."
2876 niro 501 [ -z "${pbuild}" ] && die "mage_uninstall() \$pbuild not given."
2877 niro 226
2878     # check needed global vars
2879     [ -z "${MAGEDIR}" ] && die "mage_uninstall() \$MAGEDIR not set."
2880     [ -z "${INSTALLDB}" ] && die "mage_uninstall() \$INSTALLDB not set."
2881     [ -z "${BUILDDIR}" ] && die "mage_uninstall() \$BUILDDIR not set."
2882    
2883     xtitle "[ (${count_current}/${count_total}) Removing ${pcat}/${pname}-${pver}-${pbuild} ]"
2884     echo -ne "${COLBLUE} <<< ${COLDEFAULT}"
2885     echo -n "removing: "
2886     echo -ne "${COLBLUE}${pcat}/${COLDEFAULT}"
2887 niro 416 echo -e "${COLRED}${pname}-${pver}-${pbuild}${COLDEFAULT}"
2888 niro 226
2889 niro 499 magefile="${MROOT}${INSTALLDB}/${pcat}/${pname}-${pver}-${pbuild}/${pname}-${pver}-${pbuild}.mage"
2890 niro 226 source ${magefile}
2891    
2892     ## preremove scripts
2893     if [ -n "$(typeset -f preremove)" ]
2894     then
2895     echo -e " ${COLBLUE}***${COLDEFAULT} running preremove ... "
2896     preremove
2897     unset preremove
2898     fi
2899    
2900     # runs uninstall
2901     build_douninstall \
2902     --pcat "${pcat}" \
2903     --pname "${pname}" \
2904     --pver "${pver}" \
2905     --pbuild "${pbuild}"
2906    
2907     ## postremove scripts
2908     if [ -n "$(typeset -f postremove)" ]
2909     then
2910     echo -e " ${COLBLUE}***${COLDEFAULT} running postremove ... "
2911     postremove
2912     unset postremove
2913     fi
2914    
2915     # removes the database entry
2916     remove_database_entry \
2917     --pcat "${pcat}" \
2918     --pname "${pname}" \
2919     --pver "${pver}" \
2920     --pbuild "${pbuild}" \
2921     || die "error in mage_uninstall() running remove_database_entry()."
2922    
2923     # rebuilds toplevel info node
2924     if [[ ${MAGE_INFO_REBUILD} = true ]]
2925     then
2926     echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2927     echo -n "rebuilding top-level info node ... "
2928     ${MLIBDIR}/mkinfodir ${MROOT}/usr/share/info \
2929     > ${MROOT}/usr/share/info/dir && \
2930     echo "done." || echo "failure."
2931     unset MAGE_INFO_REBUILD
2932     fi
2933    
2934     # rebuilds the enviroment with the content of /etc/env.d
2935     if [[ ${MAGE_ENV_REBUILD} = true ]]
2936     then
2937     echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2938     echo -n "rebuilding environment ... "
2939 niro 2606 ${MLIBDIR}/env-rebuild > /dev/null && \
2940 niro 226 echo "done." || echo "failure."
2941     unset MAGE_ENV_REBUILD
2942     fi
2943    
2944     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2945     echo -n "package "
2946     # echo -ne "${COLBLUE}${pcat}/${COLDEFAULT}"
2947     # echo -ne "${COLGREEN}${pname}-${pver}-${pbuild}${COLDEFAULT} "
2948     echo "successfully removed."
2949 niro 248
2950 niro 258 # unset these functions
2951     unset -f preinstall
2952     unset -f postinstall
2953     unset -f preremove
2954     unset -f postremove
2955 niro 226 }
2956    
2957 niro 2371 # rerun_pkgfunctions [method] pkg1 pkg2 pkg3
2958     rerun_pkgfunctions()
2959     {
2960     local method
2961     local list
2962     local pcat
2963     local pname
2964     local pver
2965     local pbuild
2966     local magefile
2967     local i
2968    
2969     # very basic getops
2970 niro 2372 case $1 in
2971     --method) shift; method="$1" ;;
2972     esac
2973     shift
2974 niro 2371 local list="$@"
2975    
2976     # sanity check
2977     case ${method} in
2978     preinstall|postinstall) ;;
2979     preremove|postremove) ;;
2980     *) die "rerun_pkgfunctions(): Unknown method '${method}'." ;;
2981     esac
2982    
2983     if [[ -n ${MROOT} ]]
2984     then
2985     echo -ne ${COLRED}
2986     echo "!! running in MROOT=${MROOT}"
2987     echo -ne ${COLDEFAULT}
2988     echo
2989     fi
2990    
2991     for pkg in ${list}
2992     do
2993     pcat=$(dep2pcat ${pkg})
2994     pname=$(magename2pname ${pkg})
2995     pver=$(magename2pver ${pkg})
2996     pbuild=$(magename2pbuild ${pkg})
2997     magefile="${MROOT}${INSTALLDB}/${pcat}/${pname}-${pver}-${pbuild}/${pname}-${pver}-${pbuild}.mage"
2998    
2999     if [ -e ${magefile} ]
3000     then
3001     source ${magefile}
3002     if [ -n "$(typeset -f ${method})" ]
3003     then
3004     echo -e " ${COLBLUE}***${COLDEFAULT} running ${method} for ${pkg} ... "
3005     ${method}
3006     else
3007     echo "No ${method}() for pkg '${pkg}' defined. Doing nothing."
3008     fi
3009     unset -f preinstall postinstall preremove postremove
3010     else
3011     die "Magefile '${magefile}' does not exist."
3012     fi
3013     done
3014     }
3015    
3016 niro 1209 show_etc_update_mesg()
3017     {
3018 niro 226 [ ${MAGE_PROTECT_COUNTER} -eq 0 ] && return 0
3019    
3020     echo
3021     echo -ne "${COLRED}"
3022     echo "Important:"
3023     echo -ne ${COLDEFAULT}
3024     echo "${MAGE_PROTECT_COUNTER} protected file(s) were installed."
3025     echo
3026     echo "Please run 'etc-update' to update your configuration files."
3027     echo
3028     }
3029 niro 237
3030     pkgsearch()
3031     {
3032     local string="$1"
3033     local result
3034     local pkg
3035     local pcat
3036     local pname
3037     local magefile
3038     local pver
3039     local pbuild
3040     local state
3041     local descriptiom
3042     local homepage
3043 niro 1648 local license
3044 niro 237 local i
3045     local all_installed
3046     local ipver
3047     local ipbuild
3048 niro 445 local latest_available
3049 niro 458 local depsfull
3050     local sdepsfull
3051     local deps
3052     local sdeps
3053     local dep
3054     local sign
3055 niro 237
3056     # only names no versions
3057 niro 391 result="$(find ${MAGEDIR} -mindepth 2 -maxdepth 2 -type d -name '*'${string}'*'| sed '/profiles/d' | sed '/includes/d')"
3058 niro 328 #result="$(find ${MAGEDIR} -type f -name '*'${string}'*'.mage | sort)"
3059 niro 237
3060     # nothing found
3061     [[ -z ${result} ]] && die "No package found containing '${string}' in the name."
3062    
3063     for pkg in ${result}
3064     do
3065     # dirty, but does the job
3066     pcat="$(magename2pcat ${pkg}/foo)"
3067     pname="$(magename2pname ${pkg}-foo-foo)"
3068    
3069     # get highest version available
3070     magefile=$(get_highest_magefile ${pcat} ${pname})
3071    
3072 niro 445 if [[ ! -z ${magefile} ]]
3073     then
3074     # now get all needed infos to print a nice output
3075     pver="$(magename2pver ${magefile})"
3076     pbuild="$(magename2pbuild ${magefile})"
3077     state="$(get_value_from_magefile STATE ${magefile})"
3078     description="$(get_value_from_magefile DESCRIPTION ${magefile})"
3079     homepage="$(get_value_from_magefile HOMEPAGE ${magefile})"
3080 niro 1648 license="$(get_value_from_magefile LICENSE ${magefile})"
3081    
3082 niro 445 # all installed
3083     for i in $(get_uninstall_candidates --pname ${pname} --pcat ${pcat})
3084     do
3085     ipver="$(magename2pver ${i})"
3086     ipbuild="$(magename2pbuild ${i})"
3087 niro 1648
3088 niro 445 if [[ -z ${all_installed} ]]
3089     then
3090     all_installed="${ipver}-${ipbuild}"
3091     else
3092     all_installed="${all_installed} ${ipver}-${ipbuild}"
3093     fi
3094     done
3095     [[ -z ${all_installed} ]] && all_installed="none"
3096 niro 1648
3097 niro 445 case ${state} in
3098     stable) state=${COLGREEN}"[s] ";;
3099     testing) state=${COLYELLOW}"[t] ";;
3100     unstable) state=${COLRED}"[u] ";;
3101     old) state=${COLGRAY}"[o] ";;
3102     esac
3103 niro 237
3104 niro 445 latest_available="${pver}-${pbuild}"
3105     else
3106     # package is masked
3107     state="${COLRED}[m] "
3108     latest_available="${COLRED}masked for this distribution.${COLDEFAULT}"
3109     fi
3110 niro 237
3111 niro 458 depsfull="$(get_value_from_magefile DEPEND ${magefile})"
3112     sdepsfull="$(get_value_from_magefile SDEPEND ${magefile})"
3113    
3114     while read sign dep
3115     do
3116     case ${dep} in
3117     "") continue;;
3118     esac
3119    
3120 niro 1961 if [[ -z ${deps} ]]
3121     then
3122     deps="$(basename ${dep%-*})"
3123     else
3124     deps="${deps} $(basename ${dep%-*})"
3125     fi
3126 niro 458 done << EOF
3127     ${depsfull}
3128     EOF
3129    
3130     while read sign dep
3131     do
3132     case ${dep} in
3133     "") continue;;
3134     esac
3135    
3136 niro 1961 if [[ -z ${sdeps} ]]
3137     then
3138     sdeps="$(basename ${dep%-*})"
3139     else
3140     sdeps="${sdeps} $(basename ${dep%-*})"
3141     fi
3142 niro 458 done << EOF
3143     ${sdepsfull}
3144     EOF
3145    
3146 niro 237 echo -e "${state}${pcat}/${pname}"${COLDEFAULT}
3147 niro 445 echo -e " Latest available: ${latest_available}"
3148 niro 237 echo " Installed versions: ${all_installed}"
3149     echo " Description: ${description}"
3150     echo " Homepage: ${homepage}"
3151 niro 1648 if [[ ! -z ${license} ]]
3152     then
3153     echo " License: ${license}"
3154     fi
3155 niro 1961 echo " Depends: ${deps}"
3156 niro 458 echo " SDepends: ${sdeps}"
3157 niro 237 echo
3158    
3159     unset pcat
3160     unset pname
3161     unset magefile
3162     unset pver
3163     unset pbuild
3164     unset state
3165     unset descriptiom
3166     unset homepage
3167     unset all_installed
3168     unset ipver
3169     unset ipbuild
3170 niro 458 unset depsfull
3171     unset sdepsfull
3172     unset deps
3173     unset sdeps
3174     unset dep
3175     unset sign
3176 niro 237 done
3177     }
3178 niro 249
3179     export_inherits()
3180     {
3181     local include="$1"
3182     shift
3183    
3184     while [ "$1" ]
3185     do
3186     local functions="$1"
3187    
3188     # sanity checks
3189     [ -z "${include}" ] && die "export_inherits(): \$include not given."
3190     [ -z "${functions}" ] && die "export_inherits(): \$functions not given."
3191    
3192     eval "${functions}() { ${include}_${functions} ; }"
3193    
3194     # debug
3195 niro 1584 mqueryfeature "debug" && typeset -f "${functions}"
3196 niro 249
3197     shift
3198     done
3199     }
3200 niro 350
3201     mlibdir()
3202     {
3203     local libdir=lib
3204     [[ ${ARCH} = x86_64 ]] && libdir=lib64
3205    
3206     echo "${libdir}"
3207     }
3208 niro 370
3209     ## blacklisted ${magefile}
3210     blacklisted()
3211     {
3212     [[ -z ${MAGE_DISTRIBUTION} ]] && local MAGE_DISTRIBUTION=stable
3213    
3214     # compat
3215     [[ ${USE_UNSTABLE} = true ]] && local MAGE_DISTRIBUTION=unstable
3216     [[ ${USE_TESTING} = true ]] && local MAGE_DISTRIBUTION=testing
3217    
3218 niro 892 # support both types for the moment
3219     if [[ -f /etc/mage-profile/package.blacklist-${ARCH}-${MAGE_DISTRIBUTION} ]]
3220     then
3221     local EXCLUDED="/etc/mage-profile/package.blacklist-${ARCH}-${MAGE_DISTRIBUTION}"
3222     else
3223     local EXCLUDED="/etc/mage-profile/package.blacklist-${ARCH}"
3224     fi
3225 niro 370
3226     # return 0 if the list not exist; nothin is masked
3227     [[ ! -f ${EXCLUDED} ]] && return 0
3228    
3229     local MAGEFILE="$1"
3230    
3231     local PCAT="$(magename2pcat ${MAGEFILE})"
3232     local PNAME="$(magename2pname ${MAGEFILE})"
3233     local PVER="$(magename2pver ${MAGEFILE})"
3234     local PBUILD="$(magename2pbuild ${MAGEFILE})"
3235    
3236     local EXPCAT EXPNAME EXPVER EXPBUILD
3237     while read EXPCAT EXPNAME EXPVER EXPBUILD
3238     do
3239     # ignore spaces and comments
3240     case "${EXPCAT}" in
3241     \#*|"") continue ;;
3242     esac
3243    
3244     # exclude full pver
3245     if [[ -n ${PCAT} ]] && [[ -n ${PNAME} ]] &&
3246     [[ -n ${EXPCAT} ]] && [[ -n ${EXPNAME} ]] &&
3247     [[ -n ${PVER} ]] && [[ -n ${PBUILD} ]] &&
3248     [[ -n ${EXPVER} ]] && [[ -n ${EXPBUILD} ]]
3249     then
3250     [[ ${EXPCAT}/${EXPNAME}-${EXPVER}-${EXPBUILD} = ${PCAT}/${PNAME}-${PVER}-${PBUILD} ]] && return 1
3251     fi
3252    
3253     # exclude pcat/pname only
3254     if [[ -n ${PCAT} ]] && [[ -n ${PNAME} ]] &&
3255     [[ -n ${EXPCAT} ]] && [[ -n ${EXPNAME} ]] &&
3256     [[ -z ${EXPVER} ]] && [[ -z ${EXPBUILD} ]]
3257     then
3258     [[ ${EXPCAT}/${EXPNAME} = ${PCAT}/${PNAME} ]] && return 1
3259     fi
3260     done << EOF
3261     $( cat ${EXCLUDED}; echo)
3262     EOF
3263    
3264     return 0
3265     }
3266    
3267 niro 1273 # need_busybox_support ${cmd}
3268     # return 0 (no error = needs busybox support) or return 1 (error = no busybox support required)
3269     need_busybox_support()
3270     {
3271     local cmd
3272 niro 1952 local busybox
3273 niro 1273 cmd="$1"
3274    
3275 niro 1952 for busybox in {,/usr}/bin/busybox
3276     do
3277     if [[ -x ${busybox} ]]
3278 niro 1273 then
3279 niro 2223 if [[ $(readlink $(type -P ${cmd})) = ${busybox} ]]
3280 niro 1952 then
3281     # needs busybox support
3282     return 0
3283     fi
3284 niro 1273 fi
3285 niro 1952 done
3286 niro 1318
3287     # no busybox
3288     return 1
3289 niro 1273 }
3290    
3291     # busybox_filter_wget_options ${wget_opts}
3292     busybox_filter_wget_options()
3293     {
3294     local opts="$@"
3295     local i
3296     local fixed_opts
3297    
3298     if need_busybox_support wget
3299     then
3300     for i in ${opts}
3301     do
3302     # show only the allowed ones
3303     case ${i} in
3304     -c|--continue) fixed_opts+=" -c" ;;
3305     -s|--spider) fixed_opts+=" -s" ;;
3306     -q|--quiet) fixed_opts+=" -q" ;;
3307     -O|--output-document) shift; fixed_opts+=" -O $1" ;;
3308     --header) shift; fixed_opts+=" --header $1" ;;
3309     -Y|--proxy) shift; fixed_opts+=" -Y $1" ;;
3310     -P) shift; fixed_opts+=" -P $1" ;;
3311     --no-check-certificate) fixed_opts+=" --no-check-certificate ${i}" ;;
3312     -U|--user-agent) shift; fixed_opts+=" -U ${i}" ;;
3313     # simply drop all other opts
3314     *) continue ;;
3315     esac
3316     done
3317    
3318     echo "${fixed_opts}"
3319     else
3320     echo "${opts}"
3321     fi
3322     }
3323 niro 1541
3324     have_root_privileges()
3325     {
3326     local retval
3327    
3328     if [[ $(id -u) = 0 ]]
3329     then
3330     retval=0
3331     else
3332     retval=1
3333     fi
3334    
3335     return ${retval}
3336     }
3337 niro 1584
3338     known_mage_feature()
3339     {
3340     local feature="$1"
3341     local retval
3342 niro 2167
3343 niro 1584 case "${feature}" in
3344     autosvc|!autosvc) retval=0 ;;
3345     buildlog|!buildlog) retval=0 ;;
3346     ccache|!ccache) retval=0 ;;
3347     check|!check) retval=0 ;;
3348     compressdoc|!compressdoc) retval=0 ;;
3349 niro 1627 debug|!debug) retval=0 ;;
3350 niro 1584 distcc|!distcc) retval=0 ;;
3351 niro 2167 icecc|!icecc) retval=0 ;;
3352 niro 1584 kernelsrcunpack|!kernelsrcunpack) retval=0 ;;
3353     libtool|!libtool) retval=0 ;;
3354     linuxsymlink|!linuxsymlink) retval=0 ;;
3355 niro 2606 multilib|!multilib) reval=0 ;;
3356 niro 1584 pkgbuild|!pkgbuild) retval=0 ;;
3357 niro 1649 pkgdistrotag|!pkgdistrotag) retval=0 ;;
3358 niro 2606 pkgmetadata|!pkgmetadata) retval=0 ;;
3359 niro 1584 purge|!purge) retval=0 ;;
3360     qalint|!qalint) retval=0 ;;
3361     regentree|!regentree) retval=0 ;;
3362 niro 1620 resume|!resume) retval=0 ;;
3363 niro 1584 srcpkgbuild|!srcpkgbuild) retval=0 ;;
3364     srcpkgtarball|!srcpkgtarball) retval=0 ;;
3365 niro 1627 static|!static) retval=0 ;;
3366     stepbystep|!stepbystep) retval=0 ;;
3367 niro 1584 strip|!strip) retval=0 ;;
3368 niro 1627 verbose|!verbose) retval=0 ;;
3369 niro 1584 *) retval=1 ;;
3370     esac
3371    
3372     return "${retval}"
3373     }
3374    
3375     load_mage_features()
3376     {
3377     for i in ${MAGE_FEATURES_GLOBAL[*]} ${MAGE_FEATURES[*]}
3378     do
3379     FVERBOSE=off msetfeature ${i}
3380     done
3381     }
3382    
3383     msetfeature()
3384     {
3385     local feature
3386     local count
3387     local i
3388     local found
3389    
3390     for feature in $@
3391     do
3392     found=0
3393     count="${#MAGE_FEATURES_CURRENT[*]}"
3394    
3395     if ! known_mage_feature "${feature}"
3396     then
3397 niro 1628 [[ ${FVERBOSE} = off ]] || echo -e "${COLRED}Unknown feature '${feature}', ignoring it${COLDEFAULT}"
3398 niro 1584 return 3
3399     fi
3400    
3401     for ((i=0; i<count; i++))
3402     do
3403     if [[ ${MAGE_FEATURES_CURRENT[${i}]} = ${feature} ]]
3404     then
3405 niro 1599 [[ ${FVERBOSE} = off ]] || echo -e "${COLBLUE}---${COLGREEN} Feature '${feature}' already enabled${COLDEFAULT}"
3406 niro 1584 MAGE_FEATURES_CURRENT[${i}]="${feature}"
3407     found=1
3408     elif [[ ${MAGE_FEATURES_CURRENT[${i}]} = !${feature} ]]
3409     then
3410 niro 1599 [[ ${FVERBOSE} = off ]] || echo -e "${COLBLUE}---${COLGREEN} Feature '${feature}' currently disabled, enabling it!${COLDEFAULT}"
3411 niro 1584 MAGE_FEATURES_CURRENT[${i}]="${feature}"
3412     found=1
3413     elif [[ ${MAGE_FEATURES_CURRENT[${i}]} = ${feature//!} ]]
3414     then
3415 niro 1599 [[ ${FVERBOSE} = off ]] || echo -e "${COLBLUE}---${COLGREEN} Feature '${feature//!}' currently enabled, disabling it!${COLDEFAULT}"
3416 niro 1584 MAGE_FEATURES_CURRENT[${i}]="${feature}"
3417     found=1
3418     fi
3419     done
3420    
3421     # if the feature was not found after proccessing the whole array
3422     # it was not declared. in this case enable it
3423     if [[ ${found} = 0 ]]
3424     then
3425 niro 1599 [[ ${FVERBOSE} = off ]] || echo -e "${COLBLUE}---${COLGREEN} Feature '${feature}' was not declared, enabling it!${COLDEFAULT}"
3426 niro 1584 MAGE_FEATURES_CURRENT=( ${MAGE_FEATURES_CURRENT[*]} "${feature}" )
3427     fi
3428    
3429 niro 2720 export MAGE_FEATURES_CURRENT
3430 niro 1584 done
3431     }
3432    
3433     mqueryfeature()
3434     {
3435     local feature="$1"
3436     local retval=1
3437     local i
3438    
3439     if known_mage_feature "${feature}"
3440     then
3441     for i in ${MAGE_FEATURES_CURRENT[*]}
3442     do
3443     if [[ ${i} = ${feature} ]]
3444     then
3445     retval=0
3446     break # found break here
3447     fi
3448     done
3449     else
3450 niro 1628 [[ ${FVERBOSE} = off ]] || echo -e "${COLRED}Unknown feature '${feature}', ignoring it${COLDEFAULT}"
3451 niro 1584 retval=3
3452     fi
3453    
3454     return ${retval}
3455     }
3456    
3457     mprintfeatures()
3458     {
3459 niro 1781 echo -e "${COLRED}Global features:${COLDEFAULT} ${MAGE_FEATURES_GLOBAL[*]}"
3460     echo -e "${COLYELLOW}Local features:${COLDEFAULT} ${MAGE_FEATURES[*]}"
3461     echo -e "${COLGREEN}Current features:${COLDEFAULT} ${MAGE_FEATURES_CURRENT[*]}"
3462 niro 1584 }