-
Notifications
You must be signed in to change notification settings - Fork 0
/
lfsa
11504 lines (11485 loc) · 414 KB
/
lfsa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
#
if [ $UID -ne 0 ]; then echo Please run this script as root; exit 1; fi
LFS=$LFS
echo "LFS is set to $LFS"
if [ "$LFS" = "" ]; then
echo "The LFS variable is not set"
echo "do: export LFS=/mnt/lfs to install LFS on a target machine"
echo " export LFS=local to install LFS on this (local) machine"
echo
exit 1
fi
# repository will be for LFS
REPO="LFS"
#
if [ "$LFS" = /mnt/lfs ]; then # check for the directory
if [ ! -d $LFS ]; then
echo "Directory $LFS doesn't exist"
echo "Create it to continue"
exit 1
fi
elif [ "$LFS" = local ]; then
LFS="/" # local machine
else
echo "Don't recognise env variable LFS as $LFS. Edit this script to respond to $LFS."
echo "Or else do: export LFS=/mnt/lfs"
exit 1
fi
#
if [ -e $LFS/tools ]; then
if [ ! -d $LFS/tools ]; then
echo "$LFS/tools is not a directory"
mv -v $LFS/tools $LFS/tools.backup
echo "file $LFS/tools moved to $LFS/tools.backup"
echo "create directory $LFS/tools"
install -vdm755 $LFS/tools
if [ "$LFS/tools" != "$( ls -l /tools | awk '{print $NF}' )" ]; then
echo "/tools is not a symlink to $LFS/tools"
echo ""
echo "as root, do:"
echo ""
echo " ln -s $LFS/tools /tools"
exit 1
fi
else
echo "tools dir ${LFS}/tools exists"
fi
else
install -vdm755 ${LFS}/tools
fi
#
#display_menu=true # by default, edit the config file
# set up default config filename
if [ "$LFS" = /mnt/lfs -o "$LFS" = "/" ]; then
lfs="lfs"
lfsUC=${lfs^^} # uppercase version of $lfs
cfg=~/${lfsUC}.conf
else
echo "*** Don't recognise $LFS. Make sure this script will work with that. ***"
fi
# this following bit allows you to give a config filename as $1 and use it unedited
#if [ ! -z "$1" ]; then # config filename given - use it unedited
# cfg=$1 # full name of the config file
# check it exists
# if [ ! -e $cfg ]; then # doesn't exist - exit
# echo "If you give the config filename it must exist"
# echo "Exiting now"
# exit 1
# else
# display_menu=false # do not change the config file
# fi
#fi
# output the env var LFS in a file in /home/lfs so can source it in chapter05
if [ -d /home/lfs ]; then # make sure .bash_profile and .bashrc exist
if [ -e /home/lfs/.bashrc ]; then
if [ -e /home/lfs/defineLFS ]; then rm -v /home/lfs/defineLFS; fi
# remove LFS env variable in .bashrc in case LFS=local
sed -e '/LFS=\/mnt\/lfs/d' \
-e 's/LFS LC_ALL/LC_ALL/' \
-i /home/lfs/.bashrc
cat > /home/lfs/defineLFS << "EOF"
# this is sourced by .bashrc when su - lfs is done in chapter05
EOF
echo export LFS=\"$LFS\" >> /home/lfs/defineLFS
# chown lfs:lfs /home/lfs/defineLFS
# does the .bashrc file contain the source defineLFS line?
sourcePres=$(grep -E -w 'source|defineLFS' /home/lfs/.bashrc)
if [ "$sourcePres" != "source /home/lfs/defineLFS" ]; then
sed -i '/export/a source \/home\/lfs\/defineLFS' /home/lfs/.bashrc
fi
else # .bashrc doesn't exist so create it
cat > /home/lfs/.bashrc << "EOF"
set +h
umask 022
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu
PATH=/usr/bin
PATH=$LFS/tools/bin:$PATH
CONFIG_SITE=$LFS/usr/share/config.site
export LC_ALL LFS_TGT PATH CONFIG_SITE
export MAKEFLAGS=-j6
EOF
if [ -e /home/lfs/defineLFS ]; then rm -v /home/lfs/defineLFS; fi # in case it exists
cat > /home/lfs/defineLFS << "EOF"
# this is sourced by .bashrc when su - lfs is done in chapter05
EOF
echo export LFS=\"$LFS\" >> /home/lfs/defineLFS
# now source defineLFS
sed -i '/export/a source \/home\/lfs\/defineLFS' /home/lfs/.bashrc
# does /home/lfs/.bash_profile exist
if [ ! -e "/home/lfs/.bash_profile" ]; then # create it
cat > /home/lfs/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF
fi
fi
else
echo "user lfs doesn't exist - will create the group and user lfs"
groupadd lfs
useradd -s /bin/bash -g lfs -m -k /dev/null lfs
chown -v lfs ${LFS}/tools
if [ ! -d ${LFS}/sources ]; then mkdir -v ${LFS}/sources; fi
chown -v lfs $LFS/sources
cat > /home/lfs/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF
cat > /home/lfs/.bashrc << "EOF"
set +h
umask 022
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu
PATH=/usr/bin
PATH=$LFS/tools/bin:$PATH
CONFIG_SITE=$LFS/usr/share/config.site
export LC_ALL LFS_TGT PATH CONFIG_SITE
export MAKEFLAGS=-j6
EOF
cat > /home/lfs/defineLFS << "EOF"
# this is sourced by .bashrc when su - lfs is done in chapter05
EOF
echo export LFS=\"$LFS\" >> /home/lfs/defineLFS
# chown lfs:lfs /home/lfs/{.bash_profile,.bashrc,defineLFS}
echo "*** NOTE - You need to set a password for user lfs ***"
fi
lfscommands=${lfs}-commands # the dir containing the lfs-commands
lfshtml=${lfs}-html # the dir containing the lfs html
DumpedCommands=${LFS}/${lfscommands}
Dumpedhtml=${LFS}/${lfshtml}
if [ "$LFS" = "/" ]; then # need to remove the // to get the Makefile to work
DumpedCommands="/${lfscommands}"
Dumpedhtml="/${lfshtml}"
fi
wgetopts="" # Options for wget, e.g. proxy settings etc
RETURN_OTHER_ERR=237 # used when more than one error found in a function
RETURN_GT=239 # used in test of which version is later. returned if $1 > $2
RETURN_EQ=241 # used in compare_versions - returned if versions are equal
RETURN_FNF=243 # file not found
RETURN_MTOV=245 # more than one version of file present
RETURN_NO_CMNDS=247 # no commands found for specified package
RETURN_FNF=249 # return file not found
RETURN_PARAM=251 # from a function on error
#
isInt=89 # test if a string is int, float or just a string
isFloat=91
isChar=93
#
# these are relative to newly installed lfs ( i.e. without $LFS prefix )
sourcedir=/sources # as given in the book
PKGUSERDIR=/usr/src
PkgUserDir=${PKGUSERDIR}/core # most package src files sit under here. Make sure blfsa is consistent with this.
preChrootBuild=/build # chapter05 and 06 build directory
#
buildDir=${LFS}/build # chapter05 and 06 build directory
BuildLog=${lfsUC}-build.log # keep a record of packages and times
echo "BuildLog set to $BuildLog"
if [ ! -e ${LFS}/${BuildLog} ]; then
if [ -d /home/lfs ]; then # user lfs exists
echo "Directory /home/lfs exists"
touch ${LFS}/${BuildLog}
else
echo "user lfs doesn't exist. You should create it now - section 4.3 in the book"
exit 1
fi
fi
SOURCEDIR=${LFS}${sourcedir}
if [ ! -d "$SOURCEDIR" ]; then install -vdm755 $SOURCEDIR; fi
allChaps="chapter05 chapter06 chapter07 chapter08 chapter10"
build="build" # name of the build file for each package
ncc="--no-check-certificate" # options for wget
#initialize the config variables
TZ=$TZ
PAPER_SIZE=$PAPER_SIZE
LFS_BOOK_GIT_LOC_DIR=$HOME/LFS_GIT/$REPO # def local dir for the downloaded (git) book xml
GIT_URL="git://git.linuxfromscratch.org" # git url
trunkDIR=trunk # the dir below LFS_BOOK_GIT_LOC_DIR
BOOK_VERSION=$BOOK_VERSION
SOURCES=$SOURCES
CLEAN_SRC_DIR=$CLEAN_SRC_DIR
WGETLISTNAME=$WGETLISTNAME
UPDATESRCFILES=$UPDATESRCFILES
BOOK_ORIGIN=$BOOK_ORIGIN
WHICH_CHAPTER=$WHICH_CHAPTER
PKGUSERFILE=$PKGUSERFILE
TESTS=$TESTS
MAKE_KERNEL=$MAKE_KERNEL # "no" - stop at make mrproper, "yes" - use a .config and make
AS_ROOT=$AS_ROOT # 'no' install as package user, 'yes' install as root
SYSTEMD=$SYSTEMD # 'yes' use systemd, 'no' use sysvinit for control
DESTDIR=$DESTDIR
INSTALLDEST=$INSTALLDEST
USEPROXY=$USEPROXY
SINGLE_PACKAGE=$SINGLE_PACKAGE
PRINTIT=$PRINTIT
echo "config file is $cfg"
if [ -e $cfg ]; then
source $cfg # exists so source it
else
touch $cfg #cfg is new
if [ -z "$TZ" ]; then #null
TZ="Europe/London"
fi
if [ -z "$PAPER_SIZE" ]; then #null
PAPER_SIZE="A4"
fi
if [ -z "$BOOK_ORIGIN" ]; then
BOOK_ORIGIN="git"
fi
if [ -z "$BOOK_VERSION" ]; then
BOOK_VERSION="trunk"
fi
if [ -z "$SOURCES" ]; then
SOURCES="atinstall"
fi
if [ -z "$CLEAN_SRC_DIR" ]; then
CLEAN_SRC_DIR="no"
fi
if [ -z "$WGETLISTNAME" ]; then
WGETLISTNAME="wget-list"
fi
if [ -z "$UPDATESRCFILES" ]; then
UPDATESRCFILES="no"
fi
if [ -z "$WHICH_CHAPTER" ]; then
WHICH_CHAPTER="chapter05"
fi
if [ -z "$PKGUSERFILE" ]; then
PKGUSERFILE="pkguser.tar.xz"
fi
if [ -z "$TESTS" ]; then #null
TESTS="no"
fi
if [ -z "$MAKE_KERNEL" ]; then #null
MAKE_KERNEL="no"
fi
if [ -z "$AS_ROOT" ]; then #null
AS_ROOT="no"
fi
if [ -z "$SYSTEMD" ]; then #null
SYSTEMD="yes"
fi
if [ -z "$DESTDIR" ]; then
DESTDIR="no"
fi
if [ -z "$INSTALLDEST" ]; then
INSTALLDEST="no"
fi
if [ -z "$USEPROXY" ]; then
USEPROXY="no"
fi
if [ -z "$SINGLE_PACKAGE" ]; then
SINGLE_PACKAGE="no"
fi
if [ -z "$PRINTIT" ]; then
PRINTIT="true"
fi
# store the values in the new config file
echo "TZ=$TZ" | tee $cfg
echo "PAPER_SIZE=$PAPER_SIZE" | tee -a $cfg
echo "LFS_BOOK_GIT_LOC_DIR=$HOME/LFS_GIT/$REPO" | tee -a $cfg
echo "GIT_URL=$GIT_URL" | tee -a $cfg
echo "BOOK_VERSION=$BOOK_VERSION" | tee -a $cfg
echo "SOURCES=$SOURCES" | tee -a $cfg
echo "CLEAN_SRC_DIR=$CLEAN_SRC_DIR" | tee -a $cfg
echo "WGETLISTNAME=$WGETLISTNAME" | tee -a $cfg
echo "UPDATESRCFILES=$UPDATESRCFILES" | tee -a $cfg
echo "BOOK_ORIGIN=$BOOK_ORIGIN" | tee -a $cfg
echo "WHICH_CHAPTER=$WHICH_CHAPTER" | tee -a $cfg
echo "PKGUSERFILE=$PKGUSERFILE" | tee -a $cfg
echo "TESTS=$TESTS" | tee -a $cfg
echo "MAKE_KERNEL=$MAKE_KERNEL" | tee -a $cfg
echo "AS_ROOT=$AS_ROOT" | tee -a $cfg
echo "SYSTEMD=$SYSTEMD" | tee -a $cfg
echo "DESTDIR=$DESTDIR" | tee -a $cfg
echo "INSTALLDEST=$INSTALLDEST" | tee -a $cfg
echo "USEPROXY=$USEPROXY" | tee -a $cfg
echo "SINGLE_PACKAGE=$SINGLE_PACKAGE" | tee -a $cfg
echo "PRINTIT=$PRINTIT" | tee -a $cfg
fi
# functions
#
msg () {
echo >&2 -e "${1-}"
}
#
die() {
local msg=$1
local code=${2-1} # default exit status 1
msg "$msg"
exit "$code"
}
#
configEdit () {
local DIALOG_OK=0
local DIALOG_CANCEL=1
local DIALOG_HELP=2
local DIALOG_EXTRA=3
local DIALOG_ITEM_HELP=4
local DIALOG_ESC=255
local HEIGHT=0
local WIDTH=0
display_configFile () {
dialog --textbox "$1" $HEIGHT $WIDTH
}
#
_edit () {
local value
local newval
local exit_status
local tochange
local display
#
itemMenu=$(awk -F\= '{print $1,$2}' $cfg)
exec 3>&1
tochange=$(dialog --menu "Select item to edit" 0 0 0 $itemMenu 2>&1 1>&3)
exit_status=$?
exec 3>&-
case $exit_status in
$DIALOG_CANCEL)
return 0
;;
$DIALOG_ESC)
echo "Program aborted." >&2
exit 1
;;
$DIALOG_OK)
case $tochange in
TZ)
display="Enter your local time zone. (If not known, run tzselect)"
;;
PAPER_SIZE)
display="Probably either letter or A4"
;;
LFS_BOOK_GIT_LOC_DIR)
display="If the book source is GIT, enter the local directory to store the LFS Book"
;;
GIT_URL)
display="Enter the git url of the LFS book"
;;
BOOK_VERSION)
display="LFS book version you want. Type trunk to get the development version. To use systemd, set SYSTEMD=yes in the menu. Type blank to choose from a list."
;;
BOOK_ORIGIN)
display="Enter git to download the book or local if it's already downloaded. If local the book must be in $LFS_BOOK_GIT_LOC_DIR"
;;
WHICH_CHAPTER)
display="Enter chapter05, 06, 07, 08 or 10. Enter update to update the core lfs packages in chapter08. To do this set MAKE_KERNEL to no. If MAKE_KERNEL is yes, only the kernel will be updated"
;;
SOURCES)
display="atinstall, download or local. atinstall means download to the install dir at install time (default). (if local, source files must be in ${SOURCEDIR}/<book_version>)"
;;
CLEAN_SRC_DIR)
display="If yes, all files in the $WgetList file in ${SOURCEDIR}/<book_version> will be deleted. Default is no. Note, if using the SINGLE_PACKAGE option with DESTDIR, the source directory will be cleaned first."
;;
WGETLISTNAME)
display="The name of the wget-list file. Default is wget-list"
;;
UPDATESRCFILES)
display="If yes, the source files are updated from the lfs sources page in the book.
The wget-list file is made consistent with these updates. Default is no"
;;
PKGUSERFILE)
display="tar file containing the package user build files. Default is pkguser.tar.xz. Place the file in $LFS/sources"
;;
TESTS)
display="Chapter 6 tests? Type eithe yes or no"
;;
MAKE_KERNEL)
display="If WHICH_CHAPTER is chapter10, input no will stop the kernel at makeproper. If yes, the kernel will be compiled and installed. If WHICH_CHAPTER is update, input no will update all the packages in chapter08, but not the kernel. If yes, the latest kernel will be compiled and installed; but nothing else. Remember, if this option is yes, the .config file must be in \$LFS/sources for the kernel to be installed"
;;
AS_ROOT)
display="If yes, install packages as root. If no, install as package user"
;;
SYSTEMD)
display="If yes, systemd will control start-up, running and shutdown of the system. If no, will use sysvinit."
;;
DESTDIR)
display="Set to yes to install the files to a specified directory and create a binary package tarfile from those files. Default is set to no."
;;
INSTALLDEST)
display="If yes and DESTDIR=yes then the files created by DESTDIR are installed and no binary tarfile is created. If DESTDIR=no then any existing binary tarfiles are installed for the specified chapter. Default is no"
;;
USEPROXY)
display="Set to yes if a proxy server is running on the host. Default is no."
;;
SINGLE_PACKAGE)
display="Install a single package. Use with DESTDIR to create a binary package file. The package name must be in the wget-list file (linux-headers and kernel are okay names). To turn off, type no"
;;
PRINTIT)
display="Set it to true to get more information when debugging the code."
;;
esac
value=$(awk -F\= -v x=$tochange '$1==x {print $2}' $cfg)
;;
esac
exec 3>&1
newval=$(dialog --clear --title "Change value" --inputbox "$display" 0 0 $value 2>&1 1>&3)
case ${newval+x$newval} in
(x)
dialog --infobox "Value can't be empty" 0 0
sleep 2
exit_status=1
;;
("")
dialog --infobox "Value can't be unset" 0 0
sleep 2
exit_status=1
;;
(x*[![:blank:]]*)
exit_status=$? # non blank
;;
(*)
dialog --infobox "Value can't be blank" 0 0
sleep 2
exit_status=1
;;
esac
exec 3>&-
case $exit_status in
$DIALOG_CANCEL)
return 0
;;
$DIALOG_ESC)
echo "Program aborted." >&2
exit 1
;;
$DIALOG_OK)
dialog --title "Confirmation" --yesno "Commit ?" 0 0
exit_status=$?
case $exit_status in
1)
dialog --infobox "Value not changed" 0 0
sleep 1
;;
0)
awk -v x=$tochange -v n=$newval '
BEGIN {FS=OFS="="}$1==x {$2=n} {print}
' $cfg > $cfg.tmp
mv $cfg.tmp $cfg
;;
esac
;;
esac
return 0
} # end _edit
#
_main () {
while true; do
exec 3>&1
selection=$(dialog \
--backtitle "LFS config file editor" \
--title "Menu" \
--clear \
--cancel-label "Cancel" \
--menu "Please choose an option:" $HEIGHT $WIDTH 4 \
1 "View the config file" \
2 "Edit config file" \
3 "Exit from this menu" 2>&1 1>&3)
exit_status=$?
exec 3>&-
case $exit_status in
$DIALOG_CANCEL)
echo "Cancel pressed. Exit program"
exit 1
;;
$DIALOG_ESC)
echo "Program aborted."
exit 1
;;
$DIALOG_OK)
case $selection in
1)
display_configFile $cfg
;;
2)
_edit
display_configFile $cfg
;;
3)
echo "Exit and process config file"
return
;;
esac
esac
done
#
} # end _main
_main
} #end configEdit
#
ChkLocalBook () {
# $1 is the dir of the book
# $2 is the book version
local localbookdir=$1
local version=$2
if [ "$version" = trunk ]; then # check if dir exists
if [ -d ${localbookdir}/${version}/lfs ]; then # local book dir exists
if [ -e ${localbookdir}/${version}/lfs/.git ]; then # a book exists, check the version
ChkLocalBookDetails $localbookdir $version
retval=$?
if [ $retval -eq 0 ]; then
return 0 # download the book
else
return 1 # requested book alreaded downloaded
fi
else # no .git file found, check if dir is empty
if [ $(ls -al ${localbookdir}/${version} | wc -l) -eq 3 ]; then
echo "dir ${localbookdir}/${version} is empty"
fi
return 0 # download the book
fi
else
return $RETURN_PARAM # book dir doesn't exist
fi
else # book is a release version so do nothing
echo "Requested book is present locally so will use it."
echo "It is a release version so no update necessary."
return $RETURN_PARAM
fi
} # end ChkLocalBook
#
ChkLocalBookDetails () {
local bookdir=$1
local book_version=$2
#
# check the last commit hash
pushd ${bookdir}/${version}/lfs > /dev/null
local last_commit_local=$(git rev-parse HEAD)
popd > /dev/null
# get the last commit hash from the online book
local last_commit_online=$(git ls-remote git://git.linuxfromscratch.org/lfs.git HEAD | cut -f1)
#echo "last_commit_local is $last_commit_local"
#echo "last_commit_online is $last_commit_online"
if [ "$last_commit_local" = "$last_commit_online" ]; then # latest commit already downloaded
return 1 # don't download
else
return 0 # download latest version of the book
fi
} # end ChkLocalBookDetails
#
CleanLocalREPO () { # delete any files in the local directory
local bookdir=$1
local book_version=$2
if [ -d ${bookdir}/${book_version} ]; then # local dir exists
if [ "$(ls -A ${bookdir}/${book_version})" ]; then # dir contains files
rm -rf ${bookdir}/${book_version}* # delete contents of local book dir
fi
else # create it
install -v -m0755 -d ${bookdir}/${book_version}
fi
} # end CleanLocalREPO
#
WhichLFSBook () {
# BOOK_VERSION is global
local f lfsVers lfsBooks
# get a list of branches from the website
local lfsVers=$(git ls-remote ${GIT_URL}/lfs.git | awk -F\/ '{print $NF}')
# limit the books to just a decimal number and nothing else
for f in $lfsVers; do
if [[ $f =~ ^[-+]?([0-9]*\.[0-9]+|[0-9]+\.[0-9]*)$ ]]; then
lfsBooks="$lfsBooks $f"$'\n'
fi
done
PS3="Please select the book version : "
select TAG in 'Current Development' $lfsBooks
do
case $TAG in
'') echo >&2 "Please select a numbered option"
;;
Current*)
type=trunk
version=trunk
BOOK_VERSION=trunk
;;
?*)
type=tags
version=$TAG
BOOK_VERSION=$TAG
;;
esac
echo >&2 "You have selected '$TAG'"
echo >&2 "$GIT_URL"
PS3="Is this correct? : "
select confirm in Yes No
do
case $confirm in
'') echo >&2 "Please enter 1 for Yes or 2 for No"
;;
?*) break
;;
esac
done
case $confirm in
No) PS3="Please select the book version : "
;;
# update the config file with the book version
Yes) awk -v x=BOOK_VERSION -v n=$BOOK_VERSION '
BEGIN {FS=OFS="="}$1==x {$2=n} {print}
' $cfg > $cfg.tmp
mv $cfg.tmp $cfg
break
;;
esac
done
} #end WhichLFSBook
#
git-info () {
# a close equivalent to svn info
# make sure we are in the git dir
local REPO="LFS"
local bookdir=$bookDir
local book_vers="trunk"
local target=$( echo $REPO | awk '{print tolower($1)}')
local REPODIR=${bookdir}/${book_vers}/${target}
pushd $REPODIR > /dev/null
function check_git_dir {
local IS_GIT_DIR=$(git rev-parse --is-inside-work-tree)
if [ ! "$IS_GIT_DIR" == "true" ]; then
exit 1
fi
}
#
function get_last_modified {
echo -e -n "$(git show --format="%ci %cr" $1 | head -n 1 | cut -d ' ' -f4-6)"
}
#
check_git_dir
REMOTE=$1
if [ "$REMOTE" == "" ]; then
REMOTE=origin
fi
if [ "$(git remote | grep $REMOTE)" == "" ]; then
echo "remote '$REMOTE' does not exist"
exit 1
fi
git remote update $REMOTE > /dev/null 2>&1
REMOTE_URL=$(git config --get remote.$REMOTE.url)
BRANCH=$(git rev-parse --abbrev-ref HEAD)
LAST_REMOTE_COMMIT=""
REMOTE_LAST_MODIFIED=""
REMOTE_BRANCH_EXISTS=false
if [ ! "$(git branch -r | grep $GROUP/$BRANCH)" == "" ]; then
REMOTE_BRANCH_EXISTS=true
LAST_REMOTE_COMMIT=$(git rev-parse $REMOTE/$BRANCH)
REMOTE_LAST_MODIFIED=$(get_last_modified $REMOTE/$BRANCH)
fi
LAST_LOCAL_COMMIT=$(git --no-pager log --max-count=1 | head -n1 | cut -d ' ' -f2)
LOCAL_LAST_MODIFIED=$(get_last_modified $BRANCH)
SHORT_COMMIT_HASH=$(git rev-parse --short=9 $BRANCH)
INSYNC=false
if [ "$LAST_LOCAL_COMMIT" == "$LAST_REMOTE_COMMIT" ]; then
INSYNC=true
fi
cd $(readlink -f .)
while [ ! -d .git ] && [ ! `pwd` = "/" ]; do cd ..; done
WORKING_COPY_ROOT_PATH=$(pwd)
FINAL_OUTPUT="'Working Copy Root Path: $WORKING_COPY_ROOT_PATH|Remote: $REMOTE|Remote URL: $REMOTE_URL|Branch: $BRANCH|Last Local Commit: $LAST_LOCAL_COMMIT ($LOCAL_LAST_MODIFIED)|Last Remote Commit: $LAST_REMOTE_COMMIT ($REMOTE_LAST_MODIFIED)|Synchronized: $INSYNC|Revision: $SHORT_COMMIT_HASH|'"
echo $FINAL_OUTPUT
#echo " Remote: $REMOTE"
#echo " Remote URL: $REMOTE_URL"
#echo " Branch: $BRANCH"
#echo " Last Local Commit: $LAST_LOCAL_COMMIT ($LOCAL_LAST_MODIFIED)"
#if [ "$REMOTE_BRANCH_EXISTS" == "true" ]; then
# echo " Last Remote Commit: $LAST_REMOTE_COMMIT ($REMOTE_LAST_MODIFIED)"
# echo " Synchronized: $INSYNC"
#else
# echo " Last Remote Commit: -- no remote branch --"
# echo " Synchronized: -- no remote branch --"
#fi
#
popd > /dev/null
} # end git-info
#
CheckoutGIT () {
local gitUrl=$1
local bookdir=$2
local book_version=$3
local reType='^[0-9]+([.][0-9]+)?$' # deal decimal book versions
local source="${gitUrl}/lfs.git"
local destin="${bookdir}/${book_version}/lfs"
# download the book
git clone $source $destin
# add lfs: to the Makefile
sed -i '/book:/i lfs: book wget-list\n' "${destin}/Makefile"
# deal with a released book
if [[ $book_version =~ $reType ]] ; then
echo "will do git checkout $book_version"
pushd "${bookdir}/${book_version}/lfs" > /dev/null
git checkout -b $book_version "origin/${book_version}"
popd > /dev/null
fi
#
} # end CheckoutGIT
#
DumpCommands () {
# $1 is the Repository - LFS in this case
# $2 is the dir containing the book
# $3 is the book version
local bookdir=$2
local book_version=$3
local rev="systemd" # default
if [ "$SYSTEMD" = no ]; then rev="sysv"; fi
#
GITINFO=$(git-info)
local target=$( echo $1 | awk '{print tolower($1)}')
REPODIR=${bookdir}/${book_version}/${target}
GITrevision=$( echo $GITINFO | awk 'BEGIN{ RS = "|" };/Revision/ {print $0}' )
commandRevision=""
if [ -e "$DumpedCommands/.revision" ]; then # exists so set commandRevision
commandRevision=$( cat $DumpedCommands/.revision | awk '/Revision/ {print $0}')
fi
if [ "$commandRevision" != "$GITrevision" ]; then # dump the new commands
rm -rf $DumpedCommands # make sure they don't exist
rm -rf $Dumpedhtml
install -vdm755 $DumpedCommands
install -vdm755 $Dumpedhtml
if [ ! -e ${DumpedCommands}/.revision ]; then touch ${DumpedCommands}/.revision; fi # suppress a 'No such file' warning
pushd $REPODIR > /dev/null
make -j1 DUMPDIR=$DumpedCommands BASEDIR=$Dumpedhtml REV=$rev $target "dump-commands"
for dir in $DumpedCommands $Dumpedhtml; do
echo $GITINFO | awk 'BEGIN{ RS = "|" }; {print $0}' > ${dir}/.revision
done
popd > /dev/null
mkdir -pv ${SOURCEDIR}/${book_version}
if [ ! -e ${SOURCEDIR}/${book_version}/wget-list ]; then # try and mv it from Dumpedhtml
if [ -e ${Dumpedhtml}/wget-list ]; then
mv ${Dumpedhtml}/wget-list ${SOURCEDIR}/${book_version}/
mv ${Dumpedhtml}/md5sums ${SOURCEDIR}/${book_version}/
else
echo "There is no wget-list file in $Dumpedhtml"
echo "You need to make sure that docbook-xml and docbook-xsl"
echo "are installed on the host"
echo "Abort"
exit 1
fi
fi
fi
} # end of DumpCommands
#
CleanSourceDir () {
local srcdir=$1
local wgetlistFile=$2
if [ -d $srcdir ]; then
# delete any file in $srcdir that is in $wgetlistFile
if [ -e $wgetlistFile ]; then
while read FUrl; do
if [[ ${FUrl:0:1} != '#' ]]; then # ignore file if it has a hash at the start
fileinlist=$( echo $FUrl | awk -F\/ '{print $NF}' )
[ -e ${srcdir}/${fileinlist} ] && rm -rf ${srcdir}/${fileinlist}
fi
done < $wgetlistFile
fi
else
rm -rf $srcdir # remove any file called $srcdir - it needs to be a dir
install -v -m0755 -d $srcdir
fi
} #end CleanSourceDir
#
ChkPkgExists () {
# Used with the SINGLE_PACKAGE option.
# checks that the requested package is in the wgetlist file
local wgetlistFile=$1
local packageName=("${!2}")
local pkgURL
local fileinURL=""
#
echo "in ChkPkgExists"
echo "packageName is ${packageName[@]}"
if [ -e $wgetlistFile ]; then
while read pkgURL; do
fileinURL=$( echo $pkgURL | awk -F\/ '{print $NF}' )
if [[ "$fileinURL" == ${packageName[0]}*.tar.?z* ]]; then
fileinURL=$( echo $fileinURL | awk -F\/ '{print $NF}' )
rtrnName=($fileinURL)
return 0
fi
done < $wgetlistFile
return $RETURN_FNF
else
return $RETURN_PARAM
fi
} # end ChkPkgExists
#
GetPkgName () {
# given a source file name, returns the package name for LFS packages
# $1 is the name of the src file
local pkgvers
local srcfile=$1
local pkgnm=$(echo $srcfile | awk -F\- '{print $1}')- # assumes the separator is -
case $srcfile in
expect*|tcl8*) # separator is .
pkgnm=$(echo $srcfile | awk -F\. '{print $1}')
pkgnm=${pkgnm%?} # remove trailing numeric
;;
iana-etc*|man-db*|man-pages*|pkg-config*|procps-ng*|util-linux*|XML-Parser*) # need $1 and $2 from awk
pkgnm=$(echo $srcfile | awk -F\- '{print $1"-"$2}')-
;;
tzdata*)
pkgnm=$(echo $srcfile | awk -F\. '{print $1}') # separator is .
pkgvers="${pkgnm#*tzdata}"
pkgnm="${pkgnm%${pkgvers}*}"
;;
esac
echo $pkgnm
return 0
} # end GetPkgName
#
uniqueArray () {
# $1 is the array to sort
local unsorted_array=("${!1}")
local ip
local IFS=$'\n'
local sorted_array=( $(printf "%s\n" "${unsorted_array[@]}" | sort -u) )
rtrnSorted=(${sorted_array[@]})
} # end uniqueArray
#
get_crtime() {
# get the creation time (crtime) of a file
# $1 is the filename
# $2 is the file location - no final /
# NOTE need the -P option for grep implemented (if necessary recompile grep with pcre support)
#
local target=${2}/${1}
local inode=$(stat -c %i "${target}")
local fs=$(df "${target}" | tail -1 | awk '{print $1}')
local crtime=$(sudo debugfs -R 'stat <'"${inode}"'>' "${fs}" 2>/dev/null | grep -oP 'crtime.*--\s*\K.*')
echo $crtime
}
#
detExtType () {
# determine the extension type of a tar file
# the hierarchy is xz, bz2, gz, tgz and zip
local sortedVers=("${!1}")
local isXZ=false
local isLZMA=false
local isBZ2=false
local isGZ=false
local isGZ2=false
local ispatchGZ=false
local isTGZ=false
local isZIP=false
local isTAR=false
local extType
#
for ((in=0; in<${#sortedVers[@]}; in++)); do # decide which files to test, .xz, .bz2, .gz, .tgz or zip
case ${sortedVers[in]} in
*tar.xz*)
isXZ=true # if .xz file present, don't need to continue searching
break
;;
*.tar.lzma*) # e.g. curl
isLZMA=true
;;
*tar.bz2*)
isBZ2=true
;;
*tar.gz*)
isGZ=true
;;
*.patch.gz*) # for a gz patch file
ispatchGZ=true
break
;;
*[0-9].gz*) # if no tar in name
isGZ2=true
trimto=".gz"
;;
*.tgz*)
isTGZ=true
;;
*.zip*)
isZIP=true
;;
*-signed.tar) # for any signed file
isTAR=true
break
;;
esac
done
# Set extension type to use, based on the hierarchy of tar files
if $isXZ; then
extType="xz"
elif $isLZMA; then
extType="lzma"
elif $isBZ2; then
extType="bz2"
elif $isGZ; then
extType="gz"
elif $ispatchGZ; then
extType="patch.gz"
elif $isGZ2; then
extType="gz2"
elif $isTGZ; then
extType="tgz"
elif $isZIP; then
extType="zip"
elif $isTAR; then
extType="tar"
else
return $RETURN_PARAM
fi
echo $extType
return 0
} # end detExtType
#
compare_versions () {
#
# compares two version numbers
# returns $RETURN_GT if $1 > $2
# return $RETURN_EQ if $1 = $2
# otherwise returns 0
# $3 is the separator to parse the version number, usually .
#
local IFS="$3"
local a1=( $1 )
local a2=( $2 )
# some versions have a - in them, e.g. ImageMagick
local b1=$(IFS='-'; echo "${a1[*]}") # string b1 is now - delimited
local b2=$(IFS='-'; echo "${a2[*]}")
IFS='-' read -ra a1 <<< "$b1" # put delimited string back into array
IFS='-' read -ra a2 <<< "$b2"
#echo "a1 is ${a1[@]}"
#echo "a2 is ${a2[@]}"
local num_a1=${#a1[@]}
local num_a2=${#a2[@]}
#echo "numa1, numa2 are $num_a1 $num_a2"
local max=$(( $num_a1 > $num_a2 ? $num_a1 : $num_a2 ))
local im
for (( im=0; im<$max; im++ )); do
# deal with invalid octal. usbutils uses 00 type versioning.
if [ "${a1[im]}" = "08" -o "${a1[im]}" = "09" ]; then a1[im]=${a1[im]#?}; fi
if [ "${a2[im]}" = "08" -o "${a2[im]}" = "09" ]; then a2[im]=${a2[im]#?}; fi
if [ "${a1[im]}" = "008" -o "${a1[im]}" = "009" ]; then a1[im]=${a1[im]#??}; fi
if [ "${a2[im]}" = "008" -o "${a2[im]}" = "009" ]; then a2[im]=${a2[im]#??}; fi
#echo "a1 is ${a1[im]}"
#echo "a2 is ${a2[im]}"
if [ "${a1[im]}" -eq "${a1[im]}" ] 2>/dev/null; then # is integer
if [ "${a2[im]}" -eq "${a2[im]}" ] 2>/dev/null; then # can compare
(("${a1[im]}" > "${a2[im]}")) && return $RETURN_GT
(("${a2[im]}" > "${a1[im]}")) && return 0
else
return $RETURN_GT # a2 missing so a1 greater
fi
else
return 0 # a2 greater
fi
done
# if got here then a1 and a2 are equal
return $RETURN_EQ
} # end compare_versions
#
# test if integer, float or just a string
testIntFloatChar () {
# $1 is the string to test
local testString=$1
if [[ $testString =~ ^[+-]?[0-9]+$ ]]; then return $isInt; fi
if [[ $testString =~ ^[+-]?[0-9]+\.?[0-9]*$ ]]; then return $isFloat; fi
if [[ $testString =~ ^[+-]?[0-9]+\.$ ]]; then return $isChar; fi
return $isChar
}
#
updateSorted () {
# $1 is the array holding the list of "Click to enter 'version' strings"
# $2 is the url
# $3 is the package name, no version num but include the - after the name
# $4 is the file extension, .tar.xz, .tar.bz2, .tar.gz, .tgz or .zip
# $5 is the index number in ClickToDnld containing the filename
local ClickToEnter=("${!1}")
#echo "in updateSorted"
local ClickToDnld # array containing list of "Click to download 'filename' strings"
local latestVer=${ClickToEnter[1]} # assumes the first one is the latest - note [0] is empty
latestVer=${latestVer#"Click to enter "} # version number