Magellan Linux

Annotation of /trunk/mage/usr/lib/mage/mage4.functions.sh

Parent Directory Parent Directory | Revision Log Revision Log


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