OSDN Git Service

Fixed a bug related to the previous modification.
[portsreinstall/current.git] / lib / libmisc.sh
1 #!/bin/sh -e
2 # ==============================================================================
3 # portsreinstall library script
4 # - Miscellaneous functions -
5 # Copyright (C) 2013-2018 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
8
9 # ============= Variables =============
10 MISC_IS_READONLY_MODE=no
11 MISC_DEFAULT_CONSOLE_SIZE='25 80'
12
13 # ============= Check whether the current process is by the superuser privilege =============
14 misc_is_superuser_privilege ()
15 {
16         [ `id -u` -eq 0 -a "$MISC_IS_READONLY_MODE" = no ]
17 }
18
19 # ============= Lock for duplicated executions =============
20 misc_lock_duplicated_executions ()
21 {
22         local lockfile
23         lockfile=$1
24         MISC_IS_READONLY_MODE=no
25         [ `id -u` -eq 0 ] || return 0
26         if mktemp -q "$lockfile" > /dev/null
27         then
28                 echo $$ > $lockfile
29         elif [ x`cat "$lockfile" 2> /dev/null` != x$$ ]
30         then
31                 message_echo "WARNING: Another ${APPNAME} process is running; commands requiring the superuser privilege is unavailable." >&2
32                 message_echo "If this report is incorrect, remove an obsolete lock file ($lockfile)." >&2
33                 message_echo >&2
34                 MISC_IS_READONLY_MODE=yes
35         fi
36         :
37 }
38
39 # ============= Abort if the execution is locked or the user does not have the superuser privilege =============
40 misc_chk_privilege ()
41 {
42         misc_is_superuser_privilege && return
43         [ "$MISC_IS_READONLY_MODE" = yes ] && message_echo "ERROR: Locked for this command." >&2
44         [ `id -u` -ne 0 ] && message_echo "ERROR: The superuser privilege is required for this command." >&2
45         exit 1
46 }
47
48 # ============= Get all shell variable definitions (without functions) =============
49 # Actually, this filtering is unnecessary for Bourne shell and only required for Bash.
50 # Since the overhead is not harmful, I will keep this for correspondence to possible future changes.
51 misc_get_all_vardefs ()
52 {
53         set | sed -E '/^[^ ]+ \(\) *$/,/^\}$/d'
54 }
55
56 # ============= Initialize shell variable definitions =============
57 misc_init_vardefs ()
58 {
59         eval `misc_get_all_vardefs | grep -E '^[a-z_][a-zA-Z0-9_]+=' | sed 's/=.*//;s/^/unset /'`
60 }
61
62 # ============= Get the size of the current console =============
63 misc_get_console_size ()
64 {
65         local size
66         size=`stty -f /dev/stdin size 2> /dev/null || :`
67         if [ -n "$size" ]
68         then
69                 echo "$size" > ${TMPDIR}/misc_get_console_size::size
70         else
71                 if [ ! -e "${TMPDIR}/misc_get_console_size::size" ]
72                 then
73                         size=`stty -f /dev/console size 2> /dev/null || :`
74                 else
75                         size=`cat "${TMPDIR}/misc_get_console_size::size"`
76                 fi
77         fi
78         [ -n "$size" ] || size=$MISC_DEFAULT_CONSOLE_SIZE
79         echo "$size"
80 }
81
82 # ============= Get the number of columns for the current console =============
83 misc_get_console_column_size ()
84 {
85         misc_get_console_size | sed -E 's/^[^ ]+ +([^ ]+)/\1/'
86 }
87
88 # ============= Get the number of rows for the current console =============
89 misc_get_console_row_size ()
90 {
91         misc_get_console_size | sed -E 's/^([^ ]+) +[^ ]+/\1/'
92 }
93
94 # ============= Check whether the current environment is in a jail =============
95 misc_chk_in_jail ()
96 {
97         local status
98         status=`sysctl -n security.jail.jailed`
99         [ x"$status" != x0 ]
100 }
101
102 # ============= Selection of removing leaf ports =============
103 # Box options for dialog(1) are given via stdin.
104 misc_dialog_checklist ()
105 {
106         local title desc dstfile itemlist cmdscript LINES COLUMNS hight width width_desc lines_desc hight_list width_list nlines iline len_tag tag len_tag_cur len_item_max len_item_trim
107         title=$1
108         desc=$2
109         dstfile=$3
110         itemlist=$4
111         cmdscript=${TMPDIR}/misc_dialog_checklist::command
112         if [ `wc -l < $itemlist` -eq 0 ]
113         then
114                 cp /dev/null "$dstfile"
115                 return 0
116         fi
117         echo -n 'dialog --title "$title" --checklist "$desc" $hight $width $hight_list ' > $cmdscript
118         COLUMNS=`misc_get_console_column_size`
119         LINES=`misc_get_console_row_size`
120         hight=$(($LINES-3))
121         [ $hight -gt 0 ] || hight=$LINES
122         width=$(($COLUMNS-5))
123         [ $width -gt 0 ] || width=$COLUMNS
124         width_desc=$(($width-4))
125         [ $width_desc -gt 0 ] || width_desc=$COLUMNS
126         lines_desc=`echo "$desc" | sed -E 's/\\n/\
127 /g' | fold -s -w $width_desc | wc -l`
128         hight_list=$(($hight-$lines_desc-6))
129         [ $hight_list -gt 0 ] || hight_list=$LINES
130         width_list=$(($width-6))
131         [ $width_list -gt 0 ] || width_list=$COLUMNS
132         nlines=`wc -l < $itemlist`
133         iline=1
134         len_tag=0
135         while [ $iline -le $nlines ]
136         do
137                 tag=`sed -n "${iline}p" "$itemlist" | cut -f 1`
138                 iline=$(($iline+1))
139                 len_tag_cur=`echo -n "$tag" | wc -c`
140                 [ $len_tag_cur -gt $len_tag ] && len_tag=$len_tag_cur
141         done
142         iline=1
143         len_item_max=$(($width_list-$len_tag-6))
144         [ $len_item_max -gt 0 ] || len_item_max=$width_list
145         len_item_trim=$(($len_item_max-3))
146         [ $len_item_trim -gt 0 ] || len_item_trim=$len_item_max
147         while [ $iline -le $nlines ]
148         do
149                 tag=`sed -n "${iline}p" "$itemlist" | cut -f 1`
150                 item=`sed -n "${iline}p" "$itemlist" | cut -f 2`
151                 status=`sed -n "${iline}p" "$itemlist" | cut -f 3`
152                 iline=$(($iline+1))
153                 len_item=`echo -n "$item" | wc -c`
154                 if [ $len_item -gt $len_item_max ]
155                 then
156                         item=`echo -n "$item" | head -c $len_item_trim`...\"
157                 fi
158                 echo -n "$tag $item $status "
159         done >> $cmdscript
160         echo ' 2> ${TMPDIR}/misc_dialog_checklist::selected_items || :' >> $cmdscript
161         . "$cmdscript"
162         tr -d \" < ${TMPDIR}/misc_dialog_checklist::selected_items | tr ' ' '\n' > $dstfile
163         echo >> $dstfile
164 }
165