|
Lines 1-1176
Link Here
|
| 1 |
#!/bin/sh |
|
|
| 2 |
|
| 3 |
sz_usage="I need 0 (zero) mandatory args : `basename $0` [optional arguments] |
| 4 |
|
| 5 |
Legend of [optional arguments] :: |
| 6 |
|
| 7 |
--begin <level> : Use <level> as the beginning stage |
| 8 |
( |
| 9 |
defaults to 1. But you can specify a higher value as long as it is lower |
| 10 |
than or equal to end. You can also specify a begin value of 0 - stage 0 runs |
| 11 |
a special initialization procedure to set up your graphics subsystem |
| 12 |
) |
| 13 |
|
| 14 |
--end <level> : Use <level> as the last stage to process |
| 15 |
( |
| 16 |
defaults to the highest stage value available, as evaluated at runtime. But |
| 17 |
you can change that to something lower, as long as it is at least equal to |
| 18 |
the begin value |
| 19 |
) |
| 20 |
|
| 21 |
--pkg_list_dir <dir> : Use <dir> as the package list directory |
| 22 |
(defaults to \$HOME/mkdesktop/pkg_list) |
| 23 |
|
| 24 |
--no-postproc : Disable the postproc function that kicks in automatically upon |
| 25 |
processing of regular stages to configure emulation layers and system files |
| 26 |
|
| 27 |
--dry : in dry mode, special functions (stage 0; post-processor) are |
| 28 |
disabled and regular stage levels are processed by 'pkg install --dry-run', |
| 29 |
unless you specify --echo too (in which case the --dry argument is silently |
| 30 |
ignored). --dry is available to non-root users too. |
| 31 |
|
| 32 |
--echo : in echo mode, special functions (stage 0; post-processor) are |
| 33 |
disabled and regular stage levels are processed by 'echo', not 'pkg install'. |
| 34 |
--echo takes precedence over --dry, as well as is available to non-root users |
| 35 |
too. This is useful for testing what non-automatic packages would get installed |
| 36 |
by this script. |
| 37 |
|
| 38 |
--append : in append mode, packages mentioned in package list files are |
| 39 |
appended to the stage definition lists, which otherwise would be superseded. |
| 40 |
|
| 41 |
--help : print an introductory manual |
| 42 |
(this uses \$EDITOR, if set. If not set, rvim or else rjoe or else vi) |
| 43 |
|
| 44 |
--usage : print usage information" |
| 45 |
|
| 46 |
location=$HOME/mkdesktop |
| 47 |
pkg_list_dir="$location/pkg_list" |
| 48 |
no_postproc=false |
| 49 |
|
| 50 |
mode_echo=false |
| 51 |
mode_dry=false |
| 52 |
mode_append=false |
| 53 |
mode_yes=false |
| 54 |
|
| 55 |
begin=1 |
| 56 |
end=-1 |
| 57 |
|
| 58 |
arg_begin=false |
| 59 |
arg_end=false |
| 60 |
|
| 61 |
dummy=0 |
| 62 |
|
| 63 |
die() |
| 64 |
{ |
| 65 |
[ $# -eq 0 ] && exit 1 |
| 66 |
|
| 67 |
[ $# -gt 1 ] && \ |
| 68 |
echo "error initiated at line $1 : |
| 69 |
$2" 1>&2 || \ |
| 70 |
echo "$1" 1>&2 |
| 71 |
|
| 72 |
exit 1 |
| 73 |
} |
| 74 |
|
| 75 |
while echo "$1" | grep '^--' > /dev/null; do |
| 76 |
case "$1" in |
| 77 |
--begin) |
| 78 |
shift |
| 79 |
begin="" |
| 80 |
|
| 81 |
if [ $# -gt 0 ]; then |
| 82 |
if echo $1 | grep '[^[:digit:]]' > /dev/null; then |
| 83 |
die "$LINENO" "Bad digital value for begin : $1" |
| 84 |
else |
| 85 |
begin="$1" |
| 86 |
arg_begin=true |
| 87 |
shift |
| 88 |
fi |
| 89 |
fi |
| 90 |
;; |
| 91 |
|
| 92 |
--end) |
| 93 |
shift |
| 94 |
end="" |
| 95 |
|
| 96 |
if [ $# -gt 0 ]; then |
| 97 |
if echo $1 | grep '[^[:digit:]]' > /dev/null; then |
| 98 |
die "$LINENO" "Bad digital value for end : $1" |
| 99 |
else |
| 100 |
end="$1" |
| 101 |
arg_end=true |
| 102 |
shift |
| 103 |
fi |
| 104 |
fi |
| 105 |
;; |
| 106 |
|
| 107 |
--pkg_list_dir) |
| 108 |
shift |
| 109 |
pkg_list_dir="" |
| 110 |
|
| 111 |
if [ $# -gt 0 ]; then |
| 112 |
pkg_list_dir="$1" |
| 113 |
shift |
| 114 |
fi |
| 115 |
;; |
| 116 |
|
| 117 |
--no-postproc) |
| 118 |
shift |
| 119 |
no_postproc=true |
| 120 |
;; |
| 121 |
|
| 122 |
--dry) |
| 123 |
shift |
| 124 |
mode_dry=true |
| 125 |
;; |
| 126 |
|
| 127 |
--echo) |
| 128 |
shift |
| 129 |
mode_echo=true |
| 130 |
;; |
| 131 |
|
| 132 |
--append) |
| 133 |
shift |
| 134 |
mode_append=true |
| 135 |
;; |
| 136 |
|
| 137 |
--help) |
| 138 |
my_editor="$EDITOR" |
| 139 |
[ -z "$my_editor" ] && [ -x /usr/local/bin/rvim ] && my_editor=/usr/local/bin/rvim |
| 140 |
[ -z "$my_editor" ] && [ -x /usr/local/bin/rjoe ] && my_editor=/usr/local/bin/rjoe |
| 141 |
[ -z "$my_editor" ] && my_editor=vi |
| 142 |
|
| 143 |
"$my_editor" /usr/local/share/mkdesktop/mkdesktop.help |
| 144 |
exit 0 |
| 145 |
;; |
| 146 |
|
| 147 |
--usage) |
| 148 |
echo "$sz_usage" |
| 149 |
exit 0 |
| 150 |
;; |
| 151 |
|
| 152 |
*) |
| 153 |
die "$LINENO" "Invalid optional arg : $1" |
| 154 |
;; |
| 155 |
esac |
| 156 |
done |
| 157 |
|
| 158 |
[ $# -eq 0 ] || { die "$sz_usage"; } |
| 159 |
|
| 160 |
stage=0 |
| 161 |
idents="" |
| 162 |
|
| 163 |
for var in location pkg_list_dir; do |
| 164 |
eval val='$'$var |
| 165 |
[ -z "$val" ] && die "$LINENO" "Empty string for $var" |
| 166 |
done |
| 167 |
|
| 168 |
if ! [ -d "$location" ]; then |
| 169 |
cat <<-EOF |
| 170 |
This seems to be the first time you are running mkdesktop. |
| 171 |
|
| 172 |
I can help you with the initial layout for running mkdesktop smoothly. |
| 173 |
|
| 174 |
If you wish, I can : |
| 175 |
|
| 176 |
1) create the directory $HOME/mkdesktop |
| 177 |
(which hosts the stage-definitions file) |
| 178 |
|
| 179 |
2) create a default $HOME/mkdesktop/stage-definitions |
| 180 |
(which should be good enough to get you started) |
| 181 |
|
| 182 |
Of course, you can always create the above by hand. And you can always |
| 183 |
customize your stage-definitions file. You are encouraged to at least read |
| 184 |
your stage-definitions file ($HOME/mkdesktop/stage-definitions), just to get |
| 185 |
a feel of what lies therein, and perhaps define a custom stage too, so that |
| 186 |
you becomes familiar with mkdesktop's working and ensure that everything |
| 187 |
works seamlessly end-to-end for you. If you mess up your stage-definitions |
| 188 |
file, no probs : just copy out afresh from /usr/local/share/mkdesktop/ |
| 189 |
|
| 190 |
If you later decide to boost your setup with package list files (read the |
| 191 |
output of --help for this), put them under the directory |
| 192 |
$HOME/mkdesktop/pkg_list (which too I can create right now; or else, you can |
| 193 |
create yourself later). |
| 194 |
|
| 195 |
What would you like me to do ? |
| 196 |
|
| 197 |
I) Initialize the setup |
| 198 |
S) Skip initialization |
| 199 |
|
| 200 |
Press Control-C if you wish to abort. |
| 201 |
|
| 202 |
Your choice ? (I/S) : |
| 203 |
EOF |
| 204 |
|
| 205 |
read answer |
| 206 |
|
| 207 |
case "$answer" in |
| 208 |
i|I) |
| 209 |
set -e |
| 210 |
mkdir $HOME/mkdesktop |
| 211 |
cp /usr/local/share/mkdesktop/stage-definitions $HOME/mkdesktop/stage-definitions |
| 212 |
mkdir $HOME/mkdesktop/pkg_list |
| 213 |
|
| 214 |
cat <<-EOF |
| 215 |
|
| 216 |
mkdesktop has been initialized. |
| 217 |
|
| 218 |
If you wish to alter the stage-definitions or package list files for |
| 219 |
this run, you can do still do it from another terminal window. |
| 220 |
|
| 221 |
When ready, press Enter to continue (or Control-C to abort) |
| 222 |
EOF |
| 223 |
|
| 224 |
read enter |
| 225 |
set +e |
| 226 |
;; |
| 227 |
|
| 228 |
s|S) |
| 229 |
;; |
| 230 |
|
| 231 |
*) |
| 232 |
echo "I could not make sense of your choice : - (" 1>&2 |
| 233 |
exit 1 |
| 234 |
;; |
| 235 |
esac |
| 236 |
fi |
| 237 |
|
| 238 |
[ -f "$location"/stage-definitions ] && \ |
| 239 |
{ . "$location"/stage-definitions; } || \ |
| 240 |
{ echo "Warning : $location/stage-definitions does not exist" 1>&2; } |
| 241 |
|
| 242 |
for var in begin end; do |
| 243 |
eval val='$'$var |
| 244 |
|
| 245 |
[ $var = end ] && [ "$val" = "-1" ] && val=0 |
| 246 |
[ -z "$val" ] && die "$LINENO" "Empty string for $var" |
| 247 |
|
| 248 |
echo "$val" | grep '[^[:digit:]]' > /dev/null && \ |
| 249 |
die "$LINENO" "Bad digital value ($var) : ${val}" |
| 250 |
done |
| 251 |
|
| 252 |
[ $end -gt $stage ] && \ |
| 253 |
die "$LINENO" "end must not be greater than the highest stage value ($stage)" |
| 254 |
|
| 255 |
[ $end -lt 0 ] && end=$stage |
| 256 |
|
| 257 |
if [ $begin -gt $end ]; then |
| 258 |
[ $end -eq 0 ] && echo "Have you defined at least one stage ?" 1>&2 |
| 259 |
die "$LINENO" "begin must not be greater than end" |
| 260 |
fi |
| 261 |
|
| 262 |
if [ "$mode_echo" = "false" -a "$mode_dry" = "false" ]; then |
| 263 |
dummy=`expr $dummy + 1` |
| 264 |
|
| 265 |
[ `id -u` -eq 0 ] || die "You need to be root to execute this script" |
| 266 |
fi |
| 267 |
|
| 268 |
f_stagezero() |
| 269 |
{ |
| 270 |
if [ "$mode_echo" = "false" -a "$mode_dry" = "false" ]; then |
| 271 |
cat <<-EOF |
| 272 |
|
| 273 |
This special stage has only one thing to do : |
| 274 |
setup any needed kld's for your graphics chipset |
| 275 |
|
| 276 |
Continue ? (y/n) : |
| 277 |
EOF |
| 278 |
|
| 279 |
read answer |
| 280 |
|
| 281 |
case "$answer" in |
| 282 |
y|Y) |
| 283 |
cat <<-EOF |
| 284 |
|
| 285 |
What is your graphics chipset : |
| 286 |
|
| 287 |
1) radeon [ needs radeon.ko; radeonkms.ko : |
| 288 |
both shipped by FreeBSD in the base distribution ] |
| 289 |
|
| 290 |
2) nvidia [ needs nvidia.ko; nvidia-modeset.ko : |
| 291 |
both intalled via nvidia-driver ] |
| 292 |
|
| 293 |
3) other [ needs nothing/something I am not aware of ] |
| 294 |
|
| 295 |
Your choice ? (1/2/3) : |
| 296 |
EOF |
| 297 |
|
| 298 |
read answer |
| 299 |
|
| 300 |
case "$answer" in |
| 301 |
1) |
| 302 |
for k in radeon radeonkms; do |
| 303 |
echo "kldstat -qn $k || kldload $k" >> /etc/rc.local |
| 304 |
done |
| 305 |
|
| 306 |
return $? |
| 307 |
;; |
| 308 |
|
| 309 |
2) |
| 310 |
pkg install nvidia-driver |
| 311 |
|
| 312 |
[ $? -eq 0 ] || die "$LINENO" "nvidia-driver install failed" |
| 313 |
|
| 314 |
for k in nvidia nvidia-modeset; do |
| 315 |
echo "kldstat -qn $k || kldload $k" >> /etc/rc.local |
| 316 |
done |
| 317 |
|
| 318 |
return $? |
| 319 |
;; |
| 320 |
|
| 321 |
3) |
| 322 |
return 0 |
| 323 |
;; |
| 324 |
|
| 325 |
*) |
| 326 |
echo "I do not know what to make of that : - (" 1>&2 |
| 327 |
return 1 |
| 328 |
;; |
| 329 |
|
| 330 |
esac |
| 331 |
;; |
| 332 |
|
| 333 |
n|N) |
| 334 |
;; |
| 335 |
|
| 336 |
*) |
| 337 |
echo "I do not know what to make of that : - (" 1>&2 |
| 338 |
return 1 |
| 339 |
;; |
| 340 |
esac |
| 341 |
fi |
| 342 |
} |
| 343 |
|
| 344 |
fix_noeol() |
| 345 |
{ |
| 346 |
[ $# -gt 0 ] || { echo "missing mandatory arg : <file>" 1>&2; return 1; } |
| 347 |
[ -f "$1" ] || { echo "$1 is not a regular file" 1>&2; return 1; } |
| 348 |
|
| 349 |
local r=0 |
| 350 |
local f="$1" |
| 351 |
|
| 352 |
if file "$f" | grep '\<ASCII text\>' > /dev/null; then |
| 353 |
local last="`tail -c1 \"$f\"`" |
| 354 |
|
| 355 |
if [ -n "$last" ]; then |
| 356 |
[ -w "$f" ] || { echo "$f is not writable" 1>&2; return 1; } |
| 357 |
|
| 358 |
echo >> "$f" |
| 359 |
r=$? |
| 360 |
fi |
| 361 |
fi |
| 362 |
|
| 363 |
return $r |
| 364 |
} |
| 365 |
|
| 366 |
f_stage() |
| 367 |
{ |
| 368 |
[ $# -ne 1 ] && \ |
| 369 |
{ echo "f_stage() :: I need 1 arg : stage name (ident)" 1>&2; return 1; } |
| 370 |
|
| 371 |
[ -z "$1" ] && \ |
| 372 |
{ echo "f_stage() :: I need 1 arg : stage name (ident)" 1>&2; return 1; } |
| 373 |
|
| 374 |
if ! echo "$idents" | grep -w "$1" > /dev/null; then |
| 375 |
echo "f_stage() :: I could not locate $1 among the definitions" 1>&2 |
| 376 |
return 1 |
| 377 |
fi |
| 378 |
|
| 379 |
echo -e "\e[4m${1}\e[0m :: \c" |
| 380 |
|
| 381 |
local nextline="" |
| 382 |
local firstchar="" |
| 383 |
local lines=0 |
| 384 |
local index=0 |
| 385 |
|
| 386 |
local file="" |
| 387 |
eval local arg='$'list_${1} |
| 388 |
|
| 389 |
local list="`echo $arg | sed 's/:/ /g'`" |
| 390 |
|
| 391 |
[ -f "$pkg_list_dir"/"$1" ] && file="$pkg_list_dir"/"$1" |
| 392 |
|
| 393 |
if [ -n "$file" ]; then |
| 394 |
fix_noeol "$file" |
| 395 |
|
| 396 |
[ "$mode_append" = "false" ] && list="" |
| 397 |
lines="`cat $file | wc -l | sed 's/^[[:space:]]*//'`" |
| 398 |
index=1 |
| 399 |
|
| 400 |
while [ $index -le $lines ]; do |
| 401 |
nextline="`sed -n ${index}p $file`" |
| 402 |
|
| 403 |
if [ -n "$nextline" ]; then |
| 404 |
firstchar="`echo $nextline | cut -c1`" |
| 405 |
|
| 406 |
if [ "$firstchar" = '#' ]; then |
| 407 |
dummy=`expr $dummy + 1` |
| 408 |
else |
| 409 |
[ -z "$list" ] && list="$nextline" || list="$list $nextline" |
| 410 |
fi |
| 411 |
fi |
| 412 |
|
| 413 |
index=`expr $index + 1` |
| 414 |
done |
| 415 |
fi |
| 416 |
|
| 417 |
local cmd="pkg install" |
| 418 |
|
| 419 |
[ "$mode_dry" = "true" ] && \ |
| 420 |
{ cmd="$cmd --dry-run"; } || \ |
| 421 |
{ [ "$mode_yes" = "true" ] && cmd="$cmd --yes"; } |
| 422 |
|
| 423 |
[ "$mode_echo" = true ] && cmd="echo" |
| 424 |
|
| 425 |
[ -z "$list" ] && echo || { $cmd $list; } |
| 426 |
local r=$? |
| 427 |
|
| 428 |
[ "$mode_dry" = "true" ] && [ $r -eq 1 ] && r=0 |
| 429 |
return $r |
| 430 |
} |
| 431 |
|
| 432 |
[ $begin -gt 0 ] || f_stagezero |
| 433 |
[ $? -eq 0 ] || die "$LINENO" "stage failure setting up graphics subsystem" |
| 434 |
[ $end -eq 0 ] && exit 0 |
| 435 |
|
| 436 |
postproc() |
| 437 |
{ |
| 438 |
[ "$mode_dry" = "true" ] && return 0 |
| 439 |
[ "$mode_echo" = "true" ] && return 0 |
| 440 |
[ "$no_postproc" = "true" ] && return 0 |
| 441 |
|
| 442 |
cat <<-EOF |
| 443 |
|
| 444 |
Your desktop has been successfully installed : - ) |
| 445 |
|
| 446 |
I am now going to start post-install processing to set up the following : |
| 447 |
|
| 448 |
Wine (32-bit/64-bit Windows emulation layer, user-space) |
| 449 |
Linuxulator (64-bit Linux emulation layer, kernel-space) |
| 450 |
|
| 451 |
System files : |
| 452 |
/etc/fstab |
| 453 |
/etc/devfs.conf |
| 454 |
/etc/devfs.rules |
| 455 |
/etc/rc.conf |
| 456 |
/etc/sysctl.conf |
| 457 |
/boot/loader.conf |
| 458 |
|
| 459 |
I will seek permission from you for each of the above individually : - ) |
| 460 |
|
| 461 |
Note : If you ask me to configure system files, existing originals will be |
| 462 |
saved with .bak extension |
| 463 |
EOF |
| 464 |
|
| 465 |
b_valid=false |
| 466 |
|
| 467 |
while [ "$b_valid" = "false" ]; do |
| 468 |
cat <<-EOF |
| 469 |
|
| 470 |
Would you like me to kick off post-processing ? |
| 471 |
|
| 472 |
y) Do it |
| 473 |
n) Cancel this [and exit immediately] |
| 474 |
|
| 475 |
Your choice ? (y/n) : |
| 476 |
EOF |
| 477 |
|
| 478 |
read answer |
| 479 |
|
| 480 |
case "$answer" in |
| 481 |
y|Y) |
| 482 |
b_valid=true |
| 483 |
;; |
| 484 |
|
| 485 |
n|N) |
| 486 |
b_valid=true |
| 487 |
exit 0 |
| 488 |
;; |
| 489 |
|
| 490 |
*) |
| 491 |
echo "I do not know what to make of that : - (" 1>&2 |
| 492 |
;; |
| 493 |
esac |
| 494 |
done |
| 495 |
|
| 496 |
readonly UNITY=1 |
| 497 |
readonly WIN32=$(( UNITY<<1 )) |
| 498 |
readonly WIN64=$(( UNITY<<2 )) |
| 499 |
readonly LINUX=$(( UNITY<<3 )) |
| 500 |
|
| 501 |
clear && echo "Beginning postproc" |
| 502 |
|
| 503 |
EMU=0 |
| 504 |
|
| 505 |
echo && echo "Would you like me to set up Wine (Windows emulation layer) ?" |
| 506 |
echo && echo "y/n :" |
| 507 |
read answer |
| 508 |
|
| 509 |
case "$answer" in |
| 510 |
y|Y) |
| 511 |
cat <<-EOF |
| 512 |
|
| 513 |
Choose a mode : |
| 514 |
|
| 515 |
1) 32-bit |
| 516 |
2) 64-bit (This won't work if your system's CPU is 32-bit) |
| 517 |
c) cancel Wine |
| 518 |
EOF |
| 519 |
|
| 520 |
read answer |
| 521 |
|
| 522 |
case "$answer" in |
| 523 |
1) |
| 524 |
EMU=$(( EMU | UNITY | WIN32 )) |
| 525 |
;; |
| 526 |
|
| 527 |
2) |
| 528 |
EMU=$(( EMU | UNITY | WIN64 )) |
| 529 |
;; |
| 530 |
|
| 531 |
c|C) |
| 532 |
;; |
| 533 |
|
| 534 |
*) |
| 535 |
echo "I do not know what that means : - (" |
| 536 |
echo "Skipping Wine" |
| 537 |
;; |
| 538 |
esac |
| 539 |
;; |
| 540 |
|
| 541 |
n|N) |
| 542 |
;; |
| 543 |
|
| 544 |
*) |
| 545 |
echo "I do not know what that means : - (" |
| 546 |
echo "Skipping Wine" |
| 547 |
;; |
| 548 |
esac |
| 549 |
|
| 550 |
echo && echo "Would you like me to set up Linuxulator (Linux emulation layer) ?" |
| 551 |
echo && echo "Note : if you choose y, I will factor the Linuxulator into subsequent processing" |
| 552 |
echo && echo "y/n :" |
| 553 |
|
| 554 |
read answer |
| 555 |
|
| 556 |
case "$answer" in |
| 557 |
y|Y) |
| 558 |
EMU=$(( EMU | UNITY | LINUX )) |
| 559 |
;; |
| 560 |
|
| 561 |
n|N) |
| 562 |
;; |
| 563 |
|
| 564 |
*) |
| 565 |
echo "I do not know what that means : - (" |
| 566 |
echo "Skipping Linuxulator" |
| 567 |
;; |
| 568 |
esac |
| 569 |
|
| 570 |
my_emu=$(( EMU & UNITY )) |
| 571 |
|
| 572 |
result_win32=1 |
| 573 |
result_win64=1 |
| 574 |
result_linux=1 |
| 575 |
|
| 576 |
if [ $my_emu -ne 0 ]; then |
| 577 |
my_emu=$(( EMU & WIN32 )) |
| 578 |
|
| 579 |
if [ $my_emu -ne 0 ]; then |
| 580 |
pkg install --yes i386-wine wine-mono wine-gecko |
| 581 |
result_win32=$? |
| 582 |
fi |
| 583 |
|
| 584 |
my_emu=$(( EMU & WIN64 )) |
| 585 |
|
| 586 |
if [ $my_emu -ne 0 ]; then |
| 587 |
pkg install --yes wine wine-mono wine-gecko |
| 588 |
result_win64=$? |
| 589 |
fi |
| 590 |
|
| 591 |
my_emu=$(( EMU & LINUX )) |
| 592 |
|
| 593 |
if [ $my_emu -ne 0 ]; then |
| 594 |
if ! kldstat -q -n linux; then |
| 595 |
kldload linux |
| 596 |
|
| 597 |
[ $? -eq 0 ] || \ |
| 598 |
die "$LINENO" "Unable to kldload linux" |
| 599 |
fi |
| 600 |
|
| 601 |
pkg install --yes linux_base-c6 |
| 602 |
result_linux=$? |
| 603 |
fi |
| 604 |
fi |
| 605 |
|
| 606 |
flavour_linux=false |
| 607 |
|
| 608 |
if [ $(( EMU & LINUX )) -ne 0 ]; then |
| 609 |
if [ $result_linux -eq 0 ]; then |
| 610 |
flavour_linux=true |
| 611 |
fi |
| 612 |
fi |
| 613 |
|
| 614 |
set -e |
| 615 |
|
| 616 |
#block for /etc/fstab |
| 617 |
{ |
| 618 |
f=/etc/fstab |
| 619 |
mangled=`echo $f | sed 's|[^[:alpha:]]|_|g'` |
| 620 |
|
| 621 |
if [ "$flavour_linux" = "false" ]; then |
| 622 |
eval mandatory${mangled}="\"\ |
| 623 |
fdescfs /dev/fd fdescfs rw 0 0 |
| 624 |
procfs /proc procfs rw 0 0\"" |
| 625 |
|
| 626 |
eval hint${mangled}="\"\ |
| 627 |
If you are going to use the Linuxulator to run Linux applications under |
| 628 |
FreeBSD natively, try this/these in $f once you have setup the Linuxulator |
| 629 |
(most easily done in a single command with 'pkg install linux-sublime3') :\"" |
| 630 |
|
| 631 |
eval suggested${mangled}="\"\ |
| 632 |
tmpfs /compat/linux/dev/shm tmpfs rw,mode=1777,size=1g 0 0 |
| 633 |
linprocfs /compat/linux/proc linprocfs rw 0 0 |
| 634 |
linsysfs /compat/linux/sys linsysfs rw 0 0\"" |
| 635 |
else |
| 636 |
eval mandatory${mangled}="\"\ |
| 637 |
fdescfs /dev/fd fdescfs rw 0 0 |
| 638 |
procfs /proc procfs rw 0 0 |
| 639 |
tmpfs /compat/linux/dev/shm tmpfs rw,mode=1777,size=1g 0 0 |
| 640 |
linprocfs /compat/linux/proc linprocfs rw 0 0 |
| 641 |
linsysfs /compat/linux/sys linsysfs rw 0 0\"" |
| 642 |
|
| 643 |
eval hint${mangled}="" |
| 644 |
eval suggested${mangled}="" |
| 645 |
fi |
| 646 |
} |
| 647 |
|
| 648 |
#block for /etc/devfs.conf |
| 649 |
{ |
| 650 |
f=/etc/devfs.conf |
| 651 |
mangled=`echo $f | sed 's|[^[:alpha:]]|_|g'` |
| 652 |
|
| 653 |
if [ "$flavour_linux" = "false" ]; then |
| 654 |
eval mandatory${mangled}="\"\ |
| 655 |
own /dev/pci root:operator |
| 656 |
perm /dev/pci 0664 |
| 657 |
own /dev/dri/card0 root:operator |
| 658 |
perm /dev/dri/card0 0664 |
| 659 |
own /dev/pass0 root:operator |
| 660 |
perm /dev/pass0 0664 |
| 661 |
own /dev/cd0 root:operator |
| 662 |
perm /dev/cd0 0664 |
| 663 |
own /dev/xpt0 root:operator |
| 664 |
perm /dev/xpt0 0664\"" |
| 665 |
|
| 666 |
eval hint${mangled}="\"\ |
| 667 |
If you're going to use the Linuxulator to run Linux applications under |
| 668 |
FreeBSD natively, try this/these in $f once you have setup the Linuxulator |
| 669 |
(most easily done in a single command with 'pkg install linux-sublime3') :\"" |
| 670 |
|
| 671 |
eval suggested${mangled}="\"\ |
| 672 |
link /compat/linux/dev/shm shm\"" |
| 673 |
else |
| 674 |
eval mandatory${mangled}="\"\ |
| 675 |
own /dev/pci root:operator |
| 676 |
perm /dev/pci 0664 |
| 677 |
own /dev/dri/card0 root:operator |
| 678 |
perm /dev/dri/card0 0664 |
| 679 |
own /dev/pass0 root:operator |
| 680 |
perm /dev/pass0 0664 |
| 681 |
own /dev/cd0 root:operator |
| 682 |
perm /dev/cd0 0664 |
| 683 |
own /dev/xpt0 root:operator |
| 684 |
perm /dev/xpt0 0664 |
| 685 |
link /compat/linux/dev/shm shm\"" |
| 686 |
|
| 687 |
eval hint${mangled}="" |
| 688 |
eval suggested${mangled}="" |
| 689 |
fi |
| 690 |
} |
| 691 |
|
| 692 |
#block for /etc/devfs.rules |
| 693 |
{ |
| 694 |
f=/etc/devfs.rules |
| 695 |
mangled=`echo $f | sed 's|[^[:alpha:]]|_|g'` |
| 696 |
|
| 697 |
eval mandatory${mangled}="\"\ |
| 698 |
[system=10] |
| 699 |
add path 'usb/*' mode 0664 group operator |
| 700 |
add path 'cd*' mode 0664 group operator |
| 701 |
add path 'da*' mode 0664 group operator |
| 702 |
add path 'video*' mode 0664 group operator\"" |
| 703 |
|
| 704 |
eval hint${mangled}="" |
| 705 |
eval suggested${mangled}="" |
| 706 |
} |
| 707 |
|
| 708 |
#block for /etc/rc.conf |
| 709 |
{ |
| 710 |
f=/etc/rc.conf |
| 711 |
mangled=`echo $f | sed 's|[^[:alpha:]]|_|g'` |
| 712 |
|
| 713 |
if [ "$flavour_linux" = "false" ]; then |
| 714 |
eval mandatory${mangled}="\"\ |
| 715 |
devfs_system_ruleset=system |
| 716 |
dbus_enable=YES |
| 717 |
hald_enable=YES |
| 718 |
cupsd_enable=YES\"" |
| 719 |
|
| 720 |
eval hint${mangled}="\"\ |
| 721 |
Here's a few more goodies for you to keep in mind for ${f} : |
| 722 |
|
| 723 |
1) For fuse to be able to mount non-native filesystems like ntfs/ext4 |
| 724 |
2) For a decent typing speed on the console |
| 725 |
3) For auto-loading linux.ko\"" |
| 726 |
|
| 727 |
eval suggested${mangled}="\"\ |
| 728 |
fusefs_enable=YES |
| 729 |
keyrate=fast |
| 730 |
linux_enable=YES\"" |
| 731 |
else |
| 732 |
eval mandatory${mangled}="\"\ |
| 733 |
devfs_system_ruleset=system |
| 734 |
dbus_enable=YES |
| 735 |
hald_enable=YES |
| 736 |
linux_enable=YES |
| 737 |
cupsd_enable=YES\"" |
| 738 |
|
| 739 |
eval hint${mangled}="\"\ |
| 740 |
Here's a few more goodies for you to keep in mind for ${f} : |
| 741 |
|
| 742 |
1) For fuse to be able to mount non-native filesystems like ntfs/ext4 |
| 743 |
2) For a decent typing speed on the console\"" |
| 744 |
|
| 745 |
eval suggested${mangled}="\"\ |
| 746 |
fusefs_enable=YES |
| 747 |
keyrate=fast\"" |
| 748 |
fi |
| 749 |
} |
| 750 |
|
| 751 |
#block for /etc/sysctl.conf |
| 752 |
{ |
| 753 |
f=/etc/sysctl.conf |
| 754 |
mangled=`echo $f | sed 's|[^[:alpha:]]|_|g'` |
| 755 |
|
| 756 |
if [ "$flavour_linux" = "false" ]; then |
| 757 |
eval mandatory${mangled}="" |
| 758 |
|
| 759 |
eval hint${mangled}="\"\ |
| 760 |
You might like to keep in mind a few other suggestions for ${f}, all optional. |
| 761 |
1 goodie to let normal users mount disks and 2 Linuxulator goodies :\"" |
| 762 |
|
| 763 |
eval suggested${mangled}="\"\ |
| 764 |
vfs.usermount=1 |
| 765 |
compat.linux.osrelease=2.6.18 |
| 766 |
kern.ipc.shm_allow_removed=1\"" |
| 767 |
else |
| 768 |
eval mandatory${mangled}="\"\ |
| 769 |
compat.linux.osrelease=2.6.18 |
| 770 |
kern.ipc.shm_allow_removed=1\"" |
| 771 |
|
| 772 |
eval hint${mangled}="\"\ |
| 773 |
For $f, keep in mind a tip to let normal users mount disks :\"" |
| 774 |
|
| 775 |
eval suggested${mangled}="\"\ |
| 776 |
vfs.usermount=1\"" |
| 777 |
fi |
| 778 |
} |
| 779 |
|
| 780 |
#block for /boot/loader.conf |
| 781 |
{ |
| 782 |
f=/boot/loader.conf |
| 783 |
mangled=`echo $f | sed 's|[^[:alpha:]]|_|g'` |
| 784 |
|
| 785 |
eval mandatory${mangled}="\"\ |
| 786 |
kern.vty=vt\"" |
| 787 |
|
| 788 |
eval hint${mangled}="" |
| 789 |
eval suggested${mangled}="" |
| 790 |
} |
| 791 |
|
| 792 |
for f in /etc/fstab; do |
| 793 |
echo && echo "Configure $f : (y/n) ?" |
| 794 |
read answer |
| 795 |
|
| 796 |
case "$answer" in |
| 797 |
y|Y) |
| 798 |
mangled=`echo $f | sed 's|[^[:alpha:]]|_|g'` |
| 799 |
eval mandatory='$'mandatory${mangled} |
| 800 |
|
| 801 |
if [ -f $f ]; then |
| 802 |
if [ -n "$mandatory" ]; then |
| 803 |
cp $f $f.bak |
| 804 |
|
| 805 |
maxlines=`echo "$mandatory" | wc -l | sed 's|^[[:space:]]*||'` |
| 806 |
index=1 |
| 807 |
|
| 808 |
while [ $index -le $maxlines ]; do |
| 809 |
line="`echo \"$mandatory\" | sed -n ${index}p`" |
| 810 |
token1=`echo $line | awk '{print $1}'` |
| 811 |
|
| 812 |
if ! cat $f | grep --silent "^$token1[[:space:]]"; then |
| 813 |
echo $line >> $f |
| 814 |
fi |
| 815 |
|
| 816 |
index=`expr $index + 1` |
| 817 |
done |
| 818 |
fi |
| 819 |
else |
| 820 |
echo "$mandatory" > $f |
| 821 |
fi |
| 822 |
|
| 823 |
echo && echo "Done configuring $f" |
| 824 |
eval hint='$'hint${mangled} |
| 825 |
eval suggested='$'suggested${mangled} |
| 826 |
|
| 827 |
if [ -n "$suggested" ]; then |
| 828 |
echo "$hint" |
| 829 |
echo && echo "$suggested" |
| 830 |
fi |
| 831 |
;; |
| 832 |
|
| 833 |
n|N) |
| 834 |
;; |
| 835 |
|
| 836 |
*) |
| 837 |
echo "I do not know what that means : - (" |
| 838 |
echo "Skipping $f" |
| 839 |
;; |
| 840 |
esac |
| 841 |
done |
| 842 |
|
| 843 |
for f in /etc/devfs.conf; do |
| 844 |
echo && echo "Configure $f : (y/n) ?" |
| 845 |
read answer |
| 846 |
|
| 847 |
case "$answer" in |
| 848 |
y|Y) |
| 849 |
mangled=`echo $f | sed 's|[^[:alpha:]]|_|g'` |
| 850 |
eval mandatory='$'mandatory${mangled} |
| 851 |
|
| 852 |
if [ -f $f ]; then |
| 853 |
if [ -n "$mandatory" ]; then |
| 854 |
cp $f $f.bak |
| 855 |
|
| 856 |
maxlines=`echo "$mandatory" | wc -l | sed 's|^[[:space:]]*||'` |
| 857 |
index=1 |
| 858 |
|
| 859 |
while [ $index -le $maxlines ]; do |
| 860 |
line="`echo \"$mandatory\" | sed -n ${index}p`" |
| 861 |
|
| 862 |
if ! cat $f | grep --silent "$line"; then |
| 863 |
token1=`echo $line | awk '{print $1}'` |
| 864 |
token3=`echo $line | awk '{print $3}'` |
| 865 |
|
| 866 |
token2=`echo $line | awk '{print $2}'` |
| 867 |
token2_alt=`echo $token2 | sed -n 's|^/dev/||p'` |
| 868 |
t2_lastchar=`echo $token2 | rev | cut -c1` |
| 869 |
|
| 870 |
search="^${token1}[[:space:]]+${token2}[[:space:]]" |
| 871 |
|
| 872 |
if [ -n "$token2_alt" ]; then |
| 873 |
search="^${token1}[[:space:]]+(${token2}|${token2_alt})[[:space:]]" |
| 874 |
fi |
| 875 |
|
| 876 |
if [ "$t2_lastchar" = "0" ]; then |
| 877 |
lead=`echo $token2 | sed -n 's|^\(.*[^[:digit:]]\)\([[:digit:]]*\)$|\1|p'` |
| 878 |
trail=`echo $token2 | sed -n 's|^\(.*[^[:digit:]]\)\([[:digit:]]*\)$|\2|p'` |
| 879 |
|
| 880 |
while [ -c $token2 ]; do |
| 881 |
if ! cat $f | egrep --silent "$search"; then |
| 882 |
echo $line >> $f |
| 883 |
fi |
| 884 |
|
| 885 |
trail=`expr $trail + 1` |
| 886 |
token2="${lead}${trail}" |
| 887 |
token2_alt=`echo $token2 | sed -n 's|^/dev/||p'` |
| 888 |
line="$token1 $token2 $token3" |
| 889 |
|
| 890 |
search="^${token1}[[:space:]]+${token2}[[:space:]]" |
| 891 |
|
| 892 |
if [ -n "$token2_alt" ]; then |
| 893 |
search="^${token1}[[:space:]]+(${token2}|${token2_alt})[[:space:]]" |
| 894 |
fi |
| 895 |
done |
| 896 |
else |
| 897 |
if [ -c $token2 ]; then |
| 898 |
if ! cat $f | egrep --silent "$search"; then |
| 899 |
echo $line >> $f |
| 900 |
fi |
| 901 |
fi |
| 902 |
fi |
| 903 |
fi |
| 904 |
|
| 905 |
index=`expr $index + 1` |
| 906 |
done |
| 907 |
fi |
| 908 |
else |
| 909 |
echo "$mandatory" > $f |
| 910 |
fi |
| 911 |
|
| 912 |
echo && echo "Done configuring $f" |
| 913 |
eval hint='$'hint${mangled} |
| 914 |
eval suggested='$'suggested${mangled} |
| 915 |
|
| 916 |
if [ -n "$suggested" ]; then |
| 917 |
echo "$hint" |
| 918 |
echo && echo "$suggested" |
| 919 |
fi |
| 920 |
;; |
| 921 |
|
| 922 |
n|N) |
| 923 |
;; |
| 924 |
|
| 925 |
*) |
| 926 |
echo "I do not know what that means : - (" |
| 927 |
echo "Skipping $f" |
| 928 |
;; |
| 929 |
esac |
| 930 |
done |
| 931 |
|
| 932 |
for f in /etc/devfs.rules; do |
| 933 |
echo && echo "Configure $f : (y/n) ?" |
| 934 |
read answer |
| 935 |
|
| 936 |
case "$answer" in |
| 937 |
y|Y) |
| 938 |
mangled=`echo $f | sed 's|[^[:alpha:]]|_|g'` |
| 939 |
eval mandatory='$'mandatory${mangled} |
| 940 |
|
| 941 |
if [ -f $f ]; then |
| 942 |
if [ -n "$mandatory" ]; then |
| 943 |
cp $f $f.bak |
| 944 |
|
| 945 |
line="`echo \"$mandatory\" | sed -n 1p`" |
| 946 |
|
| 947 |
if ! cat $f | grep --silent "$line"; then |
| 948 |
echo "$mandatory" >> $f |
| 949 |
fi |
| 950 |
fi |
| 951 |
else |
| 952 |
echo "$mandatory" > $f |
| 953 |
fi |
| 954 |
|
| 955 |
echo && echo "Done configuring $f" |
| 956 |
eval hint='$'hint${mangled} |
| 957 |
eval suggested='$'suggested${mangled} |
| 958 |
|
| 959 |
if [ -n "$suggested" ]; then |
| 960 |
echo "$hint" |
| 961 |
echo && echo "$suggested" |
| 962 |
fi |
| 963 |
;; |
| 964 |
|
| 965 |
n|N) |
| 966 |
;; |
| 967 |
|
| 968 |
*) |
| 969 |
echo "I do not know what that means : - (" |
| 970 |
echo "Skipping $f" |
| 971 |
;; |
| 972 |
esac |
| 973 |
done |
| 974 |
|
| 975 |
for f in /etc/rc.conf /etc/sysctl.conf /boot/loader.conf; do |
| 976 |
echo && echo "Configure $f : (y/n) ?" |
| 977 |
read answer |
| 978 |
|
| 979 |
case "$answer" in |
| 980 |
y|Y) |
| 981 |
mangled=`echo $f | sed 's|[^[:alpha:]]|_|g'` |
| 982 |
eval mandatory='$'mandatory${mangled} |
| 983 |
|
| 984 |
if [ -f $f ]; then |
| 985 |
if [ -n "$mandatory" ]; then |
| 986 |
cp $f $f.bak |
| 987 |
|
| 988 |
maxlines=`echo "$mandatory" | wc -l | sed 's|^[[:space:]]*||'` |
| 989 |
index=1 |
| 990 |
|
| 991 |
while [ $index -le $maxlines ]; do |
| 992 |
line="`echo \"$mandatory\" | sed -n ${index}p`" |
| 993 |
|
| 994 |
if ! cat $f | grep --silent "$line"; then |
| 995 |
token1=`echo $line | awk -F= '{print $1}'` |
| 996 |
token2=`echo $line | awk -F= '{print $2}'` |
| 997 |
|
| 998 |
search="^${token1}=" |
| 999 |
|
| 1000 |
if ! cat $f | egrep --silent "$search"; then |
| 1001 |
echo $line >> $f |
| 1002 |
fi |
| 1003 |
fi |
| 1004 |
|
| 1005 |
index=`expr $index + 1` |
| 1006 |
done |
| 1007 |
fi |
| 1008 |
else |
| 1009 |
echo "$mandatory" > $f |
| 1010 |
fi |
| 1011 |
|
| 1012 |
echo && echo "Done configuring $f" |
| 1013 |
eval hint='$'hint${mangled} |
| 1014 |
eval suggested='$'suggested${mangled} |
| 1015 |
|
| 1016 |
if [ -n "$suggested" ]; then |
| 1017 |
echo "$hint" |
| 1018 |
echo && echo "$suggested" |
| 1019 |
fi |
| 1020 |
;; |
| 1021 |
|
| 1022 |
n|N) |
| 1023 |
;; |
| 1024 |
|
| 1025 |
*) |
| 1026 |
echo "I do not know what that means : - (" |
| 1027 |
echo "Skipping $f" |
| 1028 |
;; |
| 1029 |
esac |
| 1030 |
done |
| 1031 |
|
| 1032 |
set +e |
| 1033 |
echo |
| 1034 |
|
| 1035 |
cat <<-EOF |
| 1036 |
Post-processing done. |
| 1037 |
If you saw no errors anywhere, your box is raring to go : - ) |
| 1038 |
A reboot is now needed - you will need to do that yourself. |
| 1039 |
|
| 1040 |
Before you reboot, please make a note of one setting that could save you |
| 1041 |
hours of googling and jostling later on. |
| 1042 |
|
| 1043 |
If you plug in a USB device, it usually will be visible to every user |
| 1044 |
out-of-the-box. But sometimes, it may happen that only the root user is able |
| 1045 |
to see the device (most commonly happens with printer/scanner). |
| 1046 |
|
| 1047 |
If that happens, run usbconfig as root to ensure that the device is showing |
| 1048 |
up in the output, and make a note of its ugen ID, with <x>.<y> translating |
| 1049 |
as <x>.<y>.0 (for example, ugen2.4 would correspond to the ugen ID 2.4.0) |
| 1050 |
|
| 1051 |
Then run usbconfig again, this time as the normal user. If the ugen ID is |
| 1052 |
missing, add a line to /etc/devfs.conf (as root, of course) : |
| 1053 |
|
| 1054 |
perm usb/<ugen_ID> 0664 |
| 1055 |
|
| 1056 |
For our example, that would mean : |
| 1057 |
|
| 1058 |
perm usb/2.4.0 0664 |
| 1059 |
|
| 1060 |
Then, as root, run '/etc/rc.d/devfs restart'. |
| 1061 |
Your device should now work cleanly for the normal user too. |
| 1062 |
EOF |
| 1063 |
} |
| 1064 |
|
| 1065 |
if [ -n "$idents" ]; then |
| 1066 |
if [ "$mode_echo" = "false" -a "$mode_dry" = "false" ]; then |
| 1067 |
clear && echo "Here is a preview of what I shall be doing" |
| 1068 |
echo |
| 1069 |
echo -e "(\e[4mstage name\e[0m :: package list as per stage definition)" |
| 1070 |
echo |
| 1071 |
echo "<<<<----" |
| 1072 |
echo |
| 1073 |
|
| 1074 |
readonly my_mode_echo=$mode_echo |
| 1075 |
mode_echo=true |
| 1076 |
previous_level=0 |
| 1077 |
|
| 1078 |
for var in $idents; do |
| 1079 |
eval level='$'$var |
| 1080 |
|
| 1081 |
[ -z "$level" ] && \ |
| 1082 |
die "$LINENO" "level must not evaluate as an empty string" |
| 1083 |
|
| 1084 |
echo "$level" | grep '[^[:digit:]]' > /dev/null && \ |
| 1085 |
die "$LINENO" "level must be numeric" |
| 1086 |
|
| 1087 |
if [ $level -le $previous_level ]; then |
| 1088 |
die "$LINENO" \ |
| 1089 |
"This level is ${level}; Previous was ${previous_level} |
| 1090 |
Random/descending order of stages is not supported" |
| 1091 |
fi |
| 1092 |
|
| 1093 |
[ $begin -gt $level ] || f_stage $var |
| 1094 |
|
| 1095 |
[ $? -eq 0 ] && \ |
| 1096 |
previous_level=$level || \ |
| 1097 |
die "$LINENO" "stage failure for stage $var" |
| 1098 |
|
| 1099 |
[ $end -eq $level ] && { break; } |
| 1100 |
done |
| 1101 |
|
| 1102 |
echo |
| 1103 |
echo "---->>>>" |
| 1104 |
echo |
| 1105 |
|
| 1106 |
mode_echo=$my_mode_echo |
| 1107 |
b_valid=false |
| 1108 |
|
| 1109 |
while [ "$b_valid" = "false" ]; do |
| 1110 |
cat <<-EOF |
| 1111 |
If you like the preview of what is to be done, give me a : |
| 1112 |
|
| 1113 |
y) Install the stages |
| 1114 |
|
| 1115 |
Y) Install stages non-interactively : passes --yes to 'pkg install' |
| 1116 |
(If you enter Y, just wait a few minutes/hours, and your entire |
| 1117 |
desktop will get assembled nicely and I shall bother you only for |
| 1118 |
the post-processing when the desktop has been put together) |
| 1119 |
|
| 1120 |
If you would like to modify the installation, press Control-C to |
| 1121 |
abort and alter the stage-definitions file and/or package list files |
| 1122 |
|
| 1123 |
Your choice ? (y/Y) : |
| 1124 |
EOF |
| 1125 |
|
| 1126 |
read answer |
| 1127 |
|
| 1128 |
case "$answer" in |
| 1129 |
y) |
| 1130 |
b_valid=true |
| 1131 |
;; |
| 1132 |
|
| 1133 |
Y) |
| 1134 |
b_valid=true |
| 1135 |
mode_yes=true |
| 1136 |
;; |
| 1137 |
|
| 1138 |
*) |
| 1139 |
echo "I do not know what to make of that : - (" 1>&2 |
| 1140 |
;; |
| 1141 |
esac |
| 1142 |
done |
| 1143 |
fi |
| 1144 |
|
| 1145 |
previous_level=0 |
| 1146 |
|
| 1147 |
for var in $idents; do |
| 1148 |
eval level='$'$var |
| 1149 |
|
| 1150 |
[ -z "$level" ] && \ |
| 1151 |
die "$LINENO" "level must not evaluate as an empty string" |
| 1152 |
|
| 1153 |
echo "$level" | grep '[^[:digit:]]' > /dev/null && \ |
| 1154 |
die "$LINENO" "level must be numeric" |
| 1155 |
|
| 1156 |
if [ $level -le $previous_level ]; then |
| 1157 |
die "$LINENO" \ |
| 1158 |
"This level is ${level}; Previous was ${previous_level} |
| 1159 |
Random/descending order of stages is not supported" |
| 1160 |
fi |
| 1161 |
|
| 1162 |
[ $begin -gt $level ] || f_stage $var |
| 1163 |
|
| 1164 |
[ $? -eq 0 ] && \ |
| 1165 |
previous_level=$level || \ |
| 1166 |
die "$LINENO" "stage failure for stage $var" |
| 1167 |
|
| 1168 |
if [ $end -eq $level ]; then |
| 1169 |
[ "$arg_end" = "true" ] && exit 0 || break |
| 1170 |
fi |
| 1171 |
done |
| 1172 |
|
| 1173 |
postproc |
| 1174 |
fi |
| 1175 |
|
| 1176 |
exit $? |