home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / bin / savelog < prev    next >
Encoding:
Text File  |  2010-07-15  |  10.1 KB  |  355 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]
  15. #         [-j] [-C] [-d] [-l] [-r rolldir] [-n] [-q] 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. #    -r rolldir- use rolldir instead of . to roll files
  21. #    -C      - force cleanup of cycled logfiles
  22. #    -d      - use standard date for rolling
  23. #    -D      - override date format for -d 
  24. #    -t      - touch file
  25. #    -l      - don't compress any log files    (default: compress)
  26. #       -p        - preserve mode/user/group of original file
  27. #    -j        - use bzip2 instead of gzip
  28. #    -J        - use xz instead of gzip
  29. #    -1 .. -9  - compression strength or memory usage (default: 9, except for xz)
  30. #    -x script - invoke script with rotated log file in $FILE
  31. #    -n      - do not rotate empty files
  32. #    -q      - be quiet
  33. #    file       - log file names
  34. #
  35. # The savelog command saves and optionally compresses old copies of files.
  36. # Older version of 'file' are named:
  37. #
  38. #        'file'.<number><compress_suffix>
  39. #
  40. # where <number> is the version number, 0 being the newest.  By default,
  41. # version numbers > 0 are compressed (unless -l prevents it). The
  42. # version number 0 is never compressed on the off chance that a process
  43. # still has 'file' opened for I/O.
  44. #
  45. # if the '-d' option is specified, <number> will be YYMMDDhhmmss
  46. #
  47. # If the 'file' does not exist and -t was given, it will be created.
  48. #
  49. # For files that do exist and have lengths greater than zero, the following 
  50. # actions are performed.
  51. #
  52. #    1) Version numered files are cycled.  That is version 6 is moved to
  53. #       version 7, version is moved to becomes version 6, ... and finally
  54. #       version 0 is moved to version 1.  Both compressed names and
  55. #       uncompressed names are cycled, regardless of -t.  Missing version 
  56. #       files are ignored.
  57. #
  58. #    2) The new file.1 is compressed and is changed subject to 
  59. #       the -m, -u and -g flags.  This step is skipped if the -t flag 
  60. #       was given.
  61. #
  62. #    3) The main file is moved to file.0.
  63. #
  64. #    4) If the -m, -u, -g, -t, or -p flags are given, then the file is
  65. #          touched into existence subject to the given flags.  The -p flag
  66. #          will preserve the original owner, group, and permissions.
  67. #
  68. #    5) The new file.0 is changed subject to the -m, -u and -g flags.
  69. #
  70. # Note: If no -m, -u, -g, -t, or -p is given, then the primary log file is 
  71. #    not created.
  72. #
  73. # Note: Since the version numbers start with 0, version number <cycle>
  74. #       is never formed.  The <cycle> count must be at least 2.
  75. #
  76. # Bugs: If a process is still writing to the file.0 and savelog
  77. #    moved it to file.1 and compresses it, data could be lost.
  78. #    Smail does not have this problem in general because it
  79. #    restats files often.
  80.  
  81. # common location
  82. export PATH=$PATH:/sbin:/bin:/usr/sbin:/usr/bin
  83. COMPRESS="gzip"
  84. COMPRESS_OPTS="-f"
  85. COMPRESS_STRENGTH_DEF="-9";
  86. DOT_Z=".gz"
  87. DATUM=`date +%Y%m%d%H%M%S`
  88.  
  89. # parse args
  90. exitcode=0    # no problems to far
  91. prog=`basename $0`
  92. mode=
  93. user=
  94. group=
  95. touch=
  96. forceclean=
  97. rolldir=
  98. datum=
  99. preserve=
  100. hookscript=
  101. quiet=0
  102. rotateifempty=yes
  103. count=7
  104.  
  105. usage()
  106. {
  107.     echo "Usage: $prog [-m mode] [-u user] [-g group] [-t] [-c cycle] [-p]"
  108.     echo "             [-j] [-C] [-d] [-l] [-r rolldir] [-n] [-q] file ..."
  109.     echo "    -m mode       - chmod log files to mode"
  110.     echo "    -u user       - chown log files to user"
  111.     echo "    -g group   - chgrp log files to group"
  112.     echo "    -c cycle   - save cycle versions of the logfile (default: 7)"
  113.     echo "    -r rolldir - use rolldir instead of . to roll files"
  114.     echo "    -C       - force cleanup of cycled logfiles"
  115.     echo "    -d       - use standard date for rolling"
  116.     echo "    -D       - override date format for -d"
  117.     echo "    -t       - touch file"
  118.     echo "    -l       - don't compress any log files (default: compress)"
  119.     echo "    -p         - preserve mode/user/group of original file"
  120.     echo "    -j         - use bzip2 instead of gzip"
  121.     echo "    -J         - use xz instead of gzip"
  122.     echo "    -1 .. -9   - compression strength or memory usage (default: 9, except for xz)"
  123.     echo "    -x script  - invoke script with rotated log file in \$FILE"
  124.     echo "    -n         - do not rotate empty files"
  125.     echo "    -q         - suppress rotation message"
  126.     echo "    file        - log file names"
  127. }
  128.  
  129.  
  130. fixfile()
  131. {
  132.     if [ -n "$user" ]; then
  133.     chown -- "$user" "$1"
  134.     fi
  135.     if [ -n "$group" ]; then 
  136.     chgrp -- "$group" "$1"
  137.     fi
  138.     if [ -n "$mode" ]; then 
  139.     chmod -- "$mode" "$1"
  140.     fi
  141. }
  142.  
  143.  
  144. while getopts m:u:g:c:r:CdD:tlphjJ123456789x:nq opt ; do
  145.     case "$opt" in
  146.     m) mode="$OPTARG" ;;
  147.     u) user="$OPTARG" ;;
  148.     g) group="$OPTARG" ;;
  149.     c) count="$OPTARG" ;;
  150.     r) rolldir="$OPTARG" ;;
  151.     C) forceclean=1 ;;
  152.     d) datum=1 ;;
  153.     D) DATUM=$(date +$OPTARG) ;;
  154.     t) touch=1 ;;
  155.     j) COMPRESS="bzip2"; COMPRESS_OPTS="-f"; COMPRESS_STRENGTH_DEF="-9"; DOT_Z=".bz2" ;;
  156.     J) COMPRESS="xz"; COMPRESS_OPTS="-f"; COMPRESS_STRENGTH_DEF=""; DOT_Z=".xz" ;;
  157.     [1-9]) COMPRESS_STRENGTH="-$opt" ;;
  158.     x) hookscript="$OPTARG" ;;
  159.     l) COMPRESS="" ;;
  160.     p) preserve=1 ;;
  161.     n) rotateifempty="no" ;;
  162.     q) quiet=1 ;;
  163.     h) usage; exit 0 ;;
  164.     *) usage; exit 1 ;;
  165.     esac
  166. done
  167.  
  168. shift $(($OPTIND - 1))
  169.  
  170. if [ "$count" -lt 2 ]; then
  171.     echo "$prog: count must be at least 2" 1>&2
  172.     exit 2
  173. fi
  174.  
  175. if [ -n "$COMPRESS" ] && [ -z "`which $COMPRESS`"  ]; then
  176.        echo "$prog: Compression binary not available, please make sure '$COMPRESS' is installed" 1>&2
  177.        exit 2
  178. fi
  179.  
  180. if [ -n "$COMPRESS_STRENGTH" ]; then
  181.     COMPRESS_OPTS="$COMPRESS_OPTS $COMPRESS_STRENGTH"
  182. else
  183.     COMPRESS_OPTS="$COMPRESS_OPTS $COMPRESS_STRENGTH_DEF"
  184. fi
  185.  
  186. # cycle thru filenames
  187. while [ $# -gt 0 ]; do
  188.  
  189.     # get the filename
  190.     filename="$1"
  191.     shift
  192.  
  193.     # catch bogus files
  194.     if [ -e "$filename" ] && [ ! -f "$filename" ]; then
  195.         echo "$prog: $filename is not a regular file" 1>&2
  196.         exitcode=3
  197.         continue
  198.     fi
  199.  
  200.     # if file does not exist or is empty, and we've been told to not rotate
  201.     # empty files, create if requested and skip to the next file.
  202.     if [ ! -s "$filename" ] && [ "$rotateifempty" = "no" ]; then
  203.         # if -t was given and it does not exist, create it
  204.         if test -n "$touch" && [ ! -f "$filename" ]; then 
  205.             touch -- "$filename"
  206.             if [ "$?" -ne 0 ]; then
  207.                 echo "$prog: could not touch $filename" 1>&2
  208.                 exitcode=4
  209.                 continue
  210.             fi
  211.             fixfile "$filename"
  212.         fi
  213.         continue
  214.     # otherwise if the file does not exist and we've been told to rotate it
  215.     # anyway, create an empty file to rotate.
  216.     elif [ ! -e "$filename" ]; then
  217.         touch -- "$filename"
  218.         if [ "$?" -ne 0 ]; then
  219.             echo "$prog: could not touch $filename" 1>&2
  220.             exitcode=4
  221.             continue
  222.         fi
  223.         fixfile "$filename"
  224.     fi
  225.  
  226.      # be sure that the savedir exists and is writable
  227.     # (Debian default: $savedir is . and not ./OLD)
  228.      savedir=`dirname -- "$filename"`
  229.      if [ -z "$savedir" ]; then
  230.          savedir=.
  231.      fi
  232.     case "$rolldir" in
  233.         (/*)
  234.         savedir="$rolldir"
  235.         ;;
  236.         (*)
  237.         savedir="$savedir/$rolldir"
  238.         ;;
  239.     esac
  240.      if [ ! -d "$savedir" ]; then
  241.          mkdir -p -- "$savedir"
  242.          if [ "$?" -ne 0 ]; then
  243.              echo "$prog: could not mkdir $savedir" 1>&2
  244.              exitcode=5
  245.              continue
  246.          fi
  247.          chmod 0755 -- "$savedir"
  248.      fi
  249.      if [ ! -w "$savedir" ]; then
  250.          echo "$prog: directory $savedir is not writable" 1>&2
  251.          exitcode=7
  252.          continue
  253.      fi
  254.  
  255.     # determine our uncompressed file names
  256.     newname=`basename -- "$filename"`
  257.     newname="$savedir/$newname"
  258.  
  259.     # cycle the old compressed log files
  260.     cycle=$(( $count - 1))
  261.     rm -f -- "$newname.$cycle" "$newname.$cycle$DOT_Z"
  262.     while [ $cycle -gt 1 ]; do
  263.         # --cycle
  264.         oldcycle=$cycle
  265.         cycle=$(( $cycle - 1 ))
  266.         # cycle log
  267.         if [ -f "$newname.$cycle$DOT_Z" ]; then
  268.             mv -f -- "$newname.$cycle$DOT_Z" \
  269.                 "$newname.$oldcycle$DOT_Z"
  270.         fi
  271.         if [ -f "$newname.$cycle" ]; then
  272.             # file was not compressed. move it anyway
  273.             mv -f -- "$newname.$cycle" "$newname.$oldcycle"
  274.         fi
  275.     done
  276.  
  277.     # compress the old uncompressed log if needed
  278.     if [ -f "$newname.0" ]; then
  279.         if [ -z "$COMPRESS" ]; then
  280.             newfile="$newname.1"
  281.             mv -- "$newname.0" "$newfile"
  282.         else
  283.             newfile="$newname.1$DOT_Z"
  284. #            $COMPRESS $COMPRESS_OPTS < $newname.0 > $newfile
  285. #            rm -f $newname.0
  286.             $COMPRESS $COMPRESS_OPTS "$newname.0"
  287.             mv -- "$newname.0$DOT_Z" "$newfile"
  288.         fi
  289.         fixfile "$newfile"
  290.     fi
  291.  
  292.     # compress the old uncompressed log if needed
  293.     if test -n "$datum" && test -n "$COMPRESS"; then
  294.         $COMPRESS $COMPRESS_OPTS -- "$newname".[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
  295.     fi
  296.  
  297.     # remove old files if so desired
  298.     if [ -n "$forceclean" ]; then
  299.         cycle=$(( $count - 1))
  300.         if [ -z "$COMPRESS" ]; then
  301.             rm -f -- `ls -t -- $newname.[0-9]* | sed -e 1,${cycle}d`
  302.         else
  303.             rm -f -- `ls -t -- $newname.[0-9]*$DOT_Z | sed -e 1,${cycle}d`
  304.         fi
  305.     fi
  306.  
  307.     # create new file if needed
  308.     if [ -n "$preserve" ]; then
  309.         (umask 077
  310.          touch -- "$filename.new"
  311.          chown --reference="$filename" -- "$filename.new"
  312.          chmod --reference="$filename" -- "$filename.new")
  313.         filenew=1
  314.     elif [ -n "$touch$user$group$mode" ]; then
  315.         touch -- "$filename.new"
  316.         fixfile "$filename.new"
  317.         filenew=1
  318.     fi
  319.  
  320.     newfilename="$newname.0"
  321.     # link the file into the file.0 holding place
  322.     if [ -f "$filename" ]; then
  323.         if [ -n "$filenew" ]; then
  324.             if ln -f -- "$filename" "$newfilename"; then
  325.                 mv -- "$filename.new" "$filename"
  326.             else
  327.                 echo "Error hardlinking $filename to $newfilename" >&2
  328.                 exitcode=8
  329.                 continue
  330.             fi
  331.         else
  332.             mv -- "$filename" "$newfilename"
  333.         fi
  334.     fi
  335.     [ ! -f "$newfilename" ] && touch -- "$newfilename"
  336.     fixfile "$newfilename"
  337.     if [ -n "$datum" ]; then
  338.         mv -- "$newfilename" "$newname.$DATUM"
  339.         newfilename="$newname.$DATUM"
  340.     fi
  341.  
  342.     if [ -n "$hookscript" ]; then
  343.       FILE="$newfilename" $SHELL -c "$hookscript" || \
  344.       {
  345.         ret=$?
  346.         test "$quiet" -eq 1 || echo "Hook script failed with exit code $ret." 1>&2
  347.       }
  348.     fi
  349.  
  350.     # report successful rotation
  351.     test "$quiet" -eq 1 || echo "Rotated \`$filename' at `date`."
  352. done
  353. exit $exitcode
  354.