Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


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