More 2 Cent Tips & Tricks Issue 16

#### "Linux Gazette...making Linux just a little more fun! "

# More 2¢ Tips!

Send Linux Tips and Tricks to gazette@ssc.com

### Contents:

- How to ftp Back Home
- Checking if You're Boot
- XV vs Xli
- Bash Shell Scripting
  - Bash Shell Script 1
  - Bash Shell Script 2
  - Bash Shell Script 3

### How to ftp Back Home

Date:Sat Mar 30 14:23:24 (PST)
From:Phil Hughesfyl@ssc.com

Many businesses place a firewall between the Internet and the inside systems. This is good protection and it just makes good sense. One common firewalling technique is to serverly restrict access through the firewall from the outside but allow a user on the inside to do most anything through the firewall to the outside.

When I am at home, I routinely need to move files between home and work. But, because of the firewall, I can ftp from work to home but not the other way around. What this means is that I need to establish an interactive connection (using ssh) from home to work and then initiate the ftp from work to home.

So far, so good. But, what I call "home" consists of various locations, all connected with a dial-up connection through one of four ISPs. All four ISPs use dynamic IP addresses meaning that each time I connect I have a different IP address for my home system. Even though the ISP knows what the current IP address for my system, the name server at work doesn't.

The solution is to enter the IP address of my home system into the ftp command at work. First, I need to find out what the IP address is. To do that, I execute the ifconfig command on my home system:

    $ /sbin/ifconfig

    lo        Link encap:Local Loopback
              inet addr:127.0.0.1  Bcast:127.255.255.255  Mask:255.0.0.0
              UP BROADCAST LOOPBACK RUNNING  MTU:2000  Metric:1
              RX packets:19 errors:0 dropped:0 overruns:0
              TX packets:19 errors:0 dropped:0 overruns:0

    eth0      Link encap:10Mbps Ethernet  HWaddr 02:60:8C:8F:A2:08
              inet addr:198.186.207.131  Bcast:198.186.207.255  Mask:255.255.255.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:969719 errors:0 dropped:0 overruns:0
              TX packets:971132 errors:0 dropped:0 overruns:0
              Interrupt:9 Base address:0x280 Memory:d8000-da000

    ppp0      Link encap:Point-Point Protocol
              inet addr:206.125.79.118  P-t-P:204.157.220.30  Mask:255.255.255.0
              UP POINTOPOINT RUNNING  MTU:296  Metric:1
              RX packets:5434 errors:0 dropped:0 overruns:0
              TX packets:5545 errors:0 dropped:0 overruns:0
    $

The inet addr for the ppp0 interface (206.125.79.118) is the number I need. Now, on my system at work I enter:

    $ ftp 206.125.79.118

ftp then prompts for a login and password. I enter my standard login and password for my home system and ftp is up and running.

### Checking if You're Root

Date: Sun Mar 23 23:20:51 1997 (PST)
From: Kevin Lyda kevin@faxint.com

In the march gazette raul miller suggested that the most portable way to test if you're root is [ -w / ]. that won't work if you're root file system is read only. [ -w /var ] might be a better method.

kevin

### XV vs Xli

Date:Wed Mar 5 16:32:49 1997(PST)
From:Michael Hammel, mjhammel@emass.com

I wasn't aware of Xli (rather, I haven't looked at it), however your statement that xv can only tile image on the background. xv allows qutie a bit of command line control. I use the following to put up a background image at work (non-tiled, takes up the whole background):

    xv -root -max -quit /export/home/mjhammel/lib/images/emass3.tga

The initial image is 601x339, with a root display of 1152x900. Since the original image is 24bpp the enlargement is very accurate in details.

Michael J. Hammel

### Bash Shell Scripting

Date:Thu Mar 20 12:22;34 1997(PST)
From:Paul Sephton paul@inet.co.ca

I have been enjoying the fruits of the Linux Gazette for a number of years now. Recently, I had one of my users accidentally type rm *>bak, and immediately noticed something was amiss by the incoherent screams eminating from her office.

In an attempt to ensure this would not have the same disasterous effect again, and to protect my eardrums in future, I spent a couple of days excersising my bash shell scripting skills, and came up with what I believe to be a decent mechanism for maintaining versioned backups.

My attitude with regard to the normal cludges like aliasing rm and so on, is that it will not protect you against other programs which unlink files. (To date I have yet to write a C program that shells rm in order to unlink a file :)

