1 #!/bin/bash
2 #
3 # pkgutils
4 #
5 # Copyright (c) 2000-2005 Per Liden
6 # Copyright (c) 2006-2021 by CRUX team (http://crux.nu)
7 #
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 # USA.
22 #
23
24 ##
25 # error codes
26 E_GENERAL=1
27 E_PKGFILE=2 # invalid Pkgfile
28 E_DIR_PERM=3 # (source/build) directory missing or missing read/write permission
29 E_DOWNLOAD=4 # error during download
30 E_UNPACK=5 # error during unpacking of source file(s)
31 E_MD5=6 # md5sum verification failed
32 E_FOOTPRINT=7 # footprint check failure
33 E_BUILD=8 # error while running 'build()'
34 E_INSTALL=9 # error while installing the package via 'pkgadd'
35 E_SIGNATURE=10 # error verifying the signature
36
37 info() {
38 echo "=======> $1"
39 }
40
41 warning() {
42 info "WARNING: $1" >&2
43 }
44
45 error() {
46 info "ERROR: $1" >&2
47 }
48
49 get_filename() {
50 local ABSOLUTE=""
51 if [ "$1" = "-a" ]; then
52 ABSOLUTE=1
53 shift
54 fi
55
56 if [[ $1 =~ ^(http|https|ftp|file)://.*/(.+) ]]; then
57 echo "$PKGMK_SOURCE_DIR/${BASH_REMATCH[2]}"
58 else
59 if [ "$ABSOLUTE" ]; then
60 echo $PKGMK_ROOT/$1
61 else
62 echo $1
63 fi
64 fi
65 }
66
67 get_basename() {
68 local FILE="`echo $1 | sed 's|^.*://.*/||g'`"
69 echo $FILE
70 }
71
72 check_pkgfile() {
73 if [ ! "$name" ]; then
74 error "Variable 'name' not specified in $PKGMK_PKGFILE."
75 exit $E_PKGFILE
76 elif [ ! "$version" ]; then
77 error "Variable 'version' not specified in $PKGMK_PKGFILE."
78 exit $E_PKGFILE
79 elif [ ! "$release" ]; then
80 error "Variable 'release' not specified in $PKGMK_PKGFILE."
81 exit $E_PKGFILE
82 elif [ "`type -t build`" != "function" ]; then
83 error "Function 'build' not specified in $PKGMK_PKGFILE."
84 exit $E_PKGFILE
85 fi
86 }
87
88 check_directory() {
89 if [ ! -d $1 ]; then
90 error "Directory '$1' does not exist."
91 exit $E_DIR_PERM
92 elif [ ! -w $1 ]; then
93 error "Directory '$1' not writable."
94 exit $E_DIR_PERM
95 elif [ ! -x $1 ] || [ ! -r $1 ]; then
96 error "Directory '$1' not readable."
97 exit $E_DIR_PERM
98 fi
99 }
100
101 check_file() {
102 if [ -e $1 ] && [ ! -w $1 ]; then
103 error "File '$1' is not writable."
104 exit 1
105 fi
106 }
107
108 download_file() {
109 info "Downloading '$1'."
110
111 PKGMK_DOWNLOAD_PROG=${PKGMK_DOWNLOAD_PROG:-wget}
112 if [ ! "`type -p ${PKGMK_DOWNLOAD_PROG}`" ]; then
113 error "Command '${PKGMK_DOWNLOAD_PROG}' not found."
114 exit $E_GENERAL
115 fi
116
117 LOCAL_FILENAME=`get_filename $1`
118 LOCAL_FILENAME_PARTIAL="$LOCAL_FILENAME.partial"
119
120 case ${PKGMK_DOWNLOAD_PROG} in
121 curl)
122 RESUME_CMD="-C -"
123 DOWNLOAD_OPTS="-L --fail --ftp-pasv --retry 3 --retry-delay 3 \
124 -o $LOCAL_FILENAME_PARTIAL $PKGMK_CURL_OPTS"
125 ;;
126 wget)
127 RESUME_CMD="-c"
128 DOWNLOAD_OPTS="--compression=none --passive-ftp --no-directories --tries=3 --waitretry=3 \
129 --directory-prefix=$PKGMK_SOURCE_DIR \
130 --output-document=$LOCAL_FILENAME_PARTIAL $PKGMK_WGET_OPTS"
131 ;;
132 esac
133
134 if [ -f "$LOCAL_FILENAME_PARTIAL" ]; then
135 info "Partial download found, trying to resume"
136 RESUME_OPTS="$RESUME_CMD"
137 fi
138
139 error=1
140
141 BASENAME=`get_basename $1`
142 for REPO in ${PKGMK_SOURCE_MIRRORS[@]}; do
143 REPO="`echo $REPO | sed 's|/$||'`"
144 $PKGMK_DOWNLOAD_PROG $DOWNLOAD_OPTS $RESUME_OPTS $REPO/$BASENAME
145 error=$?
146 if [ $error == 0 ]; then
147 break
148 fi
149 done
150
151 if [ $error != 0 ]; then
152 while true; do
153 $PKGMK_DOWNLOAD_PROG $DOWNLOAD_OPTS $RESUME_OPTS $1
154 error=$?
155 if [ $error != 0 ] && [ "$RESUME_OPTS" ]; then
156 info "Partial download failed, restarting"
157 rm -f "$LOCAL_FILENAME_PARTIAL"
158 RESUME_OPTS=""
159 else
160 break
161 fi
162 done
163 fi
164
165 if [ $error != 0 -o ! -f "$LOCAL_FILENAME_PARTIAL" ]; then
166 error "Downloading '$1' failed."
167 exit $E_DOWNLOAD
168 fi
169
170 mv -f "$LOCAL_FILENAME_PARTIAL" "$LOCAL_FILENAME"
171 }
172
173 download_source() {
174 local RENAME LOCAL_FILE ORIG_FILE srcind
175
176 srcind=0
177 while [ $srcind -lt ${#source[@]} ]; do
178 ORIG_FILE=`get_filename "${source[$srcind]}"`
179 LOCAL_FILE=$ORIG_FILE
180 RENAME="${renames[$srcind]}"
181 [ -n "$RENAME" -a "$RENAME" != "SKIP" ] && LOCAL_FILE="$PKGMK_SOURCE_DIR/$RENAME"
182 if [ ! -e $LOCAL_FILE ]; then
183 if [ "$ORIG_FILE" = "${source[$srcind]}" ]; then
184 error "Source file '$LOCAL_FILE' not found (can not be downloaded, URL not specified)."
185 exit $E_DOWNLOAD
186 else
187 if [ "$PKGMK_DOWNLOAD" = "yes" ]; then
188 download_file "${source[$srcind]}"
189 [ "$LOCAL_FILE" = "$ORIG_FILE" ] || mv $ORIG_FILE $LOCAL_FILE
190
191 else
192 error "Source file '$LOCAL_FILE' not found (use option -d to download)."
193 exit $E_DOWNLOAD
194 fi
195 fi
196 fi
197 srcind=$(( srcind+1 ))
198 done
199 }
200
201 unpack_source() {
202 local ORIG_FILE RENAME LOCAL_FILE srcind COMMAND
203
204 srcind=0
205 while [ $srcind -lt ${#source[@]} ]; do
206 ORIG_FILE=`get_filename ${source[$srcind]}`
207 LOCAL_FILE=$ORIG_FILE
208 RENAME="${renames[$srcind]}"
209 [ -n "$RENAME" -a "$RENAME" != "SKIP" ] && LOCAL_FILE="$PKGMK_SOURCE_DIR/$RENAME"
210 case $LOCAL_FILE in
211 *.tar|*.tar.gz|*.tar.Z|*.tgz|*.tar.bz2|*.tbz2|*.tar.xz|*.txz|*.tar.lzma|*.tar.lz|*.zip|*.rpm|*.7z)
212 COMMAND="bsdtar -p -o -C $SRC -xf $LOCAL_FILE" ;;
213 *)
214 COMMAND="cp $LOCAL_FILE $SRC" ;;
215 esac
216
217 echo "$COMMAND"
218
219 $COMMAND
220
221 if [ $? != 0 ]; then
222 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
223 rm -rf $PKGMK_WORK_DIR
224 fi
225 error "Building '$TARGET' failed."
226 exit $E_UNPACK
227 fi
228 srcind=$(( srcind+1 ))
229 done
230 }
231
232 make_md5sum() {
233 local srcind FILE LOCAL_FILENAMES
234
235 if [ "$source" ]; then
236 srcind=0
237 while [ $srcind -lt ${#source[@]} ]; do
238 FILE="${source[$srcind]}"
239 if [ -n "${renames[$srcind]}" -a "${renames[$srcind]}" != "SKIP" ]; then
240 LOCAL_FILENAMES="$LOCAL_FILENAMES $PKGMK_SOURCE_DIR/${renames[$srcind]}"
241 elif [ "`get_basename $FILE`" = "$FILE" ]; then
242 LOCAL_FILENAMES="$LOCAL_FILENAMES $FILE"
243 else
244 LOCAL_FILENAMES="$LOCAL_FILENAMES `get_filename $FILE`"
245 fi
246 srcind=$(( srcind+1 ))
247 done
248
249 md5sum $LOCAL_FILENAMES | sed -e 's| .*/| |' | sort -k 2
250 fi
251 }
252
253 make_footprint() {
254 pkginfo --footprint $TARGET | \
255 sed "s|\tlib/modules/`uname -r`/|\tlib/modules/<kernel-version>/|g" | \
256 sort -k 3
257 }
258
259 check_md5sum() {
260 local FILE="$PKGMK_WORK_DIR/.tmp"
261
262 cd $PKGMK_ROOT
263
264 if [ -f $PKGMK_MD5SUM ]; then
265 make_md5sum > $FILE.md5sum
266 sort -k 2 $PKGMK_MD5SUM > $FILE.md5sum.orig
267 diff -w -t -U 0 $FILE.md5sum.orig $FILE.md5sum | \
268 sed '/^@@/d' | \
269 sed '/^+++/d' | \
270 sed '/^---/d' | \
271 sed 's/^+/NEW /g' | \
272 sed 's/^-/MISSING /g' > $FILE.md5sum.diff
273 if [ -s $FILE.md5sum.diff ]; then
274 error "Md5sum mismatch found:"
275 cat $FILE.md5sum.diff >&2
276
277 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
278 rm -rf $PKGMK_WORK_DIR
279 fi
280
281 if [ "$PKGMK_CHECK_MD5SUM" = "yes" ]; then
282 error "Md5sum not ok."
283 exit $E_MD5
284 fi
285
286 error "Building '$TARGET' failed."
287 exit $E_MD5
288 fi
289 else
290 if [ "$PKGMK_CHECK_MD5SUM" = "yes" ]; then
291 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
292 rm -rf $PKGMK_WORK_DIR
293 fi
294 info "Md5sum not found."
295 exit $E_MD5
296 fi
297
298 warning "Md5sum not found, creating new."
299 make_md5sum > $PKGMK_MD5SUM
300 fi
301
302 if [ "$PKGMK_CHECK_MD5SUM" = "yes" ]; then
303 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
304 rm -rf $PKGMK_WORK_DIR
305 fi
306 info "Md5sum ok."
307 exit 0
308 fi
309 }
310
311 # requires a previous call of make_work_dir()
312 check_signature() {
313 local RESULT=0
314 local PUBKEY=""
315
316 if [ -f $PKGMK_ROOT/$PKGMK_SIGNATURE ]; then
317 cd $SRC
318 local srcind=0
319
320 while [ $srcind -lt ${#source[@]} ]; do
321 if [ -n "${renames[$srcind]}" -a "${renames[$srcind]}" != "SKIP" ]; then
322 source[$srcind]="http://somehost/${renames[$srcind]}"
323 fi
324 srcind=$(( srcind+1 ))
325 done
326
327 for FILE in "$PKGMK_PKGFILE" "$PKGMK_FOOTPRINT" "${source[@]}"; do
328 ln -s $(get_filename -a $FILE) .
329 done
330
331 if [ "$PKGMK_PUBLICKEY" ]; then
332 err=$($PKGMK_SIGNIFY -q -C -p "$PKGMK_PUBLICKEY" -x "$PKGMK_ROOT/$PKGMK_SIGNATURE" 2>&1)
333 else
334 err=$($PKGMK_SIGNIFY -q -C -x "$PKGMK_ROOT/$PKGMK_SIGNATURE" 2>&1)
335 fi
336
337 RESULT=$?
338 cd $PKGMK_ROOT
339
340 if [ $RESULT -ne 0 ]; then
341 if [ "$err" = "signify: signature verification failed" ]; then
342 error "Failed verifying cryptographic digest"
343 else
344 error "Signature mismatch found:"
345 echo "$err" | while read n; do echo 'MISMATCH '${n%%:*}; done
346 fi
347
348 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
349 rm -rf $PKGMK_WORK_DIR
350 fi
351
352 error "Building '$TARGET' failed."
353 exit $E_SIGNATURE
354 #else
355 #info "Signature verification succeeded."
356 fi
357 else
358 if [ "$PKGMK_IGNORE_MD5SUM" = "no" ] && [ "$PKGMK_CHECK_SIGNATURE" = "no" ]; then
359 warning "Signature file not found, falling back to old md5sum checking."
360 return 1;
361 fi
362 if [ "$PKGMK_CHECK_SIGNATURE" = "yes" ]; then
363 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
364 rm -rf $PKGMK_WORK_DIR
365 fi
366 info "Signature not found."
367 exit $E_SIGNATURE
368 fi
369
370 warning "Signature not found, creating new."
371 cd $PKGMK_ROOT
372 make_signature
373 fi
374
375 if [ "$PKGMK_CHECK_SIGNATURE" = "yes" ]; then
376 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
377 rm -rf $PKGMK_WORK_DIR
378 fi
379 info "Signature ok."
380 exit 0
381 fi
382
383 # remove soft links
384 find $SRC -maxdepth 1 -mindepth 1 -type l -delete
385 return 0
386 }
387
388 make_signature() {
389 local FILE LOCAL_FILENAMES
390 local REPO
391
392 local srcind=0
393 while [ $srcind -lt ${#source[@]} ]; do
394 if [ -n "${renames[$srcind]}" -a "${renames[$srcind]}" != "SKIP" ]; then
395 source[$srcind]="http://somehost/${renames[$srcind]}"
396 fi
397 srcind=$(( srcind+1 ))
398 done
399
400 for FILE in "$PKGMK_PKGFILE" "$PKGMK_FOOTPRINT" "${source[@]}"; do
401 LOCAL_FILENAMES="$LOCAL_FILENAMES `get_filename $FILE`"
402 done
403
404 if [ ! "$PKGMK_PRIVATEKEY" ]; then
405 REPO=${PWD%/*}
406 REPO=${REPO##*/}
407 REPO=${REPO%.git}
408 fi
409
410 if [ "$REPO" ]; then
411 PKGMK_PRIVATEKEY="/etc/ports/${REPO}.sec"
412 fi
413
414 sha256sum --tag $LOCAL_FILENAMES | sed 's|^SHA256 (.*/\(.*\))\(.* = .*\)|SHA256 (\1)\2|' | \
415 $PKGMK_SIGNIFY -S -e -x - -q -s "$PKGMK_PRIVATEKEY" -m - > ${PKGMK_SIGNATURE}.tmp
416
417 if [ $? -ne 0 ]; then
418 rm ${PKGMK_SIGNATURE}.tmp
419 error "Creating signature failed"
420 exit $E_SIGNATURE
421 else
422 mv ${PKGMK_SIGNATURE}.tmp ${PKGMK_SIGNATURE}
423 fi
424 }
425
426 refresh_signature() {
427 if [ ! "$PKGMK_PRIVATEKEY" ]; then
428 REPO=${PWD%/*}
429 REPO=${REPO##*/}
430 REPO=${REPO%.git}
431 fi
432
433 if [ "$REPO" ]; then
434 PKGMK_PRIVATEKEY="/etc/ports/${REPO}.sec"
435 fi
436
437 tail -n +3 ${PKGMK_SIGNATURE} | \
438 $PKGMK_SIGNIFY -S -e -x - -q -s "$PKGMK_PRIVATEKEY" -m - > ${PKGMK_SIGNATURE}.tmp
439
440 if [ $? -ne 0 ]; then
441 rm ${PKGMK_SIGNATURE}.tmp
442 error "Refreshing signature failed"
443 exit $E_SIGNATURE
444 else
445 mv ${PKGMK_SIGNATURE}.tmp ${PKGMK_SIGNATURE}
446 fi
447 }
448
449 strip_files() {
450 local FILTER
451 local N=$(nproc)
452
453 cd $PKG
454
455 if [ -f $PKGMK_ROOT/$PKGMK_NOSTRIP ]; then
456 FILTER="grep -v -f $PKGMK_ROOT/$PKGMK_NOSTRIP"
457 else
458 FILTER="cat"
459 fi
460
461 find . -type f -printf "%P\n" | $FILTER \
462 | xargs -r -L10 -P$N \
463 file --no-buffer --separator '>' \
464 -e apptype -e ascii -e encoding -e tokens \
465 -e cdf -e compress -e tar -e text \
466 | awk '
467 BEGIN { FS = ">[ ]+" }
468 $0 ~ /ELF.*executable.*not stripped/ { print "--strip-all \"" $1 "\"" }
469 $0 ~ /ELF.*shared object.*not stripped/ { print "--strip-unneeded \"" $1 "\"" }
470 $2 == "current ar archive" { print "--strip-debug \"" $1 "\"" }
471 ' \
472 | xargs -r -L1 -P$N strip
473 }
474
475 compress_manpages() {
476 local FILE DIR TARGET
477
478 cd $PKG
479
480 find . -type f -path "*/man/man*/*" | while read FILE; do
481 if [ "$FILE" = "${FILE%%.gz}" ]; then
482 gzip -9 "$FILE"
483 fi
484 done
485
486 find . -type l -path "*/man/man*/*" | while read FILE; do
487 TARGET=`readlink -n "$FILE"`
488 TARGET="${TARGET##*/}"
489 TARGET="${TARGET%%.gz}.gz"
490 rm -f "$FILE"
491 FILE="${FILE%%.gz}.gz"
492 DIR=`dirname "$FILE"`
493
494 if [ -e "$DIR/$TARGET" ]; then
495 ln -sf "$TARGET" "$FILE"
496 fi
497 done
498 }
499
500 check_footprint() {
501 local FILE="$PKGMK_WORK_DIR/.tmp"
502
503 cd $PKGMK_ROOT
504
505 if [ -f $TARGET ]; then
506 make_footprint > $FILE.footprint
507 if [ -f $PKGMK_FOOTPRINT ]; then
508 sort -k 3 $PKGMK_FOOTPRINT > $FILE.footprint.orig
509 diff -w -t -U 0 $FILE.footprint.orig $FILE.footprint | \
510 sed '/^@@/d' | \
511 sed '/^+++/d' | \
512 sed '/^---/d' | \
513 sed 's/^+/NEW /g' | \
514 sed 's/^-/MISSING /g' > $FILE.footprint.diff
515 if [ -s $FILE.footprint.diff ]; then
516 if [ "$PKGMK_IGNORE_NEW" = "yes" ] && \
517 [ -z "$(egrep -l ^MISSING $FILE.footprint.diff)" ] ; then
518 info "New files found:"
519 else
520 error "Footprint mismatch found:"
521 BUILD_SUCCESSFUL="no"
522 fi
523 cat $FILE.footprint.diff >&2
524 fi
525 else
526 warning "Footprint not found, creating new."
527 mv $FILE.footprint $PKGMK_FOOTPRINT
528 fi
529 else
530 error "Package '$TARGET' was not found."
531 BUILD_SUCCESSFUL="no"
532 fi
533 }
534
535 make_work_dir() {
536 PKG="$PKGMK_WORK_DIR/pkg"
537 SRC="$PKGMK_WORK_DIR/src"
538 umask 022
539
540 cd $PKGMK_ROOT
541 remove_work_dir
542 mkdir -p $SRC $PKG
543
544 if [ "$PKGMK_IGNORE_SIGNATURE" = "no" ] || [ "$PKGMK_CHECK_SIGNATURE" = "yes" ]; then
545 test -f $PKGMK_SIGNATURE && cp $PKGMK_SIGNATURE $PKGMK_WORK_DIR
546 if check_signature && test ! -f $PKGMK_MD5SUM
547 then
548 return 0
549 fi
550 fi
551 if [ "$PKGMK_IGNORE_MD5SUM" = "no" ]; then
552 check_md5sum
553 fi
554 }
555
556 remove_work_dir() {
557 rm -rf $PKGMK_WORK_DIR
558 }
559
560
561 build_package() {
562 local BUILD_SUCCESSFUL="no"
563 local COMPRESSION
564
565 check_file "$TARGET"
566 make_work_dir
567
568 if [ "$UID" != "0" ]; then
569 warning "Packages should be built as root."
570 fi
571
572 info "Building '$TARGET'."
573
574 unpack_source
575
576 cd $SRC
577 (set -e -x ; build)
578
579 if [ $? = 0 ]; then
580 if [ "$PKGMK_NO_STRIP" = "no" ]; then
581 strip_files
582 fi
583
584 compress_manpages
585
586 cd $PKG
587 info "Build result:"
588
589 case $PKGMK_COMPRESSION_MODE in
590 gz) COMPRESSION="-z" ;;
591 bz2) COMPRESSION="-j" ;;
592 xz) COMPRESSION="-J" ;;
593 lz) COMPRESSION="--lzip" ;;
594 esac
595 bsdtar -c $COMPRESSION -f $TARGET * && bsdtar -t -v -f $TARGET
596
597 if [ $? = 0 ]; then
598 BUILD_SUCCESSFUL="yes"
599
600 if [ "$PKGMK_IGNORE_FOOTPRINT" = "yes" ]; then
601 warning "Footprint ignored."
602 else
603 check_footprint
604 fi
605 fi
606 fi
607
608 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
609 remove_work_dir
610 fi
611
612 if [ "$BUILD_SUCCESSFUL" = "yes" ]; then
613 info "Building '$TARGET' succeeded."
614 else
615 if [ -f $TARGET ]; then
616 touch -r $PKGMK_ROOT/$PKGMK_PKGFILE $TARGET &> /dev/null
617 fi
618 error "Building '$TARGET' failed."
619 exit 1
620 fi
621 }
622
623 install_package() {
624 local COMMAND
625
626 info "Installing '$TARGET'."
627
628 if [ "$PKGMK_INSTALL" = "install" ]; then
629 COMMAND="pkgadd $TARGET"
630 else
631 COMMAND="pkgadd -u $TARGET"
632 fi
633
634 cd $PKGMK_ROOT
635 echo "$COMMAND"
636 $COMMAND
637
638 if [ $? = 0 ]; then
639 info "Installing '$TARGET' succeeded."
640 else
641 error "Installing '$TARGET' failed."
642 exit 1
643 fi
644 }
645
646 recursive() {
647 local ARGS FILE DIR
648
649 ARGS=`echo "$@" | sed -e "s/--recursive//g" -e "s/-r//g"`
650
651 for FILE in `find $PKGMK_ROOT -name $PKGMK_PKGFILE | sort`; do
652 DIR="`dirname $FILE`/"
653 if [ -d $DIR ]; then
654 info "Entering directory '$DIR'."
655 (cd $DIR && $PKGMK_COMMAND $ARGS)
656 info "Leaving directory '$DIR'."
657 fi
658 done
659 }
660
661 clean() {
662 local ORIG_FILE LOCAL_FILE srcind
663
664 if [ -f $TARGET ]; then
665 info "Removing $TARGET"
666 rm -f $TARGET
667 fi
668
669 srcind=0
670 while [ $srcind -lt ${#source[@]} ]; do
671 ORIG_FILE="${source[$srcind]}"
672 LOCAL_FILE=`get_filename "$ORIG_FILE"`
673 RENAME="${renames[$srcind]}"
674 if [ -n "$RENAME" -a "$RENAME" != "SKIP" ]; then
675 LOCAL_FILE="$PKGMK_SOURCE_DIR/$RENAME"
676 fi
677 if [ -e $LOCAL_FILE ] && [ "$LOCAL_FILE" != "$ORIG_FILE" ]; then
678 info "Removing $LOCAL_FILE"
679 rm -f $LOCAL_FILE
680 fi
681 srcind=$(( srcind+1 ))
682 done
683 }
684
685 update_footprint() {
686 if [ ! -f $TARGET ]; then
687 error "Unable to update footprint. File '$TARGET' not found."
688 exit 1
689 fi
690
691 check_file "$PKGMK_FOOTPRINT"
692 make_footprint > $PKGMK_FOOTPRINT
693 touch $TARGET
694
695 info "Footprint updated."
696 }
697
698 build_needed() {
699 local ORIG_FILE RENAME LOCAL_FILE srcind RESULT
700
701 RESULT="yes"
702 if [ -f $TARGET ]; then
703 RESULT="no"
704 srcind=0
705
706 while [ $srcind -lt ${#source[@]} ]; do
707 ORIG_FILE=`get_filename "${source[$srcind]}"`
708 LOCAL_FILE=$ORIG_FILE
709 RENAME="${renames[$srcind]}"
710 if [ -n "$RENAME" -a "$RENAME" != "SKIP" ]; then
711 LOCAL_FILE="$PKGMK_SOURCE_DIR/$RENAME"
712 fi
713 if [ -e $LOCAL_FILE ] && [ ! $TARGET -nt $LOCAL_FILE ]; then
714 RESULT="yes"
715 break
716 fi
717 srcind=$(( srcind+1 ))
718 done
719
720 if [ -e $PKGMK_PKGFILE ] && [ ! $TARGET -nt $PKGMK_PKGFILE ]; then
721 RESULT="yes"
722 fi
723 fi
724
725 echo $RESULT
726 }
727
728 interrupted() {
729 echo ""
730 error "Interrupted."
731
732 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
733 rm -rf $PKGMK_WORK_DIR
734 fi
735
736 exit 1
737 }
738
739 print_help() {
740 echo "usage: `basename $PKGMK_COMMAND` [options]"
741 echo "options:"
742 echo " -i, --install build and install package"
743 echo " -u, --upgrade build and install package (as upgrade)"
744 echo " -r, --recursive search for and build packages recursively"
745 echo " -d, --download download missing source file(s)"
746 echo " -do, --download-only do not build, only download missing source file(s)"
747 echo " -eo, --extract-only do not build, only extract source file(s)"
748 echo " -utd, --up-to-date do not build, only check if package is up to date"
749 echo " -uf, --update-footprint update footprint using result from last build"
750 echo " -if, --ignore-footprint build package without checking footprint"
751 echo " -in, --ignore-new build package, ignore new files in a footprint missmatch"
752 echo " -um, --update-md5sum update md5sum"
753 echo " -im, --ignore-md5sum build package without checking md5sum"
754 echo " -cm, --check-md5sum do not build, only check md5sum"
755 echo " -us, --update-signature update signature including sha256 checksums"
756 echo " -cs, --check-signature check the validity of the port files"
757 echo " -is, --ignore-signature build package without checking the signature"
758 echo " -rs, --refresh-signature create new signature and keep existing sha256 checksums"
759 echo " -sk, --secret-key <file> use <file> to sign the port"
760 echo " -pk, --public-key <file> check the port signature using public-key <file>"
761 echo " -ns, --no-strip do not strip executable binaries or libraries"
762 echo " -f, --force build package even if it appears to be up to date"
763 echo " -c, --clean remove package and downloaded files"
764 echo " -kw, --keep-work keep temporary working directory"
765 echo " -cf, --config-file <file> use alternative configuration file"
766 echo " -v, --version print version and exit"
767 echo " -h, --help print help and exit"
768 }
769
770 parse_options() {
771 while [ "$1" ]; do
772 case $1 in
773 -i|--install)
774 PKGMK_INSTALL="install" ;;
775 -u|--upgrade)
776 PKGMK_INSTALL="upgrade" ;;
777 -r|--recursive)
778 PKGMK_RECURSIVE="yes" ;;
779 -d|--download)
780 PKGMK_DOWNLOAD="yes" ;;
781 -do|--download-only)
782 PKGMK_DOWNLOAD="yes"
783 PKGMK_DOWNLOAD_ONLY="yes" ;;
784 -eo|--extract-only)
785 PKGMK_EXTRACT_ONLY="yes" ;;
786 -utd|--up-to-date)
787 PKGMK_UP_TO_DATE="yes" ;;
788 -uf|--update-footprint)
789 PKGMK_UPDATE_FOOTPRINT="yes" ;;
790 -if|--ignore-footprint)
791 PKGMK_IGNORE_FOOTPRINT="yes" ;;
792 -in|--ignore-new)
793 PKGMK_IGNORE_NEW="yes" ;;
794 -um|--update-md5sum)
795 PKGMK_UPDATE_MD5SUM="yes" ;;
796 -im|--ignore-md5sum)
797 PKGMK_IGNORE_MD5SUM="yes" ;;
798 -cm|--check-md5sum)
799 PKGMK_CHECK_MD5SUM="yes" ;;
800 -us|--update-signature)
801 PKGMK_UPDATE_SIGNATURE="yes" ;;
802 -cs|--check-signature)
803 PKGMK_CHECK_SIGNATURE="yes" ;;
804 -is|--ignore-signature)
805 PKGMK_IGNORE_SIGNATURE="yes" ;;
806 -rs|--referesh-signature)
807 PKGMK_REFRESH_SIGNATURE="yes" ;;
808 -ns|--no-strip)
809 PKGMK_NO_STRIP="yes" ;;
810 -f|--force)
811 PKGMK_FORCE="yes" ;;
812 -c|--clean)
813 PKGMK_CLEAN="yes" ;;
814 -kw|--keep-work)
815 PKGMK_KEEP_WORK="yes" ;;
816 -pk|--public-key)
817 if [ ! "$2" ]; then
818 echo "`basename $PKGMK_COMMAND`: option $1 requires an argument"
819 exit 1
820 fi
821 PKGMK_PUBLICKEY="$2"
822 shift ;;
823 -sk|--secret-key)
824 if [ ! "$2" ]; then
825 echo "`basename $PKGMK_COMMAND`: option $1 requires an argument"
826 exit 1
827 fi
828 PKGMK_PRIVATEKEY="$2"
829 shift ;;
830 -cf|--config-file)
831 if [ ! "$2" ]; then
832 echo "`basename $PKGMK_COMMAND`: option $1 requires an argument"
833 exit 1
834 fi
835 PKGMK_CONFFILE="$2"
836 shift ;;
837 -v|--version)
838 echo "`basename $PKGMK_COMMAND` (pkgutils) $PKGMK_VERSION"
839 exit 0 ;;
840 -h|--help)
841 print_help
842 exit 0 ;;
843 *)
844 echo "`basename $PKGMK_COMMAND`: invalid option $1"
845 exit 1 ;;
846 esac
847 shift
848 done
849 }
850
851 main() {
852 # multilib
853 PKGMK_ARCH=64
854 if [ -f ".32bit" ]; then
855 PKGMK_ARCH=32
856 fi
857
858 local FILE TARGET
859
860 parse_options "$@"
861
862 if [ "$PKGMK_RECURSIVE" = "yes" ]; then
863 recursive "$@"
864 exit 0
865 fi
866
867 for FILE in $PKGMK_PKGFILE $PKGMK_CONFFILE; do
868 if [ ! -f $FILE ]; then
869 error "File '$FILE' not found."
870 exit 1
871 fi
872 . $FILE
873 done
874
875 check_directory "$PKGMK_SOURCE_DIR"
876 check_directory "$PKGMK_PACKAGE_DIR"
877 check_directory "`dirname $PKGMK_WORK_DIR`"
878
879 check_pkgfile
880
881 case $PKGMK_COMPRESSION_MODE in
882 gz|bz2|xz|lz)
883 TARGET="$PKGMK_PACKAGE_DIR/$name#$version-$release.pkg.tar.$PKGMK_COMPRESSION_MODE"
884 ;;
885 *)
886 error "Compression mode '$PKGMK_COMPRESSION_MODE' not supported"
887 exit 1
888 ;;
889 esac
890
891 if [ "$PKGMK_CLEAN" = "yes" ]; then
892 clean
893 exit 0
894 fi
895
896 if [ "$PKGMK_UPDATE_FOOTPRINT" = "yes" ]; then
897 update_footprint
898 exit 0
899 fi
900
901 if [ "$PKGMK_UPDATE_MD5SUM" = "yes" ]; then
902 download_source
903 check_file "$PKGMK_MD5SUM"
904 make_md5sum > $PKGMK_MD5SUM
905 info "Md5sum updated."
906 exit 0
907 fi
908
909 if [ "$PKGMK_UPDATE_SIGNATURE" = "yes" ]; then
910 download_source
911 check_file "$PKGMK_SIGNATURE"
912 make_signature
913 info "Signature updated."
914 exit 0
915 fi
916
917 if [ "$PKGMK_REFRESH_SIGNATURE" = "yes" ]; then
918 check_file "$PKGMK_SIGNATURE"
919 refresh_signature
920 info "Signature refreshed."
921 exit 0
922 fi
923
924 if [ "$PKGMK_DOWNLOAD_ONLY" = "yes" ]; then
925 download_source
926 exit 0
927 fi
928
929 if [ "$PKGMK_EXTRACT_ONLY" = "yes" ]; then
930 download_source
931 make_work_dir
932 info "Extracting sources of package '$name-$version'."
933 unpack_source
934 exit 0
935 fi
936
937 if [ "$PKGMK_UP_TO_DATE" = "yes" ]; then
938 if [ "`build_needed`" = "yes" ]; then
939 info "Package '$TARGET' is not up to date."
940 else
941 info "Package '$TARGET' is up to date."
942 fi
943 exit 0
944 fi
945
946 if [ "`build_needed`" = "no" ] && [ "$PKGMK_FORCE" = "no" ] && [ "$PKGMK_CHECK_MD5SUM" = "no" ] && [ "$PKGMK_CHECK_SIGNATURE" = "no" ]; then
947 info "Package '$TARGET' is up to date."
948 else
949 download_source
950 build_package
951 fi
952
953 if [ "$PKGMK_INSTALL" != "no" ]; then
954 install_package
955 fi
956
957 exit 0
958 }
959
960 trap "interrupted" SIGHUP SIGINT SIGQUIT SIGTERM
961
962 export LC_ALL=C.UTF-8
963
964 readonly PKGMK_VERSION="#VERSION#"
965 readonly PKGMK_COMMAND="$0"
966 readonly PKGMK_ROOT="$PWD"
967 readonly PKGMK_SIGNIFY="/usr/bin/signify"
968
969 PKGMK_CONFFILE="/etc/pkgmk.conf"
970 PKGMK_PKGFILE="Pkgfile"
971 PKGMK_FOOTPRINT=".footprint"
972 PKGMK_MD5SUM=".md5sum"
973 PKGMK_NOSTRIP=".nostrip"
974 PKGMK_SIGNATURE=".signature"
975
976 PKGMK_SOURCE_MIRRORS=()
977 PKGMK_SOURCE_DIR="$PWD"
978 PKGMK_PACKAGE_DIR="$PWD"
979 PKGMK_WORK_DIR="$PWD/work"
980
981 PKGMK_COMPRESSION_MODE="gz"
982
983 PKGMK_INSTALL="no"
984 PKGMK_RECURSIVE="no"
985 PKGMK_DOWNLOAD="no"
986 PKGMK_DOWNLOAD_ONLY="no"
987 PKGMK_EXTRACT_ONLY="no"
988 PKGMK_UP_TO_DATE="no"
989 PKGMK_UPDATE_FOOTPRINT="no"
990 PKGMK_IGNORE_FOOTPRINT="no"
991 PKGMK_IGNORE_NEW="no"
992 PKGMK_FORCE="no"
993 PKGMK_KEEP_WORK="no"
994 PKGMK_UPDATE_MD5SUM="no"
995 PKGMK_IGNORE_MD5SUM="no"
996 PKGMK_CHECK_MD5SUM="no"
997 PKGMK_UPDATE_SIGNATURE="no"
998 PKGMK_IGNORE_SIGNATURE="no"
999 PKGMK_CHECK_SIGNATURE="no"
1000 PKGMK_REFRESH_SIGNATURE="no"
1001 PKGMK_PRIVATEKEY=""
1002 PKGMK_NO_STRIP="no"
1003 PKGMK_CLEAN="no"
1004
1005 main "$@"
1006
1007 # End of file
|