home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 February / PCWorld_2000-02_cd.bin / live / usr / bin / savelog < prev    next >
Text File  |  1998-08-16  |  6KB  |  241 lines

  1. #! /bin/sh
  2. # savelog - save a log file
  3. #    Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
  4. #    Copyright (C) 1992  Ronald S. Karr
  5. # Slight modifications by Ian A. Murdock <imurdock@gnu.ai.mit.edu>:
  6. #    * uses `gzip' rather than `compress'
  7. #    * doesn't use $savedir; keeps saved log files in the same directory
  8. #    * reports successful rotation of log files
  9. #    * for the sake of consistency, files are rotated even if they are
  10. #      empty
  11. # More modifications by Guy Maor <maor@debian.org>:
  12. #       * cleanup.
  13. #       * -p (preserve) option
  14. # usage: savelog [-m mode] [-u user] [-g group] [-t] [-p] [-c cycle] [-l]
  15. #                file...
  16. #    -m mode      - chmod log files to mode
  17. #    -u user      - chown log files to user
  18. #    -g group  - chgrp log files to group
  19. #    -c cycle  - save cycle versions of the logfile    (default: 7)
  20. #    -t      - touch file
  21. #    -l      - don't compress any log files    (default: compress)
  22. #       -p        - preserve mode/user/group of original file
  23. #    file       - log file names
  24. #
  25. # The savelog command saves and optionally compresses old copies of files.
  26. # Older version of 'file' are named:
  27. #
  28. #        'file'.<number><compress_suffix>
  29. #
  30. # where <number> is the version number, 0 being the newest.  By default,
  31. # version numbers > 0 are compressed (unless -l prevents it). The
  32. # version number 0 is never compressed on the off chance that a process
  33. # still has 'file' opened for I/O.
  34. #
  35. # If the 'file' does not exist and -t was given, it will be created.
  36. #
  37. # For files that do exist and have lengths greater than zero, the following 
  38. # actions are performed.
  39. #
  40. #    1) Version numered files are cycled.  That is version 6 is moved to
  41. #       version 7, version is moved to becomes version 6, ... and finally
  42. #       version 0 is moved to version 1.  Both compressed names and
  43. #       uncompressed names are cycled, regardless of -t.  Missing version 
  44. #       files are ignored.
  45. #
  46. #    2) The new file.1 is compressed and is changed subject to 
  47. #       the -m, -u and -g flags.  This step is skipped if the -t flag 
  48. #       was given.
  49. #
  50. #    3) The main file is moved to file.0.
  51. #
  52. #    4) If the -m, -u, -g, -t, or -p flags are given, then the file is
  53. #          touched into existence subject to the given flags.  The -p flag
  54. #          will preserve the original owner, group, and permissions.
  55. #
  56. #    5) The new file.0 is changed subject to the -m, -u and -g flags.
  57. #
  58. # Note: If no -m, -u, -g, -t, or -p is given, then the primary log file is 
  59. #    not created.
  60. #
  61. # Note: Since the version numbers start with 0, version number <cycle>
  62. #       is never formed.  The <cycle> count must be at least 2.
  63. #
  64. # Bugs: If a process is still writing to the file.0 and savelog
  65. #    moved it to file.1 and compresses it, data could be lost.
  66. #    Smail does not have this problem in general because it
  67. #    restats files often.
  68.  
  69. # common location
  70. export PATH=$PATH:/sbin:/bin:/usr/sbin:/usr/bin
  71. COMPRESS="gzip -9f"
  72. DOT_Z=".gz"
  73.  
  74. # parse args
  75. exitcode=0    # no problems to far
  76. prog=`basename $0`
  77. mode=
  78. user=
  79. group=
  80. touch=
  81. preserve=
  82. count=7
  83.  
  84. usage()
  85. {
  86.     echo "Usage: $prog [-m mode][-u user][-g group][-t][-c cycle][-l][-p] file ..."
  87. }
  88.  
  89.  
  90. fixfile()
  91. {
  92.     if [ -n "$user" ]; then
  93.     chown "$user" "$1"
  94.     fi
  95.     if [ -n "$group" ]; then 
  96.     chgrp "$group" "$1"
  97.     fi
  98.     if [ -n "$mode" ]; then 
  99.     chmod "$mode" "$1"
  100.     fi
  101. }
  102.  
  103.  
  104. while getopts m:u:g:c:ltph opt ; do
  105.     case "$opt" in
  106.     m) mode="$OPTARG" ;;
  107.     u) user="$OPTARG" ;;
  108.     g) group="$OPTARG" ;;
  109.     c) count="$OPTARG" ;;
  110.     t) touch=1 ;;
  111.     l) COMPRESS="" ;;
  112.     p) preserve=1 ;;
  113.     h) usage; exit 0 ;;
  114.     *) usage; exit 1 ;;
  115.     esac
  116. done
  117.  
  118. shift $(($OPTIND - 1))
  119.  
  120. if [ "$count" -lt 2 ]; then
  121.     echo "$prog: count must be at least 2" 1>&2
  122.     exit 2
  123. fi
  124.  
  125. # cycle thru filenames
  126. while [ $# -gt 0 ]; do
  127.  
  128.     # get the filename
  129.     filename="$1"
  130.     shift
  131.  
  132.     # catch bogus files
  133.     if [ -e "$filename" -a ! -f "$filename" ]; then
  134.         echo "$prog: $filename is not a regular file" 1>&2
  135.         exitcode=3
  136.         continue
  137.     fi
  138.  
  139.     # if not a file or empty, do nothing major
  140.     # (in the Debian version, we rotate even if empty)
  141.     #if [ ! -s $filename ]; then
  142.         # if -t was given and it does not exist, create it
  143.         if [ -n "$touch" -a ! -f "$filename" ]; then 
  144.             touch "$filename"
  145.             if [ "$?" -ne 0 ]; then
  146.                 echo "$prog: could not touch $filename" 1>&2
  147.                 exitcode=4
  148.                 continue
  149.             fi
  150.             fixfile "$filename"
  151.         fi
  152.     #    continue
  153.     #fi
  154.  
  155.      # be sure that the savedir exists and is writable
  156.     # (in the Debian version, $savedir is . and not ./OLD)
  157.      savedir=`dirname "$filename"`
  158.      if [ -z "$savedir" ]; then
  159.          savedir=.
  160.      fi
  161.      if [ ! -d "$savedir" ]; then
  162.          mkdir "$savedir"
  163.          if [ "$?" -ne 0 ]; then
  164.              echo "$prog: could not mkdir $savedir" 1>&2
  165.              exitcode=5
  166.              continue
  167.          fi
  168.          chmod 0755 "$savedir"
  169.      fi
  170.      if [ ! -w "$savedir" ]; then
  171.          echo "$prog: directory $savedir is not writable" 1>&2
  172.          exitcode=7
  173.          continue
  174.      fi
  175.  
  176.     # determine our uncompressed file names
  177.     newname=`basename "$filename"`
  178.     newname="$savedir/$newname"
  179.  
  180.     # cycle the old compressed log files
  181.     cycle=$(( $count - 1))
  182.     rm -f "$newname.$cycle" "$newname.$cycle$DOT_Z"
  183.     while [ $cycle -gt 1 ]; do
  184.         # --cycle
  185.         oldcycle=$cycle
  186.         cycle=$(( $cycle - 1 ))
  187.         # cycle log
  188.         if [ -f "$newname.$cycle$DOT_Z" ]; then
  189.             mv -f "$newname.$cycle$DOT_Z" \
  190.                 "$newname.$oldcycle$DOT_Z"
  191.         fi
  192.         if [ -f "$newname.$cycle" ]; then
  193.             # file was not compressed. move it anyway
  194.             mv -f "$newname.$cycle" "$newname.$oldcycle"
  195.         fi
  196.     done
  197.  
  198.     # compress the old uncompressed log if needed
  199.     if [ -f "$newname.0" ]; then
  200.         if [ -z "$COMPRESS" ]; then
  201.             newfile="$newname.1"
  202.             mv "$newname.0" "$newfile"
  203.         else
  204.             newfile="$newname.1$DOT_Z"
  205. #            $COMPRESS < $newname.0 > $newfile
  206. #            rm -f $newname.0
  207.             $COMPRESS "$newname.0"
  208.             mv "$newname.0$DOT_Z" "$newfile"
  209.         fi
  210.         fixfile "$newfile"
  211.     fi
  212.  
  213.     # create new file if needed
  214.     if [ -n "$preserve" ]; then
  215.         cp -p "$filename" "$filename.new"
  216.         echo -n > "$filename.new"
  217.         filenew=1
  218.     elif [ -n "$touch$user$group$mode" ]; then
  219.         touch "$filename.new"
  220.         fixfile "$filename.new"
  221.         filenew=1
  222.     fi
  223.  
  224.     # link the file into the file.0 holding place
  225.     if [ -f "$filename" ]; then
  226.         if [ -n "$filenew" ]; then
  227.             ln -f "$filename" "$newname.0"
  228.             mv "$filename.new" "$filename"
  229.         else
  230.             mv "$filename" "$newname.0"
  231.         fi
  232.     fi
  233.     [ ! -f "$newname.0" ] && touch "$newname.0"
  234.     fixfile "$newname.0"
  235.  
  236.     # report successful rotation
  237.     echo "Rotated \`$filename' at `date`."
  238. done
  239. exit $exitcode
  240.