Whilst writing the set of three scripts, it dawned on me that although some more complex tools do exist which perform the same sort of function, the Linux community might be interested in what I did.

Although it's not much more than a creative excersise in the use of the 'find' command, and suffers from the usual limitation of being restricted to the one file system, I include the three scripts for your perusal and possible inclusion in the gazette at your discretion.

Don't hesitate to contact me if you need more information.

Kind regards, and many thanks for the gazette.
Paul Sephton

### Bash Shell Script 1

    #!/bin/sh
    if [ -z "$SAFEDEL" ];then
    SAFEDEL=/u/safedel
    fi

    NDAYS=5                        #Erase files after 2 days
    MAXVER=6                       # Start Overwriting versins at this count
    BINDIR=$SAFEDEL/bin            # Binaries directory
    DATADIR=$SAFEDEL/data          # Where links are to go
    LOGFILE=$BINDIR/safedel.log    # Output messages go here
    ERRLOG=$BINDIR/safedel.err     # Error output messages go here
    DIRLIST=$BINDIR/safedel.dirs   # List of directories found here
    LOCKFILE=$BINDIR/safedel.lock  # Lockfile to prevent re-entry

    #  Process the file $1 by creating a symbolic link in the data directory
    #  and an entry for the file in the index.
    process-file()
    {
    SRC=`dirname $1`
    FNAME=`basename $1`
    VERSION=0
    if [ ! -d $DATADIR$SRC ]; then
    mkdir -p $DATADIR$SRC
    #  OWNER=`find -name $SRC -printf "%u"`
    #  chown $OWNER $FNAME:$VERSION
    fi
      cd $DATADIR$SRC
      while [ -f $FNAME:$VERSION ]; do
      VERSION=$[ $VERSION + 1 ]
      done
      if ! ln $1 $FNAME:$VERSION 2>> $LOGFILE; then
    echo "Could not link file $FNAME:$VERSION" >> $LOGFILE
        return
    fi
    echo -e "Linked $FNAME:$VERSION \t \tin $SRC" >> $LOGFILE
    return
    }

     # Erase a file
    erase-file()
    {
      echo "Unlinking $1 $2" >> $LOGFILE
      rm -f $1
      FN=`echo $1 | cut -f 1 -d ':'`
    if ! { echo "$ERASED" | grep "$FN" - } ; then
        ERASED="$ERASED $FN"
      fi
      return
    }
    # We want the version numbers to follow on each other, so that the next
    # file we create gets a bigger version number. This makes sure they follow.
    reorganise()
    {
      if [ -z $1 ]; then
        return
      fi
      FN=$1
      FILE_LIST=`ls $FN:* | sort -n -t: -k2`
      if [ "$FILE_LIST" = ":*" ]; then
        echo "All [$FN:*] files erased" >> $LOGFILE
        return
      fi
      echo -e "File list to be moved is:\n$FILE_LIST" >>$LOGFILE
      VERSION=0
      for FNAME in $FILE_LIST; do
        if [ "$FNAME" != "$FN:$VERSION" ]; then
          echo "Moving $FNAME $FN:$VERSION" >>$LOGFILE
          mv $FNAME "$FN:$VERSION"
          VERSION=$[ $VERSION + 1 ]
        fi
      done
    }

    # The main shell script starts here...

    cd $BINDIR
    if [ -f $LOCKFILE ]; then
      exit 0
    fi
    touch $LOCKFILE
    date >> $LOGFILE
    cat $DIRLIST |
    (
      while read SRC ; do
        if [ `echo $SRC | cut -b 1` != "#" ]; then
          echo "Finding files in $SRC" >> $LOGFILE
          echo "Point 1 ($SRC)"
          for FNAME in `find $SRC -type f -xdev -links 1 -print`; do
            process-file $FNAME
          done
        fi
      done
      ERASED=""
      echo "Point 2"
      for FNAME in `find $DATADIR -type f -links 1 -ctime $NDAYS -print`; do
        erase-file $FNAME "(older than $NDAYS days)"
      done
      echo "Point 3"
      for FNAME in `find $DATADIR -type f -name "*:$MAXVER" -print`; do
        FN=`echo $FNAME | cut -f 1 -d ':'`
        erase-file $FN:0 "Too many versions (VERSION > $MAXVER)"
      done
      echo "Point 4"
      for FNAME in "$ERASED"; do
        reorganise $FNAME
      done
    ) 2> $ERRLOG > /dev/null
    rm -f $LOCKFILE

