/usr/sbin/exicyclog is in exim4-base 4.84.2-2+deb8u5.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | #! /bin/sh
# Copyright (c) University of Cambridge, 1995 - 2007
# See the file NOTICE for conditions of use and distribution.
# This script takes the following command line arguments:
# -l dir Log file directory
# -k days Number of days to keep the log files
# Except when they appear in comments, the following placeholders in this
# source are replaced when it is turned into a runnable script:
#
# CONFIGURE_FILE_USE_NODE
# CONFIGURE_FILE_USE_EUID
# CONFIGURE_FILE
# BIN_DIRECTORY
# EXICYCLOG_MAX
# COMPRESS_COMMAND
# COMPRESS_SUFFIX
# CHOWN_COMMAND
# CHGRP_COMMAND
# CHMOD_COMMAND
# TOUCH_COMMAND
# MV_COMMAND
# RM_COMMAND
# This file has been so processed.
# This is a shell script for cycling exim main and reject log files. Each time
# it is run, the files get "shuffled down" by one, the current one (e.g.
# mainlog) becoming mainlog.01, the previous mainlog.01 becoming mainlog.02,
# and so on, up to the limit configured here. When the number to keep is
# greater than 99 (not common, but some people do it), three digits are used
# (e.g. mainlog.001). The same shuffling happens to the reject logs. All
# renamed files with numbers greater than 1 are compressed.
# This script should be called regularly (e.g. daily) by a root crontab
# entry of the form
# 1 0 * * * /opt/exim/bin/exicyclog
# The following lines are generated from Exim's configuration file when
# this source is built into a script, but you can subsequently edit them
# without rebuilding things, as long are you are careful not to overwrite
# the script in the next Exim rebuild/install. "Keep" is the number of old log
# files that are required to be kept. Its value can be overridden by the -k
# command line option. "Compress" and "suffix" define your chosen compression
# method. The others are provided because the location of certain commands
# varies from OS to OS. Sigh.
keep=10
compress=/bin/gzip
suffix=gz
chgrp=look_for_it
chmod=look_for_it
chown=look_for_it
mv=/bin/mv
rm=/bin/rm
touch=/usr/bin/touch
# End of editable lines
#########################################################################
# Sort out command line options.
while [ $# -gt 0 ] ; do
case "$1" in
-l) log_file_path=$2
shift
;;
-k) keep=$2
shift
;;
*) echo "** exicyclog: unknown option $1"
exit 1
;;
esac
shift
done
# Some operating systems have different versions in which the commands live
# in different places. We have a fudge that will search the usual suspects if
# requested.
for cmd in chgrp chmod chown mv rm touch; do
eval "oldcmd=\$$cmd"
if [ "$oldcmd" != "look_for_it" ] ; then continue ; fi
newcmd=$cmd
for dir in /bin /usr/bin /usr/sbin /usr/etc ; do
if [ -f $dir/$cmd ] ; then
newcmd=$dir/$cmd
break
fi
done
eval $cmd=$newcmd
done
# See if this installation is using the esoteric "USE_EUID" feature of Exim,
# in which it uses the effective user id as a suffix for the configuration file
# name. In order for this to work, exicyclog must be run under the appropriate
# euid.
if [ "" = "yes" ]; then
euid=.`id -u`
fi
# See if this installation is using the esoteric "USE_NODE" feature of Exim,
# in which it uses the host's name as a suffix for the configuration file name.
if [ "" = "yes" ]; then
hostsuffix=.`uname -n`
fi
# Now find the configuration file name. This has got complicated because the
# CONFIGURE_FILE value may now be a list of files. The one that is used is the
# first one that exists. Mimic the code in readconf.c by testing first for the
# suffixed file in each case.
set `awk -F: '{ for (i = 1; i <= NF; i++) print $i }' <<End
/etc/exim4/exim4.conf:/var/lib/exim4/config.autogenerated
End
`
while [ "$config" = "" -a $# -gt 0 ] ; do
if [ -f "$1$euid$hostsuffix" ] ; then
config="$1$euid$hostsuffix"
elif [ -f "$1$euid" ] ; then
config="$1$euid"
elif [ -f "$1$hostsuffix" ] ; then
config="$1$hostsuffix"
elif [ -f "$1" ] ; then
config="$1"
fi
shift
done
# Determine if the log file path is set, and where the spool directory is.
# Search for an exim_path setting in the configure file; otherwise use the bin
# directory. Call that version of Exim to find the spool directory and log file
# path, unless log_file_path was set above by a command line option. BEWARE: a
# tab character is needed in the command below. It has had a nasty tendency to
# get lost in the past. Use a variable to hold a space and a tab to keep the
# tab in one place.
st=' '
exim_path=`grep "^[$st]*exim_path" $config | sed "s/.*=[$st]*//"`
if test "$exim_path" = ""; then exim_path=/usr/sbin/exim4; fi
spool_directory=`$exim_path -bP spool_directory | sed 's/.*=[ ]*//'`
if [ "$log_file_path" = "" ] ; then
log_file_path=`$exim_path -bP log_file_path | sed 's/.*=[ ]*//'`
fi
# If log_file_path contains only "syslog" then no Exim log files are in use.
# We can't cycle anything. Complain and give up.
if [ "$log_file_path" = "syslog" ] ; then
echo "*** Exim is logging to syslog - no log files to cycle ***"
exit 1
fi
# Otherwise, remove ":syslog" or "syslog:" (some spaces allowed) and inspect
# what remains. The simplistic regex originally used failed when a filename
# contained "syslog", so we have to use three less general ones, because sed
# doesn't have much power in its regexs.
log_file_path=`echo "$log_file_path" | \
sed 's/^ *:\{0,1\} *syslog *:\{0,1\} *//;s/: *syslog *:/:/;s/: *syslog *$//'`
# If log_file_path is empty, try and get the compiled in default by using
# /dev/null as the configuration file.
if [ "$log_file_path" = "" ]; then
log_file_path=`$exim_path -C /dev/null -bP log_file_path | sed 's/.*=[ ]*//'`
log_file_path=`echo "$log_file_path" | \
sed 's/^ *:\{0,1\} *syslog *:\{0,1\} *//;s/: *syslog *:/:/;s/: *syslog *$//'`
fi
# If log_file_path is still empty, the logs we are interested in are probably
# called "mainlog" and "rejectlog" in the directory called "log" in the spool
# directory. Otherwise we fish out the directory from the given path, and also
# the names of the logs.
if [ "$log_file_path" = "" ]; then
logdir=$spool_directory/log
mainlog=mainlog
rejectlog=rejectlog
paniclog=paniclog
else
logdir=`echo $log_file_path | sed 's?/[^/]*$??'`
logbase=`echo $log_file_path | sed 's?^.*/??'`
mainlog=`echo $logbase | sed 's/%s/main/'`
rejectlog=`echo $logbase | sed 's/%s/reject/'`
paniclog=`echo $logbase | sed 's/%s/panic/'`
fi
# Get into the log directory to do the business.
cd $logdir || exit 1
# If there is no main log file, do nothing.
if [ ! -f $mainlog ]; then exit; fi
# Find out the owner and group of the main log file so that we can re-instate
# this on moved and compressed files, since some operating systems may change
# things. This is a tedious bit of code, but it should work both in operating
# systems where the -l option of ls gives the user and group, and those in which
# you need -lg. The condition is that, if the fifth field of the output from
# ls consists entirely of digits, then the third and fourth fields are the user
# and group.
a=`ls -lg $mainlog`
b=`ls -l $mainlog`
# These statements work fine in the Bourne or Korn shells, but not in Bash.
# So for the benefit of systems whose /bin/sh is really Bash, they have been
# changed to a messier form.
# user=`echo "$a\n$b\n" | awk 'BEGIN { OFS=""} { if ($5 ~ /^[0-9]+$/) print $3; }'`
# group=`echo "$a\n$b\n" | awk 'BEGIN { OFS=""} { if ($5 ~ /^[0-9]+$/) print $4; }'`
user=`echo "$a
$b
" | awk 'BEGIN { OFS=""} { if ($5 ~ /^[0-9]+$/) { print $3; exit; } }'`
group=`echo "$a
$b
" | awk 'BEGIN { OFS=""} { if ($5 ~ /^[0-9]+$/) { print $4; exit; } }'`
# Now do the job. First remove the files that have "fallen off the bottom".
# Look for both the compressed and uncompressed forms.
if [ $keep -lt 10 ]; then keept=0$keep; else keept=$keep; fi;
if [ -f $mainlog.$keept ]; then $rm $mainlog.$keept; fi;
if [ -f $mainlog.$keept.$suffix ]; then $rm $mainlog.$keept.$suffix; fi;
if [ -f $rejectlog.$keept ]; then $rm $rejectlog.$keept; fi;
if [ -f $rejectlog.$keept.$suffix ]; then $rm $rejectlog.$keept.$suffix; fi;
if [ -f $paniclog.$keept ]; then $rm $paniclog.$keept; fi;
if [ -f $paniclog.$keept.$suffix ]; then $rm $paniclog.$keept.$suffix; fi;
# Now rename all the previous old files by increasing their numbers by 1.
# When the number is less than 10, insert a leading zero.
count=$keep
if [ $count -lt 10 ]; then countt=0$count; else countt=$count; fi
while [ $count -gt 1 ]; do
old=`expr -- $count - 1`
if [ $keep -gt 99 ]; then
if [ $old -lt 10 ]; then oldt=00$old
elif [ $old -lt 100 ]; then oldt=0$old
else oldt=$old
fi
else
if [ $old -lt 10 ]; then oldt=0$old; else oldt=$old; fi;
fi
if [ -f $mainlog.$oldt ]; then
$mv $mainlog.$oldt $mainlog.$countt
elif [ -f $mainlog.$oldt.$suffix ]; then
$mv $mainlog.$oldt.$suffix $mainlog.$countt.$suffix
fi
if [ -f $rejectlog.$oldt ]; then
$mv $rejectlog.$oldt $rejectlog.$countt
elif [ -f $rejectlog.$oldt.$suffix ]; then
$mv $rejectlog.$oldt.$suffix $rejectlog.$countt.$suffix
fi
if [ -f $paniclog.$oldt ]; then
$mv $paniclog.$oldt $paniclog.$countt
elif [ -f $paniclog.$oldt.$suffix ]; then
$mv $paniclog.$oldt.$suffix $paniclog.$countt.$suffix
fi
count=$old
countt=$oldt
done
# Now rename the current files as 01 or 001 if keeping more than 99
if [ $keep -gt 99 ]; then first=001; else first=01; fi
if [ -f $mainlog ]; then
$mv $mainlog $mainlog.$first
$chown $user:$group $mainlog.$first
$touch $mainlog
$chown $user:$group $mainlog
$chmod 640 $mainlog
fi
if [ -f $rejectlog ]; then
$mv $rejectlog $rejectlog.$first
$chown $user:$group $rejectlog.$first
$touch $rejectlog
$chown $user:$group $rejectlog
$chmod 640 $rejectlog
fi
if [ -f $paniclog ]; then
$mv $paniclog $paniclog.$first
$chown $user:$group $paniclog.$first
$touch $paniclog
$chown $user:$group $paniclog
$chmod 640 $paniclog
fi
# Now scan the (0)02 and later files, compressing where necessary, and
# ensuring that their owners and groups are correct.
count=2;
while [ $count -le $keep ]; do
if [ $keep -gt 99 ]; then
if [ $count -lt 10 ]; then countt=00$count
elif [ $count -lt 100 ]; then countt=0$count
else countt=$count
fi
else
if [ $count -lt 10 ]; then countt=0$count; else countt=$count; fi
fi
if [ -f $mainlog.$countt ]; then $compress $mainlog.$countt; fi
if [ -f $mainlog.$countt.$suffix ]; then
$chown $user:$group $mainlog.$countt.$suffix
fi
if [ -f $rejectlog.$countt ]; then $compress $rejectlog.$countt; fi
if [ -f $rejectlog.$countt.$suffix ]; then
$chown $user:$group $rejectlog.$countt.$suffix
fi
if [ -f $paniclog.$countt ]; then $compress $paniclog.$countt; fi
if [ -f $paniclog.$countt.$suffix ]; then
$chown $user:$group $paniclog.$countt.$suffix
fi
count=`expr -- $count + 1`
done
# End of exicyclog
|