Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1961 - (hide annotations) (download) (as text)
Thu Oct 25 07:07:28 2012 UTC (11 years, 6 months ago) by niro
Original Path: trunk/mage/usr/lib/mage/mage4.functions.sh
File MIME type: application/x-sh
File size: 80446 byte(s)
-print cosmetic
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 1758 # dirty hack to convert 0001 -> 1; 0120 -> 120 etc
1891     x="${#count}"
1892     for (( i=0; i<x; i++ ))
1893     do
1894     if [[ ${count:${i}:1} != 0 ]]
1895     then
1896     count="${count:${i}}"
1897     break
1898     fi
1899     done
1900    
1901 niro 1762 count="$(( ${count}+1 ))"
1902 niro 1758
1903 niro 603 # fill output up with zeros
1904     for (( i=${#count}; i < 4; i++ )); do output="${output}0"; done
1905     output="${output}${count}"
1906    
1907     echo "${output}"
1908 niro 226 }
1909    
1910     # call with
1911     # 'get_uninstall_candidates (--pcat cat --protected pcat/pfull) --pname PNAME'
1912     # returns /path/to/magefile(s)
1913     get_uninstall_candidates()
1914     {
1915     local search_pname
1916     local pkg
1917     local pcat
1918     local pname
1919     local pver
1920     local pbuild
1921     local list
1922     local pcatdir
1923     local protected
1924 niro 449 local i
1925 niro 226
1926     # very basic getops
1927     for i in $*
1928     do
1929     case $1 in
1930     --pcat|-c) shift; pcatdir="$1" ;;
1931     --pname|-n) shift; search_pname="$1" ;;
1932     --protected|-p) shift; protected="$1" ;;
1933     esac
1934     shift
1935     done
1936    
1937 niro 329 # it's not good to complain here about empty pnames; better to continue later anyway
1938     # # sanity checks; abort if not given
1939     # [ -z "${search_pname}" ] && die "get_uninstall_candidates() \$search_pname not given."
1940 niro 226
1941    
1942     # check needed global vars
1943     [ -z "${INSTALLDB}" ] && die "get_uninstall_candidates() \$INSTALLDB not set."
1944    
1945     # set pcatdir to '*' if empty
1946 niro 329 [ -z "${pcatdir}" ] && pcatdir='*'
1947 niro 226
1948     for pkg in ${MROOT}${INSTALLDB}/${pcatdir}/*
1949     do
1950     # abort if not a dir
1951     [ ! -d ${pkg} ] && continue
1952    
1953     pname="$(magename2pname ${pkg})"
1954    
1955     if [[ ${search_pname} = ${pname} ]]
1956     then
1957     pcat="$(magename2pcat ${pkg} installdb)"
1958     pver="$(magename2pver ${pkg})"
1959     pbuild="$(magename2pbuild ${pkg})"
1960    
1961     # exclude proteced
1962     [[ ${protected} = ${pcat}/${pname}-${pver}-${pbuild} ]] && continue
1963    
1964     list="${list} ${pcat}/${pname}-${pver}-${pbuild}"
1965     fi
1966     done
1967    
1968     echo "${list}"
1969     }
1970    
1971     # reads virtualdb file
1972     #$1 = virtualname; $2 commands: showpkgs, showline
1973     #return 0 == installed -> shows installed pkg as well
1974     #return 1 == not installed
1975     virtuals_read()
1976     {
1977     local virtualname="$1"
1978     local command="$2"
1979     local virtline
1980     local line x i
1981    
1982     # parse file to get virtual_name line
1983     IFS=$'\n'
1984     for line in $(< ${MROOT}${VIRTUALDB_FILE})
1985     do
1986     IFS=$' '
1987     for x in ${line}
1988     do
1989     if [[ ${x} = ${virtualname} ]]
1990     then
1991     virtline="${line}"
1992     [[ ${command} = showline ]] && echo "${line}"
1993     fi
1994     done
1995     IFS=$'\n'
1996     done
1997    
1998     unset IFS
1999    
2000     # now read the packages linked to VIRTUAL_NAME and output them
2001     if [ -n "${virtline}" ]
2002     then
2003     if [[ ${command} = showpkgs ]]
2004     then
2005     declare -i x=0
2006     for i in ${virtline}
2007     do
2008     if [ ${x} -ge 1 ]
2009     then
2010     echo "${i}"
2011     fi
2012     ((x++))
2013     done
2014     fi
2015     return 0
2016     fi
2017     return 1
2018     }
2019    
2020    
2021     #add pkg to virtualdb
2022     # $1 == virtualname $2= pkgname
2023     # retvals: 0=ok,added; 1=error; 3=pkg already in virtual
2024     virtuals_add()
2025     {
2026     local virtualname="$1"
2027     local pkgname="$2"
2028     local oldline
2029     local line i
2030     local installed_file
2031 niro 273 local OLDIFS
2032 niro 226
2033     if virtuals_read ${virtualname}
2034     then
2035 niro 329 # make sure ${PKG_NAME} is *not* in ${VIRTUAL_NAME} already
2036 niro 226 for i in $(virtuals_read ${virtualname} showpkgs)
2037     do
2038     if [[ ${i} = ${pkgname} ]]
2039     then
2040     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2041     echo "${pkgname} already linked as ${virtualname} ..."
2042     #return 3
2043     return 0
2044     fi
2045     done
2046    
2047     echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2048     echo "updating ${virtualname} entry with ${pkgname} ..."
2049     oldline="$(virtuals_read ${virtualname} showline)"
2050    
2051     # make a backup
2052     mv ${MROOT}${VIRTUALDB_FILE} ${MROOT}${VIRTUALDB_FILE}.old
2053    
2054 niro 273 OLDIFS="${IFS}"
2055 niro 226 IFS=$'\n'
2056     for line in $(< ${MROOT}${VIRTUALDB_FILE}.old)
2057     do
2058     # if the right line, append ${pkgname}, else do nothing
2059     if [[ ${line} = ${oldline} ]]
2060     then
2061     echo "${line} ${pkgname}" >> ${MROOT}${VIRTUALDB_FILE}
2062     else
2063     echo "${line}" >> ${MROOT}${VIRTUALDB_FILE}
2064     fi
2065     done
2066 niro 273 # unset IFS
2067     IFS="${OLDIFS}"
2068 niro 226 else
2069 niro 273 echo -ne "${COLBLUE} >>> ${COLDEFAULT}"
2070 niro 226 echo "register ${pkgname} as ${virtualname} ..."
2071     echo "${virtualname} ${pkgname}" >> ${MROOT}${VIRTUALDB_FILE}
2072     fi
2073    
2074     return 0
2075     }
2076    
2077     #deletes pakages from virtual database
2078     #$1 virtualname; $2 pkgname
2079 niro 1209 virtuals_del()
2080     {
2081 niro 226
2082 niro 273 local virtualname="$1"
2083     local pkgname="$2"
2084     local oldline
2085     local method
2086     local line i x
2087     local pkg_installed
2088     local OLDIFS
2089    
2090     # first check if exists
2091     if virtuals_read ${virtualname}
2092 niro 226 then
2093 niro 273 # get method -> delall or update and check if ${PKG_NAME} exists in ${VIRTUAL_NAME}
2094 niro 226 declare -i x=0
2095 niro 273 for i in $(virtuals_read ${virtualname} showpkgs)
2096 niro 226 do
2097 niro 273 if [[ ${i} = ${pkgname} ]]
2098 niro 226 then
2099 niro 273 pkg_installed=true
2100 niro 226 fi
2101     ((x++))
2102     done
2103 niro 273
2104     # abort if not installed
2105     if [[ ${pkg_installed} != true ]]
2106 niro 226 then
2107 niro 273 echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2108     echo "${pkgname} does not exists in ${virtualname}."
2109 niro 226 return 0
2110     fi
2111 niro 273
2112 niro 226 if [ ${x} -ge 2 ]
2113     then
2114 niro 273 method=update
2115 niro 226 else
2116 niro 273 method=delall
2117 niro 226 fi
2118 niro 273
2119     # get the complete line
2120     oldline="$(virtuals_read ${virtualname} showline)"
2121    
2122     # make a backup of the db
2123 niro 226 mv ${VIRTUALDB_FILE} ${VIRTUALDB_FILE}.old
2124 niro 273
2125     # parse virtualdb
2126     OLDIFS="${IFS}"
2127 niro 226 IFS=$'\n'
2128     for line in $(< ${VIRTUALDB_FILE}.old)
2129     do
2130 niro 273 if [[ ${line} = ${oldline} ]]
2131 niro 226 then
2132     #delall or update?
2133 niro 273 case ${method} in
2134 niro 226 update)
2135 niro 273 echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2136     echo "Unlinking ${pkgname} from ${virtualname} in virtual database ..."
2137     # del PKG_NAME from line
2138     echo "${line/ ${pkgname}/}" >> ${VIRTUALDB_FILE}
2139 niro 226 ;;
2140     delall)
2141 niro 273 echo -ne "${COLBLUE} <<< ${COLDEFAULT}"
2142     echo "Deleting ${virtualname} in virtual database ..."
2143     # continue; do not write anything
2144 niro 226 continue
2145     ;;
2146     esac
2147     else
2148     echo "${line}" >> ${VIRTUALDB_FILE}
2149     fi
2150     done
2151 niro 273 # unset IFS
2152     IFS="${OLDIFS}"
2153 niro 226 else
2154 niro 273 echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2155     echo "${virtualname} does not exists in virtual database."
2156 niro 226 fi
2157     }
2158    
2159     # gets real pkgname from virtuals.default
2160     #$1=VIRTUAL_NAME; returns PKG_NAME
2161     default_virtualname_to_pkgname()
2162     {
2163     local VIRTUAL_NAME PKG_NAME db_virtualname db_pkgname
2164    
2165     VIRTUAL_NAME=$1
2166    
2167     while read db_virtualname db_pkgname
2168     do
2169     if [ "${db_virtualname}" == "${VIRTUAL_NAME}" ]
2170     then
2171     PKG_NAME="${db_pkgname}"
2172     fi
2173     done << EOF
2174     $(< ${VIRTUALDB_DEFAULTS})
2175     EOF
2176    
2177     if [ -n "${PKG_NAME}" ]
2178     then
2179     echo "${PKG_NAME}"
2180     fi
2181     }
2182    
2183     minclude()
2184     {
2185     local i
2186    
2187 niro 437 if [[ -n $* ]]
2188 niro 226 then
2189 niro 437 for i in $*
2190 niro 226 do
2191 niro 1584 mqueryfeature "debug" && \
2192 niro 226 echo "--- Including ${MAGEDIR}/include/${i}.minc"
2193     source ${MAGEDIR}/include/${i}.minc
2194     done
2195 niro 1584 mqueryfeature "debug" && echo
2196 niro 226 fi
2197     }
2198    
2199     sminclude()
2200     {
2201     local i
2202    
2203 niro 437 if [[ -n $* ]]
2204 niro 226 then
2205 niro 437 for i in $*
2206 niro 226 do
2207     echo "--- Including ${SMAGESCRIPTSDIR}/include/${i}.sminc"
2208     source ${SMAGESCRIPTSDIR}/include/${i}.sminc
2209     done
2210     echo
2211     fi
2212     }
2213    
2214     # checks if an newer mage version is available
2215     is_newer_mage_version_available()
2216     {
2217     local newest_mage
2218     local installed_mage
2219    
2220 niro 252 newest_mage="$(basename $(get_highest_magefile app-mage mage) .mage)"
2221 niro 226 installed_mage="$(magequery -n mage | cut -d' ' -f5)"
2222    
2223     if [[ ${newest_mage} > ${installed_mage} ]]
2224     then
2225     echo
2226     echo -en ${COLRED}"An update for your packetmanager is available. "${COLDEFAULT}
2227     echo -e ${COLBLUE}"[ ${newest_mage} ]"${COLDEFAULT}
2228     echo "It is recommened to install this newer version"
2229 niro 373 echo "or your current system installation may break."
2230 niro 226 echo
2231     echo -en "Please update mage by running "
2232     echo -e ${COLGREEN}"'mage install mage'"${COLDEFAULT}
2233     echo
2234     fi
2235     }
2236    
2237    
2238     # returns pname from pkgname
2239     # pkgname2pname $PKGNAME
2240     pkgname2pname()
2241     {
2242     local pname
2243    
2244     pname="${1%-*-*-*}"
2245     echo "${pname}"
2246     }
2247    
2248     # returns pver from pkgname
2249     # pkgname2pver $PKGNAME
2250     pkgname2pver()
2251     {
2252     local i pver
2253    
2254     i="${1/$(pkgname2pname $1)-/}"
2255     pver="${i%-*-*}"
2256     echo "${pver}"
2257     }
2258    
2259     # returns pbuild from pkgname
2260     # pkgname2pbuild $PKGNAME
2261     pkgname2pbuild()
2262     {
2263     local pbuild
2264    
2265     pbuild="${1##*-}"
2266     echo "${pbuild}"
2267     }
2268    
2269     # returns parch from pkgname
2270     # pkgname2parch $PKGNAME
2271     pkgname2parch()
2272     {
2273     local i x parch
2274    
2275     i="${1%-*-*}-"
2276     x="${1%-*}"
2277     parch="${x/${i}/}"
2278     echo "${parch}"
2279     }
2280    
2281     # returns pname from magename
2282     # magename2pname /PATH/TO/MAGE/FILE
2283     magename2pname()
2284     {
2285     local i pname
2286    
2287     i="$(basename $1 .mage)"
2288     pname="${i%-*-*}"
2289     echo "${pname}"
2290     }
2291    
2292     # returns pver from magename
2293     # magename2pver /PATH/TO/MAGE/FILE
2294     magename2pver()
2295     {
2296     local i pver
2297    
2298     i="$(basename $1 .mage)"
2299     i="${i/$(magename2pname $1)-/}"
2300     pver="${i%-*}"
2301     echo "${pver}"
2302     }
2303    
2304     # returns pbuild from magename
2305     # magename2pbuild /PATH/TO/MAGE/FILE
2306     magename2pbuild()
2307     {
2308     local i pbuild
2309    
2310     i="$(basename $1 .mage)"
2311     pbuild="${i##*-}"
2312     echo "${pbuild}"
2313     }
2314    
2315     # returns pcat from magename
2316     # magename2pcat /PATH/TO/MAGE/FILE
2317     magename2pcat()
2318     {
2319     local i pcat
2320    
2321     if [[ ${2} = installdb ]]
2322     then
2323     # go 1 dir back
2324     i="${1%/*}"
2325     else
2326     # go 2 dirs back
2327     i="${1%/*/*}"
2328     fi
2329    
2330     # get basename
2331     pcat="${i##*/}"
2332     echo "${pcat}"
2333     }
2334    
2335     # returns pcat from DEPEND (without operand ! PCAT/PNAME-VERSION)
2336     # dep2pcat DEPEND
2337     dep2pcat()
2338     {
2339     local pcat
2340    
2341     pcat="${1%/*}"
2342     echo "${pcat}"
2343     }
2344    
2345     # returns pname from DEPEND (without operand ! PCAT/PNAME-VERSION)
2346     # $2=virtual is used to resolv VDEPEND from virtual packages
2347     # dep2pcat DEPEND (virtual)
2348     dep2pname()
2349     {
2350     local pname
2351    
2352     pname="${1##*/}"
2353    
2354     # cut version only if not virtual or it will cut the name
2355     if [[ $(dep2pcat $1) != virtual ]] && \
2356     [[ $2 != virtual ]]
2357     then
2358     pname="${pname%-*}"
2359     fi
2360    
2361     echo "${pname}"
2362     }
2363    
2364     dep2highest_magefile()
2365     {
2366     local pcat
2367     local pname
2368     local magefile
2369     local installed_virtuals
2370    
2371     pcat="$(dep2pcat $1)"
2372     pname="$(dep2pname $1)"
2373    
2374     if [[ ${pcat} = virtual ]]
2375     then
2376     # first check if virtual is already installed
2377     installed_virtuals="$(virtuals_read ${pcat}/${pname} showpkgs)"
2378     if [ -n "${installed_virtuals}" ]
2379     then
2380     for vpkg in ${installed_virtuals}
2381     do
2382     realpkgname="${vpkg}"
2383     virtualpkgname="${pcat}/${pname}"
2384     pcat="$(dep2pcat ${realpkgname})"
2385     pname="$(dep2pname ${realpkgname} virtual)"
2386     done
2387     else
2388     # choose one from virtualdb defaults (virtuals.defaults)
2389     realpkgname="$(default_virtualname_to_pkgname ${pcat}/${pname})"
2390     virtualpkgname="${pcat}/${pname}"
2391     pcat="$(dep2pcat ${realpkgname})"
2392     pname="$(dep2pname ${realpkgname} virtual)"
2393     fi
2394     fi
2395    
2396     magefile="$(get_highest_magefile ${pcat} ${pname})"
2397     echo "${magefile}"
2398     }
2399    
2400     # is_installed ${PCAT}/${PNAME}-${PVER}-${PBUILD}
2401     is_installed()
2402     {
2403     local fullpkgname="$1"
2404    
2405     # return 0 if installed
2406     [ -d ${MROOT}${INSTALLDB}/${fullpkgname} ] && return 0
2407    
2408     return 1
2409     }
2410    
2411     install_packages()
2412     {
2413     local list="$@"
2414     local pkg
2415     local pcat
2416     local pname
2417     local pver
2418     local pbuild
2419     local total_pkgs
2420     local current_pkg
2421     local src_install
2422     local uninstall_list
2423    
2424     # check for --src-install
2425     if [[ $1 = --src-install ]]
2426     then
2427     # remove --src-install from list
2428     list=${list/--src-install/}
2429     # enable src-install
2430     src_install="--src-install"
2431     fi
2432    
2433     # reset MAGE_PROTECT_COUNTER
2434     declare -i MAGE_PROTECT_COUNTER=0
2435     export MAGE_PROTECT_COUNTER
2436    
2437     # get count of total packages
2438     declare -i total_pkgs=0
2439     declare -i current_pkg=0
2440     for i in ${list}; do (( total_pkgs++ )); done
2441    
2442     echo
2443    
2444     if [[ -n ${MROOT} ]]
2445     then
2446     echo -ne ${COLRED}
2447     echo "!! installing in MROOT=${MROOT}"
2448     echo -ne ${COLDEFAULT}
2449     echo
2450     fi
2451    
2452     for pkg in ${list}
2453     do
2454     (( current_pkg++ ))
2455     pcat=$(magename2pcat ${pkg})
2456     pname=$(magename2pname ${pkg})
2457     pver=$(magename2pver ${pkg})
2458     pbuild=$(magename2pbuild ${pkg})
2459    
2460     mage_install \
2461     --pcat ${pcat} \
2462     --pname ${pname} \
2463     --pver ${pver} \
2464     --pbuild ${pbuild} \
2465     --count-total ${total_pkgs} \
2466     --count-current ${current_pkg} \
2467     ${src_install}
2468    
2469     # check for allready installed packages and remove them
2470     # except the package we have installed
2471     uninstall_list="$(get_uninstall_candidates \
2472     --pcat "${pcat}" \
2473     --pname "${pname}" \
2474     --protected ${pcat}/${pname}-${pver}-${pbuild})"
2475    
2476     # uninstall all packges in uninstall_list if not empty
2477     if [ -n "${uninstall_list}" ]
2478     then
2479     echo
2480     uninstall_packages ${uninstall_list} \
2481     || die "install_packges() uninstalling not-needed."
2482     fi
2483    
2484     # crlf for better view in VERBOSE mode
2485     #if [[ ${VERBOSE} = on ]]; then echo; fi
2486     echo
2487     done
2488    
2489     #echo "DEBUG MAGE_PROTECT_COUNTER=${MAGE_PROTECT_COUNTER}"
2490     show_etc_update_mesg
2491     }
2492    
2493     # get_value_from_magefile VARIABLE
2494     # returns the content of this VAR
2495     get_value_from_magefile()
2496     {
2497     local var="$1"
2498     local magefile="$2"
2499     local value
2500    
2501 niro 370 [[ -z ${var} ]] && return 1
2502     [[ -z ${magefile} ]] && return 1
2503    
2504 niro 226 # local all possible vars of a mage file
2505     # to prevent bad issues
2506     local PKGNAME
2507     local STATE
2508     local DESCRIPTION
2509     local HOMEPAGE
2510     local DEPEND
2511     local SDEPEND
2512     local PROVIDE
2513     local PKGTYPE
2514 niro 943 local MAGE_TARGETS
2515     local SPLIT_PACKAGE_BASE
2516 niro 226 local preinstall
2517     local postinstall
2518 niro 248 local preremove
2519     local postremove
2520 niro 226
2521     # sanity checks
2522     [ -f ${magefile} ] && source ${magefile} || \
2523     die "get_value_from_magefile: ${magefile} not found."
2524     [ -z "${var}" ] && die "get_value_from_magefile: \$var not given."
2525    
2526     source ${magefile}
2527     eval value=\$$(echo ${var})
2528     echo "${value}"
2529 niro 248
2530 niro 258 # unset these functions
2531     unset -f preinstall
2532     unset -f postinstall
2533     unset -f preremove
2534     unset -f postremove
2535 niro 226 }
2536    
2537     mage_install()
2538     {
2539     # local all possible vars of a mage file
2540     # to prevent bad issues
2541     local PKGNAME
2542     local STATE
2543     local DESCRIPTION
2544     local HOMEPAGE
2545     local DEPEND
2546     local SDEPEND
2547     local PROVIDE
2548     local PKGTYPE
2549     local preinstall
2550     local postinstall
2551 niro 248 local preremove
2552     local postremove
2553 niro 226
2554     local pcat
2555     local pname
2556     local pver
2557     local pbuild
2558     local count_total
2559     local count_current
2560     local magefile
2561     local src_install
2562 niro 876 local i
2563 niro 226
2564     # very basic getops
2565     for i in $*
2566     do
2567     case $1 in
2568     --pcat|-c) shift; pcat="$1" ;;
2569     --pname|-n) shift; pname="$1" ;;
2570     --pver|-v) shift; pver="$1" ;;
2571     --pbuild|-b) shift; pbuild="$1" ;;
2572     --count-total) shift; count_total="$1" ;;
2573     --count-current) shift; count_current="$1" ;;
2574     --src-install|-s) shift; src_install=true ;;
2575     esac
2576     shift
2577     done
2578    
2579     # sanity checks; abort if not given
2580     [ -z "${pcat}" ] && die "mage_install() \$pcat not given."
2581     [ -z "${pname}" ] && die "mage_install() \$pname not given."
2582     [ -z "${pver}" ] && die "mage_install() \$pver not given."
2583     [ -z "${pbuild}" ] && die "mage_install() \$pbuild not given."
2584    
2585     # check needed global vars
2586     [ -z "${MAGEDIR}" ] && die "mage_install() \$MAGEDIR not set."
2587     [ -z "${INSTALLDB}" ] && die "mage_install() \$INSTALLDB not set."
2588     [ -z "${BUILDDIR}" ] && die "mage_install() \$BUILDDIR not set."
2589    
2590     xtitle "[ (${count_current}/${count_total}) Installing ${pcat}/${pname}-${pver}-${pbuild} ]"
2591     echo -ne "${COLBLUE} >>> ${COLDEFAULT}"
2592     echo -n "installing (${count_current}/${count_total}): "
2593     echo -ne "${COLBLUE}${pcat}/${COLDEFAULT}"
2594     echo -e "${COLGREEN}${pname}-${pver}-${pbuild}${COLDEFAULT}"
2595    
2596     magefile="${MAGEDIR}/${pcat}/${pname}/${pname}-${pver}-${pbuild}.mage"
2597     source ${magefile}
2598    
2599     # abort on sources if no srcinstall
2600     if [[ ${PKGTYPE} = sources ]] && [[ ${src_install} != true ]]
2601     then
2602     echo
2603     echo -e "This Package is a Source Package."
2604     echo
2605     echo -e "Only 'srcinstall' works with this type of packages"
2606     echo -en "If you have done a srcinstall before, "
2607     echo -e "you will find the files in /usr/src."
2608     echo
2609     exit 1
2610     fi
2611    
2612     ## preinstall scripts
2613     if [ -n "$(typeset -f preinstall)" ]
2614     then
2615     echo -e " ${COLBLUE}***${COLDEFAULT} running preinstall ... "
2616     preinstall
2617     unset preinstall
2618     fi
2619    
2620     if [[ ${src_install} = true ]]
2621     then
2622     local smage2file
2623     # check needed global vars
2624     [ -z "${SMAGESCRIPTSDIR}" ] && die "\$SMAGESCRIPTSDIR not set."
2625     [ -z "${SOURCEDIR}" ] && die "\$SOURCEDIR not set."
2626     [ -z "${BINDIR}" ] && die "\$BINDIR not set."
2627    
2628     # build the package first
2629     if [[ ${MAGEDEBUG} = on ]]
2630     then
2631     echo M:${pname}
2632     echo V:${pver}
2633     echo B:${pbuild}
2634     fi
2635    
2636 niro 943 if [[ -n ${MAGE_TARGETS} ]]
2637 niro 675 then
2638 niro 876 # basic svn compat
2639 niro 1502 if [[ -d ${SMAGESCRIPTSDIR}/.svn ]]
2640 niro 876 then
2641 niro 1502 for i in ${SMAGESCRIPTSDIR}/*/${pname/${MAGE_TARGETS}/}/${pname/${MAGE_TARGETS}/}-${pver}-${pbuild}.smage2
2642 niro 876 do
2643     smage2file="${i}"
2644     done
2645     else
2646 niro 943 smage2file=${SMAGESCRIPTSDIR}/${pname/${MAGE_TARGETS}/}/${pname/${MAGE_TARGETS}/}-${pver}-${pbuild}.smage2
2647 niro 876 fi
2648 niro 943
2649     elif [[ -n ${SPLIT_PACKAGE_BASE} ]]
2650     then
2651     # basic svn compat
2652 niro 1502 if [[ -d ${SMAGESCRIPTSDIR}/.svn ]]
2653 niro 943 then
2654 niro 1502 for i in ${SMAGESCRIPTSDIR}/*/${SPLIT_PACKAGE_BASE}/${SPLIT_PACKAGE_BASE}-${pver}-${pbuild}.smage2
2655 niro 943 do
2656     smage2file="${i}"
2657     done
2658     else
2659     smage2file=${SMAGESCRIPTSDIR}/${SPLIT_PACKAGE_BASE}/${SPLIT_PACKAGE_BASE}-${pver}-${pbuild}.smage2
2660     fi
2661    
2662 niro 675 else
2663 niro 876 # basic svn compat
2664 niro 1502 if [[ -d ${SMAGESCRIPTSDIR}/.svn ]]
2665 niro 876 then
2666 niro 1502 for i in ${SMAGESCRIPTSDIR}/*/${pname}/${pname}-${pver}-${pbuild}.smage2
2667 niro 876 do
2668     smage2file="${i}"
2669     done
2670     else
2671 niro 943 smage2file=${SMAGESCRIPTSDIR}/${pname}/${pname}-${pver}-${pbuild}.smage2
2672 niro 876 fi
2673 niro 675 fi
2674 niro 943
2675 niro 226 if [ -f "${smage2file}" ]
2676     then
2677 niro 385 echo -e " ${COLBLUE}***${COLDEFAULT} building package from source ... "
2678 niro 226 smage2 ${smage2file} || die "compile failed"
2679     else
2680     echo
2681     echo "$(basename ${SMAGEFILE}) not found."
2682     echo "update your smage-tree and try it again."
2683     echo
2684     die
2685     fi
2686     fi
2687    
2688     if [[ ${PKGTYPE} != virtual ]] && \
2689     [[ ${PKGTYPE} != sources ]]
2690     then
2691 niro 385 echo -e " ${COLBLUE}***${COLDEFAULT} merging files into system ... "
2692 niro 226 build_doinstall ${PKGNAME}
2693     fi
2694    
2695     ## postinstall scripts
2696     if [ -n "$(typeset -f postinstall)" ]
2697     then
2698     echo -e " ${COLBLUE}***${COLDEFAULT} running postinstall ... "
2699     postinstall
2700     unset postinstall
2701     fi
2702    
2703     # install a database entry
2704     install_database_entry \
2705     --pcat "${pcat}" \
2706     --pname "${pname}" \
2707     --pver "${pver}" \
2708     --pbuild "${pbuild}" \
2709     --pkgname "${PKGNAME}" \
2710     --pkgtype "${PKGTYPE}" \
2711     || die "error in mage_install() running install_database_entry()."
2712    
2713     # remove the package dir now
2714     if [ -d ${BUILDDIR}/${PKGNAME} ]
2715     then
2716     rm -rf ${BUILDDIR}/${PKGNAME}
2717     fi
2718    
2719     # rebuilds toplevel info node
2720     if [[ ${MAGE_INFO_REBUILD} = true ]]
2721     then
2722     echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2723     echo -n "rebuilding top-level info node ... "
2724     ${MLIBDIR}/mkinfodir ${MROOT}/usr/share/info \
2725     > ${MROOT}/usr/share/info/dir && \
2726     echo "done." || echo "failure."
2727     unset MAGE_INFO_REBUILD
2728     fi
2729    
2730     # rebuilds the enviroment with the content of /etc/env.d
2731     if [[ ${MAGE_ENV_REBUILD} = true ]]
2732     then
2733     echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2734     echo -n "rebuilding environment ... "
2735     ${MLIBDIR}/env-rebuild.sh > /dev/null && \
2736     echo "done." || echo "failure."
2737     unset MAGE_ENV_REBUILD
2738     fi
2739    
2740     xtitleclean
2741    
2742     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2743     echo -n "package "
2744     # echo -ne "${COLBLUE}${pcat}/${COLDEFAULT}"
2745     # echo -ne "${COLGREEN}${pname}-${pver}-${pbuild}${COLDEFAULT} "
2746     echo "successfully installed."
2747 niro 248
2748 niro 258 # unset these functions
2749     unset -f preinstall
2750     unset -f postinstall
2751     unset -f preremove
2752     unset -f postremove
2753 niro 226 }
2754    
2755     md5sum_packages()
2756     {
2757     local list="$@"
2758     local magefile
2759     local pcat
2760     local pname
2761     local pkgname
2762     local pkgfile
2763     local pkgtype
2764     local count_current
2765     local count_total
2766    
2767     # get count of total packages
2768     declare -i count_current=0
2769     declare -i count_total=0
2770    
2771     for i in ${list}; do (( count_total++ )); done
2772    
2773     for magefile in ${list}
2774     do
2775     pcat=$(magename2pcat ${magefile})
2776     pname=$(magename2pname ${magefile})
2777     pkgname="$(get_value_from_magefile PKGNAME ${magefile})"
2778     md5file="${MAGEDIR}/${pcat}/${pname}/md5/${pkgname}.md5"
2779     pkgfile="$(get_value_from_magefile PKGNAME ${magefile}).${PKGSUFFIX}"
2780     pkgtype="$(get_value_from_magefile PKGTYPE ${magefile})"
2781    
2782     (( count_current++ ))
2783     xtitle "[ (${count_current}/${count_total}) MD5SUM: ${pkgfile} ]"
2784    
2785     # abort on virtual pkg
2786     if [[ ${pkgtype} = virtual ]]
2787     then
2788     echo -ne " ${COLBLUE}---${COLDEFAULT}"
2789     echo " !md5sum virtual (${count_current}/${count_total}): ${pkgfile/.${PKGSUFFIX}/} ... "
2790     continue
2791     fi
2792    
2793     # abort on sources pkg
2794     if [[ ${pkgtype} = sources ]]
2795     then
2796     echo -ne " ${COLBLUE}---${COLDEFAULT}"
2797     echo " !md5sum sources (${count_current}/${count_total}): ${pkgfile/.${PKGSUFFIX}/} ... "
2798     continue
2799     fi
2800    
2801     if [ -f "${md5file}" ]
2802     then
2803     echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2804     echo -ne "checking md5sum (${count_current}/${count_total}): "
2805 niro 1652 mchecksum --rundir "${PKGDIR}" --file "${md5file}" --method md5 || die "md5 for ${pkgfile} failed"
2806 niro 226 else
2807     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2808     echo -e "!! no md5sum file found for ${pkgfile} :("
2809     fi
2810     done
2811    
2812     # add a crlf for a better view
2813     if [ ${count_total} -gt 1 ]; then echo; fi
2814     }
2815    
2816     ## uninstall_packages ulist
2817     uninstall_packages()
2818     {
2819     local list="$@"
2820     local pcat
2821     local pname
2822     local pver
2823     local pbuild
2824     local can_pcat
2825     local can_pname
2826     local can_ver_list
2827    
2828     if [[ -n ${MROOT} ]]
2829     then
2830     echo -ne ${COLRED}
2831     echo "!! uninstalling from MROOT=${MROOT}"
2832     echo -ne ${COLDEFAULT}
2833     echo
2834     fi
2835    
2836     # generate a candidates list
2837     for pkg in ${list}
2838     do
2839     pcat=$(dep2pcat ${pkg})
2840     pname=$(magename2pname ${pkg})
2841     pver=$(magename2pver ${pkg})
2842     pbuild=$(magename2pbuild ${pkg})
2843     can_pcat="${pcat}"
2844     can_pname="${pname}"
2845    
2846     if [ -z "${can_ver_list}" ]
2847     then
2848     can_ver_list=" ${pver}-${pbuild}"
2849     else
2850     can_ver_list="${can_ver_list}, ${pver}-${pbuild}"
2851     fi
2852     done
2853    
2854     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2855     echo "following candidate(s) will be removed:"
2856     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2857 niro 240 echo -ne "${COLBOLD}${can_pcat}/${can_pname}:${COLDEFAULT}"
2858 niro 226 echo -e "${COLRED} ${can_ver_list} ${COLDEFAULT}"
2859 niro 501 echo
2860 niro 240 if [ ${MAGE_UNINSTALL_TIMEOUT} -gt 0 ]
2861     then
2862     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2863     echo "( Press [CTRL+C] to abort )"
2864     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
2865     echo -n "Waiting ${MAGE_UNINSTALL_TIMEOUT} seconds ..."
2866     for ((i=MAGE_UNINSTALL_TIMEOUT; i >= 0; i--))
2867     do
2868     echo -ne "${COLRED} ${i}${COLDEFAULT}"
2869     sleep 1
2870     done
2871     echo
2872     echo
2873     fi
2874 niro 226
2875     for pkg in ${list}
2876     do
2877     pcat=$(dep2pcat ${pkg})
2878     pname=$(magename2pname ${pkg})
2879     pver=$(magename2pver ${pkg})
2880     pbuild=$(magename2pbuild ${pkg})
2881    
2882     mage_uninstall \
2883     --pcat ${pcat} \
2884     --pname ${pname} \
2885     --pver ${pver} \
2886     --pbuild ${pbuild} \
2887     --count-total ${total_pkgs} \
2888     --count-current ${current_pkg} \
2889     ${src_install}
2890    
2891     # crlf for better view in VERBOSE mode
2892     #if [[ ${VERBOSE} = on ]]; then echo; fi
2893     echo
2894     done
2895     }
2896    
2897     mage_uninstall()
2898     {
2899     # local all possible vars of a mage file
2900     # to prevent bad issues
2901     local PKGNAME
2902     local STATE
2903     local DESCRIPTION
2904     local HOMEPAGE
2905     local DEPEND
2906     local SDEPEND
2907     local PROVIDE
2908     local PKGTYPE
2909     local preinstall
2910     local postinstall
2911 niro 248 local preremove
2912     local postremove
2913 niro 226
2914     local pcat
2915     local pname
2916     local pver
2917     local pbuild
2918     local magefile
2919     local i
2920    
2921     # very basic getops
2922     for i in $*
2923     do
2924     case $1 in
2925 niro 501 --pcat|-c) shift; pcat="$1" ;;
2926 niro 226 --pname|-n) shift; pname="$1" ;;
2927     --pver|-v) shift; pver="$1" ;;
2928 niro 501 --pbuild|-b) shift; pbuild="$1" ;;
2929 niro 226 esac
2930     shift
2931 niro 501 done
2932 niro 226
2933     # sanity checks; abort if not given
2934 niro 501 [ -z "${pcat}" ] && die "mage_uninstall() \$pcat not given."
2935 niro 226 [ -z "${pname}" ] && die "mage_uninstall() \$pname not given."
2936     [ -z "${pver}" ] && die "mage_uninstall() \$pver not given."
2937 niro 501 [ -z "${pbuild}" ] && die "mage_uninstall() \$pbuild not given."
2938 niro 226
2939     # check needed global vars
2940     [ -z "${MAGEDIR}" ] && die "mage_uninstall() \$MAGEDIR not set."
2941     [ -z "${INSTALLDB}" ] && die "mage_uninstall() \$INSTALLDB not set."
2942     [ -z "${BUILDDIR}" ] && die "mage_uninstall() \$BUILDDIR not set."
2943    
2944     xtitle "[ (${count_current}/${count_total}) Removing ${pcat}/${pname}-${pver}-${pbuild} ]"
2945     echo -ne "${COLBLUE} <<< ${COLDEFAULT}"
2946     echo -n "removing: "
2947     echo -ne "${COLBLUE}${pcat}/${COLDEFAULT}"
2948 niro 416 echo -e "${COLRED}${pname}-${pver}-${pbuild}${COLDEFAULT}"
2949 niro 226
2950 niro 499 magefile="${MROOT}${INSTALLDB}/${pcat}/${pname}-${pver}-${pbuild}/${pname}-${pver}-${pbuild}.mage"
2951 niro 226 source ${magefile}
2952    
2953     ## preremove scripts
2954     if [ -n "$(typeset -f preremove)" ]
2955     then
2956     echo -e " ${COLBLUE}***${COLDEFAULT} running preremove ... "
2957     preremove
2958     unset preremove
2959     fi
2960    
2961     # runs uninstall
2962     build_douninstall \
2963     --pcat "${pcat}" \
2964     --pname "${pname}" \
2965     --pver "${pver}" \
2966     --pbuild "${pbuild}"
2967    
2968     ## postremove scripts
2969     if [ -n "$(typeset -f postremove)" ]
2970     then
2971     echo -e " ${COLBLUE}***${COLDEFAULT} running postremove ... "
2972     postremove
2973     unset postremove
2974     fi
2975    
2976     # removes the database entry
2977     remove_database_entry \
2978     --pcat "${pcat}" \
2979     --pname "${pname}" \
2980     --pver "${pver}" \
2981     --pbuild "${pbuild}" \
2982     || die "error in mage_uninstall() running remove_database_entry()."
2983    
2984     # rebuilds toplevel info node
2985     if [[ ${MAGE_INFO_REBUILD} = true ]]
2986     then
2987     echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2988     echo -n "rebuilding top-level info node ... "
2989     ${MLIBDIR}/mkinfodir ${MROOT}/usr/share/info \
2990     > ${MROOT}/usr/share/info/dir && \
2991     echo "done." || echo "failure."
2992     unset MAGE_INFO_REBUILD
2993     fi
2994    
2995     # rebuilds the enviroment with the content of /etc/env.d
2996     if [[ ${MAGE_ENV_REBUILD} = true ]]
2997     then
2998     echo -ne "${COLBLUE} *** ${COLDEFAULT}"
2999     echo -n "rebuilding environment ... "
3000     ${MLIBDIR}/env-rebuild.sh > /dev/null && \
3001     echo "done." || echo "failure."
3002     unset MAGE_ENV_REBUILD
3003     fi
3004    
3005     echo -ne "${COLBLUE} --- ${COLDEFAULT}"
3006     echo -n "package "
3007     # echo -ne "${COLBLUE}${pcat}/${COLDEFAULT}"
3008     # echo -ne "${COLGREEN}${pname}-${pver}-${pbuild}${COLDEFAULT} "
3009     echo "successfully removed."
3010 niro 248
3011 niro 258 # unset these functions
3012     unset -f preinstall
3013     unset -f postinstall
3014     unset -f preremove
3015     unset -f postremove
3016 niro 226 }
3017    
3018 niro 1209 show_etc_update_mesg()
3019     {
3020 niro 226 [ ${MAGE_PROTECT_COUNTER} -eq 0 ] && return 0
3021    
3022     echo
3023     echo -ne "${COLRED}"
3024     echo "Important:"
3025     echo -ne ${COLDEFAULT}
3026     echo "${MAGE_PROTECT_COUNTER} protected file(s) were installed."
3027     echo
3028     echo "Please run 'etc-update' to update your configuration files."
3029     echo
3030     }
3031 niro 237
3032     pkgsearch()
3033     {
3034     local string="$1"
3035     local result
3036     local pkg
3037     local pcat
3038     local pname
3039     local magefile
3040     local pver
3041     local pbuild
3042     local state
3043     local descriptiom
3044     local homepage
3045 niro 1648 local license
3046 niro 237 local i
3047     local all_installed
3048     local ipver
3049     local ipbuild
3050 niro 445 local latest_available
3051 niro 458 local depsfull
3052     local sdepsfull
3053     local deps
3054     local sdeps
3055     local dep
3056     local sign
3057 niro 237
3058     # only names no versions
3059 niro 391 result="$(find ${MAGEDIR} -mindepth 2 -maxdepth 2 -type d -name '*'${string}'*'| sed '/profiles/d' | sed '/includes/d')"
3060 niro 328 #result="$(find ${MAGEDIR} -type f -name '*'${string}'*'.mage | sort)"
3061 niro 237
3062     # nothing found
3063     [[ -z ${result} ]] && die "No package found containing '${string}' in the name."
3064    
3065     for pkg in ${result}
3066     do
3067     # dirty, but does the job
3068     pcat="$(magename2pcat ${pkg}/foo)"
3069     pname="$(magename2pname ${pkg}-foo-foo)"
3070    
3071     # get highest version available
3072     magefile=$(get_highest_magefile ${pcat} ${pname})
3073    
3074 niro 445 if [[ ! -z ${magefile} ]]
3075     then
3076     # now get all needed infos to print a nice output
3077     pver="$(magename2pver ${magefile})"
3078     pbuild="$(magename2pbuild ${magefile})"
3079     state="$(get_value_from_magefile STATE ${magefile})"
3080     description="$(get_value_from_magefile DESCRIPTION ${magefile})"
3081     homepage="$(get_value_from_magefile HOMEPAGE ${magefile})"
3082 niro 1648 license="$(get_value_from_magefile LICENSE ${magefile})"
3083    
3084 niro 445 # all installed
3085     for i in $(get_uninstall_candidates --pname ${pname} --pcat ${pcat})
3086     do
3087     ipver="$(magename2pver ${i})"
3088     ipbuild="$(magename2pbuild ${i})"
3089 niro 1648
3090 niro 445 if [[ -z ${all_installed} ]]
3091     then
3092     all_installed="${ipver}-${ipbuild}"
3093     else
3094     all_installed="${all_installed} ${ipver}-${ipbuild}"
3095     fi
3096     done
3097     [[ -z ${all_installed} ]] && all_installed="none"
3098 niro 1648
3099 niro 445 case ${state} in
3100     stable) state=${COLGREEN}"[s] ";;
3101     testing) state=${COLYELLOW}"[t] ";;
3102     unstable) state=${COLRED}"[u] ";;
3103     old) state=${COLGRAY}"[o] ";;
3104     esac
3105 niro 237
3106 niro 445 latest_available="${pver}-${pbuild}"
3107     else
3108     # package is masked
3109     state="${COLRED}[m] "
3110     latest_available="${COLRED}masked for this distribution.${COLDEFAULT}"
3111     fi
3112 niro 237
3113 niro 458 depsfull="$(get_value_from_magefile DEPEND ${magefile})"
3114     sdepsfull="$(get_value_from_magefile SDEPEND ${magefile})"
3115    
3116     while read sign dep
3117     do
3118     case ${dep} in
3119     "") continue;;
3120     esac
3121    
3122 niro 1961 if [[ -z ${deps} ]]
3123     then
3124     deps="$(basename ${dep%-*})"
3125     else
3126     deps="${deps} $(basename ${dep%-*})"
3127     fi
3128 niro 458 done << EOF
3129     ${depsfull}
3130     EOF
3131    
3132     while read sign dep
3133     do
3134     case ${dep} in
3135     "") continue;;
3136     esac
3137    
3138 niro 1961 if [[ -z ${sdeps} ]]
3139     then
3140     sdeps="$(basename ${dep%-*})"
3141     else
3142     sdeps="${sdeps} $(basename ${dep%-*})"
3143     fi
3144 niro 458 done << EOF
3145     ${sdepsfull}
3146     EOF
3147    
3148 niro 237 echo -e "${state}${pcat}/${pname}"${COLDEFAULT}
3149 niro 445 echo -e " Latest available: ${latest_available}"
3150 niro 237 echo " Installed versions: ${all_installed}"
3151     echo " Description: ${description}"
3152     echo " Homepage: ${homepage}"
3153 niro 1648 if [[ ! -z ${license} ]]
3154     then
3155     echo " License: ${license}"
3156     fi
3157 niro 1961 echo " Depends: ${deps}"
3158 niro 458 echo " SDepends: ${sdeps}"
3159 niro 237 echo
3160    
3161     unset pcat
3162     unset pname
3163     unset magefile
3164     unset pver
3165     unset pbuild
3166     unset state
3167     unset descriptiom
3168     unset homepage
3169     unset all_installed
3170     unset ipver
3171     unset ipbuild
3172 niro 458 unset depsfull
3173     unset sdepsfull
3174     unset deps
3175     unset sdeps
3176     unset dep
3177     unset sign
3178 niro 237 done
3179     }
3180 niro 249
3181     export_inherits()
3182     {
3183     local include="$1"
3184     shift
3185    
3186     while [ "$1" ]
3187     do
3188     local functions="$1"
3189    
3190     # sanity checks
3191     [ -z "${include}" ] && die "export_inherits(): \$include not given."
3192     [ -z "${functions}" ] && die "export_inherits(): \$functions not given."
3193    
3194     eval "${functions}() { ${include}_${functions} ; }"
3195    
3196     # debug
3197 niro 1584 mqueryfeature "debug" && typeset -f "${functions}"
3198 niro 249
3199     shift
3200     done
3201     }
3202 niro 350
3203     mlibdir()
3204     {
3205     local libdir=lib
3206     [[ ${ARCH} = x86_64 ]] && libdir=lib64
3207    
3208     echo "${libdir}"
3209     }
3210 niro 370
3211     ## blacklisted ${magefile}
3212     blacklisted()
3213     {
3214     [[ -z ${MAGE_DISTRIBUTION} ]] && local MAGE_DISTRIBUTION=stable
3215    
3216     # compat
3217     [[ ${USE_UNSTABLE} = true ]] && local MAGE_DISTRIBUTION=unstable
3218     [[ ${USE_TESTING} = true ]] && local MAGE_DISTRIBUTION=testing
3219    
3220 niro 892 # support both types for the moment
3221     if [[ -f /etc/mage-profile/package.blacklist-${ARCH}-${MAGE_DISTRIBUTION} ]]
3222     then
3223     local EXCLUDED="/etc/mage-profile/package.blacklist-${ARCH}-${MAGE_DISTRIBUTION}"
3224     else
3225     local EXCLUDED="/etc/mage-profile/package.blacklist-${ARCH}"
3226     fi
3227 niro 370
3228     # return 0 if the list not exist; nothin is masked
3229     [[ ! -f ${EXCLUDED} ]] && return 0
3230    
3231     local MAGEFILE="$1"
3232    
3233     local PCAT="$(magename2pcat ${MAGEFILE})"
3234     local PNAME="$(magename2pname ${MAGEFILE})"
3235     local PVER="$(magename2pver ${MAGEFILE})"
3236     local PBUILD="$(magename2pbuild ${MAGEFILE})"
3237    
3238     local EXPCAT EXPNAME EXPVER EXPBUILD
3239     while read EXPCAT EXPNAME EXPVER EXPBUILD
3240     do
3241     # ignore spaces and comments
3242     case "${EXPCAT}" in
3243     \#*|"") continue ;;
3244     esac
3245    
3246     # exclude full pver
3247     if [[ -n ${PCAT} ]] && [[ -n ${PNAME} ]] &&
3248     [[ -n ${EXPCAT} ]] && [[ -n ${EXPNAME} ]] &&
3249     [[ -n ${PVER} ]] && [[ -n ${PBUILD} ]] &&
3250     [[ -n ${EXPVER} ]] && [[ -n ${EXPBUILD} ]]
3251     then
3252     [[ ${EXPCAT}/${EXPNAME}-${EXPVER}-${EXPBUILD} = ${PCAT}/${PNAME}-${PVER}-${PBUILD} ]] && return 1
3253     fi
3254    
3255     # exclude pcat/pname only
3256     if [[ -n ${PCAT} ]] && [[ -n ${PNAME} ]] &&
3257     [[ -n ${EXPCAT} ]] && [[ -n ${EXPNAME} ]] &&
3258     [[ -z ${EXPVER} ]] && [[ -z ${EXPBUILD} ]]
3259     then
3260     [[ ${EXPCAT}/${EXPNAME} = ${PCAT}/${PNAME} ]] && return 1
3261     fi
3262     done << EOF
3263     $( cat ${EXCLUDED}; echo)
3264     EOF
3265    
3266     return 0
3267     }
3268    
3269 niro 1273 # need_busybox_support ${cmd}
3270     # return 0 (no error = needs busybox support) or return 1 (error = no busybox support required)
3271     need_busybox_support()
3272     {
3273     local cmd
3274 niro 1952 local busybox
3275 niro 1273 cmd="$1"
3276    
3277 niro 1952 for busybox in {,/usr}/bin/busybox
3278     do
3279     if [[ -x ${busybox} ]]
3280 niro 1273 then
3281 niro 1952 if [[ $(readlink $(which ${cmd})) = ${busybox} ]]
3282     then
3283     # needs busybox support
3284     return 0
3285     fi
3286 niro 1273 fi
3287 niro 1952 done
3288 niro 1318
3289     # no busybox
3290     return 1
3291 niro 1273 }
3292    
3293     # busybox_filter_wget_options ${wget_opts}
3294     busybox_filter_wget_options()
3295     {
3296     local opts="$@"
3297     local i
3298     local fixed_opts
3299    
3300     if need_busybox_support wget
3301     then
3302     for i in ${opts}
3303     do
3304     # show only the allowed ones
3305     case ${i} in
3306     -c|--continue) fixed_opts+=" -c" ;;
3307     -s|--spider) fixed_opts+=" -s" ;;
3308     -q|--quiet) fixed_opts+=" -q" ;;
3309     -O|--output-document) shift; fixed_opts+=" -O $1" ;;
3310     --header) shift; fixed_opts+=" --header $1" ;;
3311     -Y|--proxy) shift; fixed_opts+=" -Y $1" ;;
3312     -P) shift; fixed_opts+=" -P $1" ;;
3313     --no-check-certificate) fixed_opts+=" --no-check-certificate ${i}" ;;
3314     -U|--user-agent) shift; fixed_opts+=" -U ${i}" ;;
3315     # simply drop all other opts
3316     *) continue ;;
3317     esac
3318     done
3319    
3320     echo "${fixed_opts}"
3321     else
3322     echo "${opts}"
3323     fi
3324     }
3325 niro 1541
3326     have_root_privileges()
3327     {
3328     local retval
3329    
3330     if [[ $(id -u) = 0 ]]
3331     then
3332     retval=0
3333     else
3334     retval=1
3335     fi
3336    
3337     return ${retval}
3338     }
3339 niro 1584
3340     known_mage_feature()
3341     {
3342     local feature="$1"
3343     local retval
3344    
3345     case "${feature}" in
3346     autosvc|!autosvc) retval=0 ;;
3347     buildlog|!buildlog) retval=0 ;;
3348     ccache|!ccache) retval=0 ;;
3349     check|!check) retval=0 ;;
3350     compressdoc|!compressdoc) retval=0 ;;
3351 niro 1627 debug|!debug) retval=0 ;;
3352 niro 1584 distcc|!distcc) retval=0 ;;
3353     kernelsrcunpack|!kernelsrcunpack) retval=0 ;;
3354     libtool|!libtool) retval=0 ;;
3355     linuxsymlink|!linuxsymlink) retval=0 ;;
3356     pkgbuild|!pkgbuild) retval=0 ;;
3357 niro 1649 pkgdistrotag|!pkgdistrotag) retval=0 ;;
3358 niro 1584 purge|!purge) retval=0 ;;
3359     qalint|!qalint) retval=0 ;;
3360     regentree|!regentree) retval=0 ;;
3361 niro 1620 resume|!resume) retval=0 ;;
3362 niro 1584 srcpkgbuild|!srcpkgbuild) retval=0 ;;
3363     srcpkgtarball|!srcpkgtarball) retval=0 ;;
3364 niro 1627 static|!static) retval=0 ;;
3365     stepbystep|!stepbystep) retval=0 ;;
3366 niro 1584 strip|!strip) retval=0 ;;
3367 niro 1627 verbose|!verbose) retval=0 ;;
3368 niro 1584 *) retval=1 ;;
3369     esac
3370    
3371     return "${retval}"
3372     }
3373    
3374     load_mage_features()
3375     {
3376     for i in ${MAGE_FEATURES_GLOBAL[*]} ${MAGE_FEATURES[*]}
3377     do
3378     FVERBOSE=off msetfeature ${i}
3379     done
3380     }
3381    
3382     msetfeature()
3383     {
3384     local feature
3385     local count
3386     local i
3387     local found
3388    
3389     for feature in $@
3390     do
3391     found=0
3392     count="${#MAGE_FEATURES_CURRENT[*]}"
3393    
3394     if ! known_mage_feature "${feature}"
3395     then
3396 niro 1628 [[ ${FVERBOSE} = off ]] || echo -e "${COLRED}Unknown feature '${feature}', ignoring it${COLDEFAULT}"
3397 niro 1584 return 3
3398     fi
3399    
3400     for ((i=0; i<count; i++))
3401     do
3402     if [[ ${MAGE_FEATURES_CURRENT[${i}]} = ${feature} ]]
3403     then
3404 niro 1599 [[ ${FVERBOSE} = off ]] || echo -e "${COLBLUE}---${COLGREEN} Feature '${feature}' already enabled${COLDEFAULT}"
3405 niro 1584 MAGE_FEATURES_CURRENT[${i}]="${feature}"
3406     found=1
3407     elif [[ ${MAGE_FEATURES_CURRENT[${i}]} = !${feature} ]]
3408     then
3409 niro 1599 [[ ${FVERBOSE} = off ]] || echo -e "${COLBLUE}---${COLGREEN} Feature '${feature}' currently disabled, enabling it!${COLDEFAULT}"
3410 niro 1584 MAGE_FEATURES_CURRENT[${i}]="${feature}"
3411     found=1
3412     elif [[ ${MAGE_FEATURES_CURRENT[${i}]} = ${feature//!} ]]
3413     then
3414 niro 1599 [[ ${FVERBOSE} = off ]] || echo -e "${COLBLUE}---${COLGREEN} Feature '${feature//!}' currently enabled, disabling it!${COLDEFAULT}"
3415 niro 1584 MAGE_FEATURES_CURRENT[${i}]="${feature}"
3416     found=1
3417     fi
3418     done
3419    
3420     # if the feature was not found after proccessing the whole array
3421     # it was not declared. in this case enable it
3422     if [[ ${found} = 0 ]]
3423     then
3424 niro 1599 [[ ${FVERBOSE} = off ]] || echo -e "${COLBLUE}---${COLGREEN} Feature '${feature}' was not declared, enabling it!${COLDEFAULT}"
3425 niro 1584 MAGE_FEATURES_CURRENT=( ${MAGE_FEATURES_CURRENT[*]} "${feature}" )
3426     fi
3427    
3428     export MAGE_FEATURE_CURRENT
3429     done
3430     }
3431    
3432     mqueryfeature()
3433     {
3434     local feature="$1"
3435     local retval=1
3436     local i
3437    
3438     if known_mage_feature "${feature}"
3439     then
3440     for i in ${MAGE_FEATURES_CURRENT[*]}
3441     do
3442     if [[ ${i} = ${feature} ]]
3443     then
3444     retval=0
3445     break # found break here
3446     fi
3447     done
3448     else
3449 niro 1628 [[ ${FVERBOSE} = off ]] || echo -e "${COLRED}Unknown feature '${feature}', ignoring it${COLDEFAULT}"
3450 niro 1584 retval=3
3451     fi
3452    
3453     return ${retval}
3454     }
3455    
3456     mprintfeatures()
3457     {
3458 niro 1781 echo -e "${COLRED}Global features:${COLDEFAULT} ${MAGE_FEATURES_GLOBAL[*]}"
3459     echo -e "${COLYELLOW}Local features:${COLDEFAULT} ${MAGE_FEATURES[*]}"
3460     echo -e "${COLGREEN}Current features:${COLDEFAULT} ${MAGE_FEATURES_CURRENT[*]}"
3461 niro 1584 }