source: src-sh/libsh/functions.sh @ 8afc51a

9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3releng/10.1
Last change on this file since 8afc51a was 8afc51a, checked in by Kris Moore <kris@…>, 14 months ago

Fix a bug with getZFSRelativePath, make sure we have a '/' at the start
of the pathname

  • Property mode set to 100755
File size: 16.5 KB
Line 
1#!/bin/sh
2# Functions we can source for pc-bsd scripts
3# Author: Kris Moore
4# Copyright: 2012
5# License: BSD
6##############################################################
7
8PCBSD_ETCCONF="/usr/local/etc/pcbsd.conf"
9
10download_cache_packages()
11{
12  if [ ! -e "/usr/local/etc/pkg.conf" ] ; then
13    exit_err "No /usr/local/etc/pkg.conf!"
14  fi
15
16  # Tickle pkg update first
17  pkg-static update
18  local ARCH="`uname -m`"
19
20  ${1} > /tmp/.pkgUpList.$$
21
22  while read line
23  do
24     lTag=`echo $line | awk '{print $1}'` 
25     case $lTag in
26    Upgrading|Downgrading) pkgList="`echo $line | awk '{print $2}' | sed 's|:||g'`-`echo $line | awk '{print $5}'`.txz $pkgList" ;;
27 Reinstalling) pkgList="`echo $line | awk '{print $2}'`.txz $pkgList" ;;
28   Installing) pkgList="`echo $line | awk '{print $2}' | sed 's|:||g'`-`echo $line | awk '{print $3}'`.txz $pkgList" ;;
29                    *) continue ;;
30     esac
31
32  done < /tmp/.pkgUpList.$$
33  rm /tmp/.pkgUpList.$$
34
35  # Get the PKG_CACHEDIR
36  PKG_CACHEDIR="/var/cache/pkg"
37  cat /usr/local/etc/pkg.conf | grep -q "^PKG_CACHEDIR:"
38  if [ $? -eq 0 ] ; then
39    PKG_CACHEDIR="`grep '^PKG_CACHEDIR:' /usr/local/etc/pkg.conf | awk '{print $2}'`"
40  fi
41  if [ -z "$PKG_CACHEDIR" ] ; then
42     exit_err "Failed getting PKG_CACHEDIR"
43  fi
44  export PKG_CACHEDIR
45
46  # Where are the packages on our mirrors?
47  cat /usr/local/etc/pkg.conf | grep -q "^packagesite:"
48  if [ $? -ne 0 ] ; then
49     exit_err "Failed getting packagesite:"
50  fi
51  pkgUrl="`grep '^packagesite:' /usr/local/etc/pkg.conf | awk '{print $2}'`"
52
53  if [ ! -d "$PKG_CACHEDIR/All" ] ; then
54     mkdir -p ${PKG_CACHEDIR}/All
55  fi
56
57  for i in $pkgList
58  do
59    # Does the package already exist?
60    if [ -e "${PKG_CACHEDIR}/All/${i}" ] ; then 
61        # Once bapt gives us a working rquery string, we can add a check here to skip
62        # re-downloading already valid files
63        #pName=`echo $i | sed 's|.txz$||g'`
64        # Check the sizes
65        #eSize=`pkg rquery "%sb" $pName`
66        #dSize=`ls -al `
67        #rm ${PKG_CACHEDIR}/All/${i} ;
68    fi
69    get_file "${pkgUrl}/All/${i}" "${PKG_CACHEDIR}/All/${i}"
70    if [ $? -ne 0 ] ; then
71      echo "Failed downloading: ${pkgUrl}/All/${i}"
72      return 1
73    fi
74  done
75  return 0
76}
77
78get_mirror() {
79
80  # Check if we already looked up a mirror we can keep using
81  if [ -n "$CACHED_PCBSD_MIRROR" ] ; then
82     VAL="$CACHED_PCBSD_MIRROR"
83     export VAL
84     return
85  fi
86
87  # Set the mirror URL
88  VAL="`cat ${PCBSD_ETCCONF} 2>/dev/null | grep 'PCBSD_MIRROR: ' | sed 's|PCBSD_MIRROR: ||g'`"
89  if [ -n "$VAL" ] ; then
90     echo "Using mirror: $VAL"
91     CACHED_PCBSD_MIRROR="$VAL"
92     export VAL CACHED_PCBSD_MIRROR
93     return
94  fi
95
96  echo "Getting regional mirror..."
97  . /etc/profile
98
99  # No URL? Lets get one from the master server
100  local mFile="${HOME}/.mirrorUrl.$$"
101  touch $mFile
102  fetch -o $mFile http://getmirror.pcbsd.org >/dev/null 2>/dev/null
103  VAL="`cat $mFile | grep 'URL: ' | sed 's|URL: ||g'`"
104  rm $mFile
105  if [ -n "$VAL" ] ; then
106     echo "Using mirror: $VAL"
107     CACHED_PCBSD_MIRROR="$VAL"
108     export VAL CACHED_PCBSD_MIRROR
109     return
110  fi
111
112  # Still no mirror? Lets try the PC-BSD FTP server...
113  VAL="ftp://ftp.pcbsd.org/pub/mirror"
114  CACHED_PCBSD_MIRROR="$VAL"
115  export VAL CACHED_PCBSD_MIRROR
116  echo "Using mirror: $VAL"
117  return 
118}
119
120# Function which returns the installed list of PC-BSD mirrors for use
121# with the fetch command
122# Will return just a single mirror, if the user has manually specified one
123# in /usr/local/etc/pcbsd.conf
124get_mirror_loc()
125{
126  if [ -z $1 ] ; then
127     exit_err "Need to supply file to grab from mirrors..."
128  fi
129  if [ -z $2 ] ; then
130     exit_err "Need to supply which mirror to fetch from..."
131  fi
132
133  case $2 in
134    pkg) mirrorTag="PKG_MIRROR" 
135         mirrorFile="/usr/local/share/pcbsd/conf/pkg-mirror"
136         ;;
137    pbi) mirrorTag="PBI_MIRROR" 
138         mirrorFile="/usr/local/share/pcbsd/conf/pbi-mirror"
139         ;;
140    iso) mirrorTag="ISO_MIRROR" 
141         mirrorFile="/usr/local/share/pcbsd/conf/iso-mirror"
142         ;;
143  update) mirrorTag="UPDATE_MIRROR" 
144         mirrorFile="/usr/local/share/pcbsd/conf/update-mirror"
145         ;;
146    *) exit_err "Bad mirror type!" ;;
147  esac
148
149  # Set the mirror URL
150  local VAL=`cat ${PCBSD_ETCCONF} 2>/dev/null | grep "^${mirrorTag}:" | sed "s|^${mirrorTag}: ||g"`
151  if [ -n "$VAL" ] ; then
152     echo "${VAL}${1}"
153     return
154  fi
155
156  if [ ! -e "${mirrorFile}" ] ; then
157     exit_err "Missing mirror list: ${mirrorFile}"
158  fi
159
160  # Build the mirror list
161  while read line
162  do
163    VAL="${line}${1}"
164    break
165  done < ${mirrorFile}
166  echo ${VAL}
167}
168
169# Function to download a file from the pcbsd mirrors
170# Arg1 = Remote File URL
171# Arg2 = Where to save file
172get_file_from_mirrors()
173{
174   _rf="${1}"
175   _lf="${2}"
176   _mtype="${3}"
177
178   case $_mtype in
179      iso|pbi|pkg|update) ;;
180      *) exit_err "Fixme! Missing mirror type in get_file_from_mirrors" ;;
181   esac
182
183   # Get any proxy information
184   . /etc/profile
185
186   # Get mirror list
187   local mirrorLoc="$(get_mirror_loc ${_rf} ${_mtype})"
188   mirrorLoc="`echo $mirrorLoc | awk '{print $1}'`"
189
190   # Running from a non GUI?
191   if [ "$GUI_FETCH_PARSING" != "YES" -a "$PBI_FETCH_PARSING" != "YES" -a -z "$PCFETCHGUI" ] ; then
192      fetch -o "${_lf}" ${mirrorLoc}
193      return $?
194   fi
195
196   echo "FETCH: ${_rf}"
197
198   # Doing a front-end download, parse the output of fetch
199   _eFile="/tmp/.fetch-exit.$$"
200   fetch -s ${mirrorLoc} > /tmp/.fetch-size.$$ 2>/dev/null
201   _fSize=`cat /tmp/.fetch-size.$$ 2>/dev/null`
202   _fSize="`expr ${_fSize} / 1024 2>/dev/null`"
203   rm "/tmp/.fetch-size.$$" 2>/dev/null
204   _time=1
205   if [ -z "$_fSize" ] ; then _fSize=0; fi
206
207   ( fetch -o ${_lf} ${mirrorLoc} >/dev/null 2>/dev/null ; echo "$?" > ${_eFile} ) &
208   FETCH_PID=$!
209   while :
210   do
211      if [ -e "${_lf}" ] ; then
212         sync
213         _dSize=`du -k ${_lf} | tr -d '\t' | cut -d '/' -f 1`
214         if [ $(is_num "$_dSize") ] ; then
215            if [ ${_fSize} -lt ${_dSize} ] ; then _dSize="$_fSize" ; fi
216            _kbs=`expr ${_dSize} \/ $_time`
217            echo "SIZE: ${_fSize} DOWNLOADED: ${_dSize} SPEED: ${_kbs} KB/s"
218         fi
219      fi
220
221      # Make sure download isn't finished
222      jobs -l >/tmp/.jobProcess.$$
223      cat /tmp/.jobProcess.$$ | awk '{print $3}' | grep -q ${FETCH_PID}
224      if [ "$?" != "0" ] ; then rm /tmp/.jobProcess.$$ ; break ; fi
225      sleep 1
226      _time=`expr $_time + 1`
227   done
228
229   _err="`cat ${_eFile} 2>/dev/null`"
230   if [ -z "$_err" ] ; then _err="0"; fi
231   rm ${_eFile} 2>/dev/null
232   if [ "$_err" = "0" ]; then echo "FETCHDONE" ; fi
233   unset FETCH_PID
234   return $_err
235
236}
237
238# Function to download a file from remote using fetch
239# Arg1 = Remote File URL
240# Arg2 = Where to save file
241# Arg3 = Number of attempts to make before failing
242get_file() {
243
244        _rf="${1}"
245        _lf="${2}"
246        _ftries=${3}
247        if [ -z "$_ftries" ] ; then _ftries=3; fi
248
249        # Get any proxy information
250        . /etc/profile
251
252        if [ -e "${_lf}" ] ; then
253                echo "Resuming download of: ${_lf}"
254        fi
255
256        if [ "$GUI_FETCH_PARSING" != "YES" -a -z "$PCFETCHGUI" ] ; then
257                fetch -r -o "${_lf}" "${_rf}"
258                _err=$?
259        else
260                echo "FETCH: ${_rf}"
261
262                # Doing a front-end download, parse the output of fetch
263                _eFile="/tmp/.fetch-exit.$$"
264                fetch -s "${_rf}" > /tmp/.fetch-size.$$ 2>/dev/null
265                _fSize=`cat /tmp/.fetch-size.$$ 2>/dev/null`
266                _fSize="`expr ${_fSize} / 1024 2>/dev/null`"
267                rm "/tmp/.fetch-size.$$" 2>/dev/null
268                _time=1
269                if [ -z "$_fSize" ] ; then _fSize=0; fi
270
271                ( fetch -r -o "${_lf}" "${_rf}" >/dev/null 2>/dev/null ; echo "$?" > ${_eFile} ) &
272                FETCH_PID=`ps -auwwwx | grep -v grep | grep "fetch -r -o ${_lf}" | awk '{print $2}'`
273                while :
274                do
275                        if [ -e "${_lf}" ] ; then
276                                _dSize=`du -k ${_lf} | tr -d '\t' | cut -d '/' -f 1`
277                                if [ $(is_num "$_dSize") ] ; then
278                                        if [ ${_fSize} -lt ${_dSize} ] ; then _dSize="$_fSize" ; fi
279                                        _kbs=`expr ${_dSize} \/ $_time`
280                                        echo "SIZE: ${_fSize} DOWNLOADED: ${_dSize} SPEED: ${_kbs} KB/s"
281                                fi
282                        fi
283
284                        # Make sure download isn't finished
285                        ps -p $FETCH_PID >/dev/null 2>/dev/null
286                        if [ "$?" != "0" ] ; then break ; fi
287                        sleep 2
288                        _time=`expr $_time + 2`
289                done
290
291                _err="`cat ${_eFile} 2>/dev/null`"
292                if [ -z "$_err" ] ; then _err="0"; fi
293                rm ${_eFile} 2>/dev/null
294                if [ "$_err" = "0" ]; then echo "FETCHDONE" ; fi
295                unset FETCH_PID
296        fi
297
298        echo ""
299        if [ $_err -ne 0 -a $_ftries -gt 0 ] ; then
300                sleep 30
301                _ftries=`expr $_ftries - 1`
302
303                # Remove the local file if we failed
304                if [ -e "${_lf}" ]; then rm "${_lf}"; fi
305
306                get_file "${_rf}" "${_lf}" $_ftries     
307                _err=$?
308        fi
309        return $_err
310}
311
312# Check if a value is a number
313is_num()
314{
315        expr $1 + 1 2>/dev/null
316        return $?
317}
318
319# Exit with a error message
320exit_err() {
321        if [ -n "${LOGFILE}" ] ; then
322           echo "ERROR: $*" >> ${LOGFILE}
323        fi
324        echo >&2 "ERROR: $*"
325        exit 1
326}
327
328
329### Print an error on STDERR and bail out
330printerror() {
331  exit_err $*
332}
333
334
335# Check if the target directory is on ZFS
336# Arg1 = The dir to check
337# Arg2 = If set to 1, don't dig down to lower level directory
338isDirZFS() {
339  local _chkDir="$1"
340  while :
341  do
342     # Is this dir a ZFS mount
343     mount | grep -w "on $_chkDir " | grep -qw "(zfs," && return 0
344
345     # If this directory is mounted, but NOT ZFS
346     if [ "$2" != "1" ] ; then
347       mount | grep -qw "on $_chkDir " && return 1
348     fi
349     
350     # Quit if not walking down
351     if [ "$2" = "1" ] ; then return 1 ; fi
352 
353     if [ "$_chkDir" = "/" ] ; then break ; fi
354     _chkDir=`dirname $_chkDir`
355  done
356 
357  return 1
358}
359
360# Gets the mount-point of a particular zpool / dataset
361# Arg1 = zpool to check
362getZFSMount() {
363  local zpool="$1"
364  local mnt=`mount | grep "^${zpool} on" | grep "(zfs," | awk '{print $3}'`
365  if [ -n "$mnt" ] ; then
366     echo "$mnt"
367     return 0
368  fi
369  return 1
370}
371
372# Get the ZFS dataset of a particular directory
373getZFSDataset() {
374  local _chkDir="$1"
375  while :
376  do
377    local zData=`mount | grep " on ${_chkDir} " | grep "(zfs," | awk '{print $1}'`
378    if [ -n "$zData" ] ; then
379       echo "$zData"
380       return 0
381    fi
382    if [ "$2" != "rec" ] ; then return 1 ; fi
383    if [ "$_chkDir" = "/" ] ; then return 1 ; fi
384    _chkDir=`dirname $_chkDir`
385  done
386  return 1
387}
388
389# Get the ZFS tank name for a directory
390# Arg1 = Directory to check
391getZFSTank() {
392  local _chkDir="$1"
393
394  _chkdir=${_chkDir%/}
395  while :
396  do
397     zpath=`zfs list | awk -v path="${_chkDir}" '$5 == path { print $1 }'`
398     if [ -n "${zpath}" ] ; then
399        echo $zpath | cut -f1 -d '/'
400        return 0
401     fi
402
403     if [ "$_chkDir" = "/" ] ; then return 1 ; fi
404     _chkDir=`dirname $_chkDir`
405  done
406
407  return 1
408}
409
410# Get the mountpoint for a ZFS name
411# Arg1 = name
412getZFSMountpoint() {
413   local _chkName="${1}"
414   if [ -z "${_chkName}" ]; then return 1 ; fi
415
416   zfs list "${_chkName}" | tail -1 | awk '{ print $5 }'
417}
418
419# Get the ZFS relative path for a path
420# Arg1 = Path
421getZFSRelativePath() {
422   local _chkDir="${1}"
423   local _tank=`getZFSTank "$_chkDir"`
424   local _mp=`getZFSMountpoint "${_tank}"`
425
426   if [ -z "${_tank}" ] ; then return 1 ; fi
427
428   local _name="${_chkDir#${_mp}}"
429
430   # Make sure we have a '/' at the start of dataset
431   if [ "`echo ${_name} | cut -c 1`" != "/" ] ; then _name="/${_name}"; fi
432
433   echo "${_name}"
434   return 0
435}
436
437# Check if an address is IPv6
438isV6() {
439  echo ${1} | grep -q ":"
440  return $?
441}
442   
443# Is a mount point, or any of its parent directories, a symlink?
444is_symlinked_mountpoint()
445{
446        local _dir
447        _dir=$1
448        [ -L "$_dir" ] && return 0
449        [ "$_dir" = "/" ] && return 1
450        is_symlinked_mountpoint `dirname $_dir`
451        return $?
452}
453
454# Function to ask the user to press Return to continue
455rtn()
456{
457  echo -e "Press ENTER to continue\c";
458  read garbage
459};
460
461# Function to check if an IP address passes a basic sanity test
462check_ip()
463{
464  ip="$1"
465 
466  # If this is a V6 address, skip validation for now
467  isV6 "${ip}"
468  if [ $? -eq 0 ] ; then return ; fi
469
470  # Check if we can cut this IP into the right segments
471  SEG="`echo $ip | cut -d '.' -f 1 2>/dev/null`"
472  echo $SEG | grep -E "^[0-9]+$" >/dev/null 2>/dev/null
473  if [ "$?" != "0" ]
474  then
475     return 1
476  fi
477  if [ $SEG -gt 255 -o $SEG -lt 0 ]
478  then
479     return 1
480  fi
481 
482  # Second segment
483  SEG="`echo $ip | cut -d '.' -f 2 2>/dev/null`"
484  echo $SEG | grep -E "^[0-9]+$" >/dev/null 2>/dev/null
485  if [ "$?" != "0" ]
486  then
487     return 1
488  fi
489  if [ $SEG -gt 255 -o $SEG -lt 0 ]
490  then
491     return 1
492  fi
493
494  # Third segment
495  SEG="`echo $ip | cut -d '.' -f 3 2>/dev/null`"
496  echo $SEG | grep -E "^[0-9]+$" >/dev/null 2>/dev/null
497  if [ "$?" != "0" ]
498  then
499     return 1
500  fi
501  if [ $SEG -gt 255 -o $SEG -lt 0 ]
502  then
503     return 1
504  fi
505 
506  # Fourth segment
507  SEG="`echo $ip | cut -d '.' -f 4 2>/dev/null`"
508  echo $SEG | grep -E "^[0-9]+$" >/dev/null 2>/dev/null
509  if [ "$?" != "0" ]
510  then
511     return 1
512  fi
513  if [ $SEG -gt 255 -o $SEG -lt 0 ]
514  then
515     return 1
516  fi
517
518  return 0
519};
520
521check_pkg_conflicts()
522{
523  # Lets test if we have any conflicts
524  pkg-static ${1} 2>/tmp/.pkgConflicts.$$ >/tmp/.pkgConflicts.$$
525  if [ $? -eq 0 ] ; then rm /tmp/.pkgConflicts.$$ ; return ; fi
526 
527  # Found conflicts, suprise suprise, yet another reason I hate packages
528  # Lets start building a list of the old packages we can prompt to remove
529
530  # Nice ugly sed line, sure this can be neater
531  cat /tmp/.pkgConflicts.$$ | grep 'WARNING: locally installed' \
532        | sed 's|.*installed ||g' | sed 's| conflicts.*||g' | sort | uniq \
533        > /tmp/.pkgConflicts.$$.2
534  while read line
535  do
536    cList="$line $cList"
537  done < /tmp/.pkgConflicts.$$.2
538  rm /tmp/.pkgConflicts.$$.2
539  rm /tmp/.pkgConflicts.$$
540
541  if [ "$GUI_FETCH_PARSING" != "YES" -a "$PBI_FETCH_PARSING" != "YES" -a -z "$PCFETCHGUI" ] ; then
542        echo "The following packages will conflict with your pkg command:"
543        echo "-------------------------------------"
544        echo "$cList" | more
545        echo "Do you wish to remove them automatically?"
546        echo -e "Default yes: (y/n)\c"
547        read tmp
548        if [ "$tmp" != "y" -a "$tmp" != "Y" -a -n "$tmp" ] ; then return 1 ; fi
549  else
550        echo "PKGCONFLICTS: $cList"
551        echo "PKGREPLY: /tmp/pkgans.$$"
552        while :
553        do
554          if [ -e "/tmp/pkgans.$$" ] ; then
555            ans=`cat /tmp/pkgans.$$`
556            if [ "$ans" = "yes" ] ; then
557               break
558            else
559               return 1
560            fi
561          fi
562          sleep 3
563        done
564  fi
565
566  # Lets auto-resolve these bad-boys
567  # Right now the logic is pretty simple, you conflict, you die
568  for bPkg in $cList
569  do
570     # Nuked!
571     echo "Removing conflicting package: $bPkg"
572     pkg delete -q -y -f ${bPkg}
573  done
574
575  # Lets test if we still have any conflicts
576  pkg-static ${1} 2>/dev/null >/dev/null
577  if [ $? -eq 0 ] ; then return 0; fi
578
579  # Crapola, we still have conflicts, lets warn and bail
580  echo "ERROR: pkg ${1} is still reporting conflicts... Resolve these manually and try again"
581  return 1
582}
583
584# Run the first boot wizard
585# Should be called from a .xinitrc script, after fluxbox is already running
586run_firstboot()
587{
588  # Is the trigger file set?
589  if [ ! -e "/var/.pcbsd-firstgui" ] ; then return; fi
590
591  # Set all our path variables
592  PATH="/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/bin:/usr/local/sbin"
593  HOME="/root"
594  export PATH HOME
595
596  # Unset the PROGDIR variable
597  PROGDIR=""
598  export PROGDIR
599
600  if [ -e "/root/.xprofile" ] ; then . /root/.xprofile ; fi
601
602  # Figure out which intro video to play
603  res=`xdpyinfo | grep dimensions: | awk "{print $2}"`
604  h=`echo $res | cut -d "x" -f 1`
605  w=`echo $res | cut -d "x" -f 2`
606  h=`expr 100 \* $h`
607  ratio=`expr $h \/ $w | cut -c 1-2`
608  case $ratio in
609    13) mov="PCBSD9_4-3_UXGA.flv";;
610    16) mov="PCBSD9_16-10_WUXGA.flv";;
611    17) mov="PCBSD9_16-9_1080p.flv";;
612     *) mov="PCBSD9_4-3_UXGA.flv";;
613  esac
614
615  # Play the video now
616  # NO Movie for 10, if we end up with one, replace this
617  #mplayer -fs -nomouseinput -zoom /usr/local/share/pcbsd/movies/$mov
618
619  # Setting a language
620  if [ -e "/etc/pcbsd-lang" ] ; then
621    LANG=`cat /etc/pcbsd-lang`
622    export LANG
623  fi
624
625  # Start first-boot wizard
626  /usr/local/bin/pc-firstboot >/var/log/pc-firstbootwiz 2>/var/log/pc-firstbootwiz
627  if [ $? -eq 0 ] ; then
628    rm /var/.pcbsd-firstgui
629  fi
630}
631
632# Run-command, don't halt if command exits with non-0
633rc_nohalt()
634{
635  CMD="$1"
636
637  if [ -z "${CMD}" ] ; then
638    exit_err "Error: missing argument in rc_nohalt()"
639  fi
640
641  ${CMD}
642}
643
644# Run-command, halt if command exits with non-0
645rc_halt()
646{
647  CMD="$@"
648
649  if [ -z "${CMD}" ] ; then
650    exit_err "Error: missing argument in rc_halt()"
651  fi
652
653  ${CMD}
654  STATUS=$?
655  if [ ${STATUS} -ne 0 ] ; then
656    exit_err "Error ${STATUS}: ${CMD}"
657  fi
658}
659
660# Run-command silently, only display / halt if command exits with non-0
661rc_halt_s()
662{
663  CMD="$@"
664
665  if [ -z "${CMD}" ] ; then
666    exit_err "Error: missing argument in rc_halt()"
667  fi
668
669  TMPRCLOG=`mktemp /tmp/.rc_halt.XXXXXX`
670  ${CMD} >${TMPRCLOG} 2>${TMPRCLOG}
671  STATUS=$?
672  if [ ${STATUS} -ne 0 ] ; then
673    cat ${TMPRCLOG}
674    rm ${TMPRCLOG}
675    exit_err "Error ${STATUS}: ${CMD}"
676  fi
677  rm ${TMPRCLOG}
678}
Note: See TracBrowser for help on using the repository browser.