### Bash Shell Script 2

    #!/bin/sh
    CURRDIR=`pwd`/
    if [ -z $SAFEDEL ]; then
      SAFEDEL=/u/safedel
    fi

    DATADIR=$SAFEDEL/data
    BINDIR=$SAFEDEL/bin
    cd $DATADIR$CURRDIR
    if [ -z "$1" ]; then
      echo
      echo "Restores files unintentionally deleted"
      echo
      echo "Useage <salvage <filename>[:version] [dest]> from within the directory"
      echo "       in which the file was deleted."
      echo
      echo "The following is a list of your backed up files and their versions:"
      echo "  Salvageable Files:"
      find . -xdev -type f -maxdepth 1 -links 1 -printf "%P\n" | column
      echo "  Files Currently in Use:"
      find . -xdev -type f -maxdepth 1 -not -links 1 -printf "%P\n" | column
    else
      FN=`echo "$1:end" | cut -f 1 -d ':'`
      VER=`echo "$1:end" | cut -f 2 -d ':'`
      EXIST=`find $CURRDIR -name "$FN"`
    #  echo "[$EXIST]"
      if [ -n "$EXIST" ]; then
        echo "Incorrect file specification: File(s) are not deleted. ($FN)"
        exit 0
      fi
      if [ "$VER" = "end" -o "$VER" = "*" ]; then
        VER=""
      fi
      FILE_LIST=`find . -name "$FN:*" -printf "%f "`
      FLIST=""
    #  echo "FILE_LIST is $FILE_LIST"
      for FNAME in $FILE_LIST; do
        FN=`echo "$FNAME:end" | cut -f 1 -d ':'`
        FOUND=0
    #    echo "Looking for [$FN] in [$FLIST]"
        for F in $FLIST; do
          if [ "$F" = "$FN" ]; then
            FOUND=1
          fi
        done
        if [ "$FOUND" = "0" ]; then
          FLIST="$FLIST $FN"
        fi
      done
    #  echo "FLIST is $FLIST"
      for FNAME in $FLIST; do
        if [ -z "$VER" ]; then
          VERSION=0
          NEXTVER=1
          while [ -f $FNAME:$NEXTVER ]; do
            VERSION=$NEXTVER
            NEXTVER=$[ $NEXTVER + 1 ]
          done
        else
          VERSION=$VER
        fi

        if [ ! -f $FNAME:$VERSION ]; then
          echo "File $FNAME:$VERSION not found"
          exit 0
        fi

        if [ -z "$2" ]; then
          DEST=$CURRDIR$FNAME
        else
          DEST=$CURRDIR$2
        fi

        if ln $FNAME:$VERSION $DEST 2> /dev/null; then
          echo "File $FNAME:$VERSION successfully recovered"
        else
          echo "Cannot link $FNAME:$VERSION to $DEST"
        fi
      done
    fi

### Bash Shell Script 3

    #!/bin/sh

    if [ -z $SAFEDEL ]; then
      SAFEDEL=/u/safedel
    fi

    BINDIR=$SAFEDEL/bin            # Binaries directory
    DATADIR=$SAFEDEL/data          # Where links are to go

    # Erase a file
    reorganise()
    {
      if [ -z $1 ]; then
        return
      fi
      FN=`echo "$1:end" | cut -f 1 -d ':'`
      FILE_LIST=`ls $FN:* | sort -n -t: -k2`
      if [ "$FILE_LIST" = ":*" ]; then
        echo "All [$FN:*] files erased"
        return
      fi
    #  echo -e "File list to be moved is:\n$FILE_LIST"
      VERSION=0
      for FNAME in $FILE_LIST; do
        if [ "$FNAME" != "$FN:$VERSION" ]; then
          echo "Moving $FNAME $FN:$VERSION"
          mv $FNAME "$FN:$VERSION"
          VERSION=$[ $VERSION + 1 ]
        fi
      done
    }

    # The main shell script starts here...

    CURRDIR=`pwd`/

    echo "Safedel: Purging extra versions in $CURRDIR"

    cd $BINDIR
    find $DATADIR$CURRDIR -type f -maxdepth 1 -links 1 -exec rm {} \;
    for FNAME in `find $DATADIR$CURRDIR -type f -maxdepth 1 -print`; do
      reorganise $FNAME
    done

Published in Linux Gazette Issue 16, April 1997

##### This page maintained by the Assistant Editor of Linux Gazette, gazette@ssc.com
Copyright © 1997 Specialized Systems Consultants, Inc.