freebsd-src/mk/newlog.sh
Simon J. Gerraty a6b892e1c7 Import bmake-20240309
Intersting/relevant changes since bmake-20240108

ChangeLog since bmake-20240108

2024-03-10  Simon J Gerraty  <sjg@beast.crufty.net>

	* boot-strap: tests can take a long time; use a cookie to
	skip them if bmake has not been updated since tests last
	ran successfully.

	* Makefile: Cygwin handles MANTARGET man

	* unit-tests/Makefile: set BROKEN_TESTS for Cygwin

2024-03-09  Simon J Gerraty  <sjg@beast.crufty.net>

	* VERSION (_MAKE_VERSION): 20240309
	Merge with NetBSD make, pick up
	o set .ERROR_EXIT to the exit status of .ERROR_TARGET
	this allows a .ERROR target to ignore the case of
	.ERROR_EXIT==6 which just means that the build actually
	failed somewhere else.

2024-03-04  Simon J Gerraty  <sjg@beast.crufty.net>

	* VERSION (_MAKE_VERSION): 20240303

	* var.c: on IRIX we need both inttypes.h and stdint.h

2024-03-01  Simon J Gerraty  <sjg@beast.crufty.net>

	* VERSION (_MAKE_VERSION): 20240301
	Merge with NetBSD make, pick up
	o export variables with value from target scope
	when appropriate.

2024-02-12  Simon J Gerraty  <sjg@beast.crufty.net>

	* VERSION (_MAKE_VERSION): 20240212
	Merge with NetBSD make, pick up
	o remove unneeded conditional-compilation toggles
	INCLUDES, LIBRARIES, POSIX, SYSVINCLUDE, SYSVVARSUB,
	GMAKEEXPORT NO_REGEX and SUNSHCMD

	* configure.in: add check for regex.h

	* var.c: replace use of NO_REGEX with HAVE_REGEX_H

2024-02-04  Simon J Gerraty  <sjg@beast.crufty.net>

	* VERSION (_MAKE_VERSION): 20240204
	Merge with NetBSD make, pick up
	o var.c: fix some lint (-dL) mode parsing issues

2024-02-02  Simon J Gerraty  <sjg@beast.crufty.net>

	* VERSION: (_MAKE_VERSION): 20240202
	Merge with NetBSD make, pick up
	o make.1: note that arg to :D and :U can be empty
	o var.c: $$ is not a parse error when .MAKE.SAVE_DOLLARS=no

mk/ChangeLog since bmake-20240108

2024-03-09  Simon J Gerraty  <sjg@beast.crufty.net>

	* install-mk (MK_VERSION): 20240309

	* meta.sys.mk: _metaError: if .ERROR_EXIT == 6, we do not
	want to save the .ERROR_META_FILE

2024-02-20  Simon J Gerraty  <sjg@beast.crufty.net>

	* install-mk (MK_VERSION): 20240220

	* sys.dirdeps.mk, dirdeps-targets.mk, init.mk:
	do not set .MAIN: dirdeps in sys.dirdeps.mk
	dirdeps-targets.mk will do that for top-level builds
	and init.mk will do it for others.
	This allows a Makefile which has no need of 'dirdeps' to
	set .MAIN for itself and "just work".

2024-02-18  Simon J Gerraty  <sjg@beast.crufty.net>

	* bsd.*.mk: for makefiles that get a bsd. symlink,
	use _this in  multiple inclusion tags since .PARSEFILE will not
	DTRT when such a makefile is included directly by Makefile and
	automatically (without bsd. prefix).
	Since we cannot guarantee that our sys.mk will be used, we provide
	a default _this in each makefile that gets a bsd. prefix such that
	the value is the same regardless of bsd. prefix.

	* subdir.mk: drop the !target guard on $SUBDIR_TARGETS

2024-02-12  Simon J Gerraty  <sjg@beast.crufty.net>

	* install-mk (MK_VERSION): 20240212

	* SPDX-License-Identifier: BSD-2-Clause
	Add SPDX-License-Identifier to inidicate that I consider
	my copyright on any of these makefiles equivalent to BSD-2-Clause

	* autoconf.mk: allow for configure.ac as currently recommended

	* subdir.mk: support @auto
	which is replaced with each subdir that
	has a [Mm]akefile.

	* subdir.mk: include local.subdir.mk if it exists.

	* subdir.mk: rework to handle .WAIT

2024-02-11  Simon J Gerraty  <sjg@beast.crufty.net>

	* subdir.mk: _SUBDIRUSE report the target we are entering subdirs for.

2024-02-10  Simon J Gerraty  <sjg@beast.crufty.net>

	* prog.mk: treat empty SRCS the same as undefined

2024-02-02  Simon J Gerraty  <sjg@beast.crufty.net>

	* Avoid undefined errors in lint (-dL) mode

	* man.mk (CMT2DOC_FLAGS): note that -mm does mdoc(7)

2024-01-28  Simon J Gerraty  <sjg@beast.crufty.net>

	* install-mk (MK_VERSION): 20240128

	* FILES: add ccm.dep.mk for C++ modules
	add suffixes.mk for common location for generic SUFFIX rules.

	* auto.dep.mk autodep.mk meta.autodep.mk: include ccm.dep.mk
	replace OBJ_EXTENSIONS with OBJ_SUFFIXES

	* autodep.mk: leverage CXX_SUFFIXES for __depsrcs
	and update style (spaces around = etc)

	* init.mk: add OBJS_SRCS_FILTER to filter SRCS when
	setting OBJS

	* meta2deps.py: handle multiple ./ embedded in path better.
2024-03-13 19:14:41 -07:00

415 lines
8.3 KiB
Bash
Executable File

#!/bin/sh
# NAME:
# newlog - rotate log files
#
# SYNOPSIS:
# newlog.sh [options] "log"[:"num"] ...
#
# DESCRIPTION:
# This script saves multiple generations of each "log".
# The "logs" are kept compressed except for the current and
# previous ones.
#
# Options:
#
# -C "compress"
# Compact old logs (other than .0) with "compress"
# (default is 'gzip' or 'compress' if no 'gzip').
#
# -E "ext"
# If "compress" produces a file extention other than
# '.Z' or '.gz' we need to know.
#
# -G "gens"
# "gens" is a comma separated list of "log":"num" pairs
# that allows certain logs to handled differently.
#
# -N Don't actually do anything, just show us.
#
# -R Rotate rather than save logs by default.
# This is the default anyway.
#
# -S Save rather than rotate logs by default.
# Each log is saved to a unique name that remains
# unchanged. This results in far less churn.
#
# -f "fmt"
# Format ('%Y%m%d.%H%M%S') for suffix added to "log" to
# uniquely name it when using the '-S' option.
# If a "log" is saved more than once per second we add
# an extra suffix of our process-id.
#
# -d The "log" to be rotated/saved is a directory.
# We leave the mode of old directories alone.
#
# -e Normally logs are only cycled if non-empty, this
# option forces empty logs to be cycled as well.
#
# -g "group"
# Set the group of "log" to "group".
#
# -m "mode"
# Set the mode of "log".
#
# -M "mode"
# Set the mode of old logs (default 444).
#
# -n "num"
# Keep "num" generations of "log".
#
# -o "owner"
# Set the owner of "log".
#
# Regardless of whether '-R' or '-S' is provided, we attempt to
# choose the correct behavior based on observation of "log.0" if
# it exists; if it is a symbolic link, we save, otherwise
# we rotate.
#
# BUGS:
# 'Newlog.sh' tries to avoid being fooled by symbolic links, but
# multiply indirect symlinks are only handled on machines where
# test(1) supports a check for symlinks.
#
# AUTHOR:
# Simon J. Gerraty <sjg@crufty.net>
#
# RCSid:
# $Id: newlog.sh,v 1.27 2024/02/17 17:26:57 sjg Exp $
#
# SPDX-License-Identifier: BSD-2-Clause
#
# @(#) Copyright (c) 1993-2016 Simon J. Gerraty
#
# This file is provided in the hope that it will
# be of use. There is absolutely NO WARRANTY.
# Permission to copy, redistribute or otherwise
# use this file is hereby granted provided that
# the above copyright notice and this notice are
# left intact.
#
# Please send copies of changes and bug-fixes to:
# sjg@crufty.net
#
Mydir=`dirname $0`
case $Mydir in
/*) ;;
*) Mydir=`cd $Mydir; pwd`;;
esac
# places to find chown (and setopts.sh)
PATH=$PATH:/usr/etc:/sbin:/usr/sbin:/usr/local/share/bin:/share/bin:$Mydir
# linux doesn't necessarily have compress,
# and gzip appears in various locations...
Which() {
case "$1" in
-*) t=$1; shift;;
*) t=-x;;
esac
case "$1" in
/*) test $t $1 && echo $1;;
*)
for d in `IFS=:; echo ${2:-$PATH}`
do
test $t $d/$1 && { echo $d/$1; break; }
done
;;
esac
}
# shell's typically have test(1) as built-in
# and not all support all options.
test_opt() {
_o=$1
_a=$2
_t=${3:-/}
case `test -$_o $_t 2>&1` in
*:*) eval test_$_o=$_a;;
*) eval test_$_o=-$_o;;
esac
}
# convert find/ls mode to octal
fmode() {
eval `echo $1 |
sed 's,\(.\)\(...\)\(...\)\(...\),ft=\1 um=\2 gm=\3 om=\4,'`
sm=
case "$um" in
*s*) sm=r
um=`echo $um | sed 's,s,x,'`
;;
*) sm=-;;
esac
case "$gm" in
*[Ss]*)
sm=${sm}w
gm=`echo $gm | sed 's,s,x,;s,S,-,'`
;;
*) sm=${sm}-;;
esac
case "$om" in
*t)
sm=${sm}x
om=`echo $om | sed 's,t,x,'`
;;
*) sm=${sm}-;;
esac
echo $sm $um $gm $om |
sed 's,rwx,7,g;s,rw-,6,g;s,r-x,5,g;s,r--,4,g;s,-wx,3,g;s,-w-,2,g;s,--x,1,g;s,---,0,g;s, ,,g'
}
get_mode() {
case "$OS,$STAT" in
FreeBSD,*)
$STAT -f %Op $1 | sed 's,.*\(....\),\1,'
return
;;
esac
# fallback to find
fmode `find $1 -ls -prune | awk '{ print $3 }'`
}
get_mtime_suffix() {
case "$OS,$STAT" in
FreeBSD,*)
$STAT -t "${2:-$opt_f}" -f %Sm $1
return
;;
esac
# this will have to do
date "+${2:-$opt_f}"
}
case /$0 in
*/newlog*) rotate_func=rotate_log;;
*/save*) rotate_func=save_log;;
*) rotate_func=rotate_log;;
esac
opt_n=7
opt_m=
opt_M=444
opt_f=%Y%m%d.%H%M%S
opt_str=dNn:o:g:G:C:M:m:eE:f:RS
. setopts.sh
test $# -gt 0 || exit 0 # nothing to do.
OS=${OS:-`uname`}
STAT=${STAT:-`Which stat`}
# sorry, setops semantics for booleans changed.
case "${opt_d:-0}" in
0) rm_f=-f
opt_d=-f
for x in $opt_C gzip compress
do
opt_C=`Which $x "/bin:/usr/bin:$PATH"`
test -x $opt_C && break
done
empty() { test ! -s $1; }
;;
*) rm_f=-rf
opt_d=-d
opt_M=
opt_C=:
empty() {
if [ -d $1 ]; then
n=`'ls' -a1 $1/. | wc -l`
[ $n -gt 2 ] && return 1
fi
return 0
}
;;
esac
case "${opt_N:-0}" in
0) ECHO=;;
*) ECHO=echo;;
esac
case "${opt_e:-0}" in
0) force=;;
*) force=yes;;
esac
case "${opt_R:-0}" in
0) ;;
*) rotate_func=rotate_log;;
esac
case "${opt_S:-0}" in
0) ;;
*) rotate_func=save_log opt_S=;;
esac
# see whether test handles -h or -L
test_opt L -h
test_opt h ""
case "$test_L,$test_h" in
-h,) test_L= ;; # we don't support either!
esac
case "$test_L" in
"") # No, so this is about all we can do...
logs=`'ls' -ld $* | awk '{ print $NF }'`
;;
*) # it does
logs="$*"
;;
esac
read_link() {
case "$test_L" in
"") 'ls' -ld $1 | awk '{ print $NF }'; return;;
esac
if test $test_L $1; then
'ls' -ld $1 | sed 's,.*> ,,'
else
echo $1
fi
}
# create the new log
new_log() {
log=$1
mode=$2
if test "x$opt_M" != x; then
$ECHO chmod $opt_M $log.0 2> /dev/null
fi
# someone may have managed to write to it already
# so don't truncate it.
case "$opt_d" in
-d) $ECHO mkdir -p $log;;
*) $ECHO touch $log;;
esac
# the order here matters
test "x$opt_o" = x || $ECHO chown $opt_o $log
test "x$opt_g" = x || $ECHO chgrp $opt_g $log
test "x$mode" = x || $ECHO chmod $mode $log
}
rotate_log() {
log=$1
n=${2:-$opt_n}
# make sure excess generations are trimmed
$ECHO rm $rm_f `echo $log.$n | sed 's/\([0-9]\)$/[\1-9]*/'`
mode=${opt_m:-`get_mode $log`}
while test $n -gt 0
do
p=`expr $n - 1`
if test -s $log.$p; then
$ECHO rm $rm_f $log.$p.*
$ECHO $opt_C $log.$p
if test "x$opt_M" != x; then
$ECHO chmod $opt_M $log.$p.* 2> /dev/null
fi
fi
for ext in $opt_E .gz .Z ""
do
test $opt_d $log.$p$ext || continue
$ECHO mv $log.$p$ext $log.$n$ext
done
n=$p
done
# leave $log.0 uncompressed incase some one still has it open.
$ECHO mv $log $log.0
new_log $log $mode
}
# unlike rotate_log we do not rotate files,
# but give each log a unique (but stable name).
# This avoids churn for folk who rsync things.
# We make log.0 a symlink to the most recent log
# so it can be found and compressed next time around.
save_log() {
log=$1
n=${2:-$opt_n}
fmt=$3
last=`read_link $log.0`
case "$last" in
$log.0) # should never happen
test -s $last && $ECHO mv $last $log.$$;;
$log.*)
$ECHO $opt_C $last
;;
*.*) $ECHO $opt_C `dirname $log`/$last
;;
esac
$ECHO rm -f $log.0
# remove excess logs - we rely on mtime!
$ECHO rm $rm_f `'ls' -1td $log.* 2> /dev/null | sed "1,${n}d"`
mode=${opt_m:-`get_mode $log`}
# this is our default suffix
opt_S=${opt_S:-`get_mtime_suffix $log $fmt`}
case "$fmt" in
""|$opt_f) suffix=$opt_S;;
*) suffix=`get_mtime_suffix $log $fmt`;;
esac
# find a unique name to save current log as
for nlog in $log.$suffix $log.$suffix.$$
do
for f in $nlog*
do
break
done
test $opt_d $f || break
done
# leave $log.0 uncompressed incase some one still has it open.
$ECHO mv $log $nlog
test "x$opt_M" = x || $ECHO chmod $opt_M $nlog 2> /dev/null
$ECHO ln -s `basename $nlog` $log.0
new_log $log $mode
}
for f in $logs
do
n=$opt_n
save=
case "$f" in
*:[1-9]*)
set -- `IFS=:; echo $f`; f=$1; n=$2;;
*:n=*|*:save=*)
eval `echo "f=$f" | tr ':' ' '`;;
esac
# try and pick the right function to use
rfunc=$rotate_func # default
if test $opt_d $f.0; then
case `read_link $f.0` in
$f.0) rfunc=rotate_log;;
*) rfunc=save_log;;
esac
fi
case "$test_L" in
-?)
while test $test_L $f # it is [still] a symlink
do
f=`read_link $f`
done
;;
esac
case ",${opt_G}," in
*,${f}:n=*|,${f}:save=*)
eval `echo ",${opt_G}," | sed "s!.*,${f}:\([^,]*\),.*!\1!;s,:, ,g"`
;;
*,${f}:*)
# opt_G is a , separated list of log:n pairs
n=`echo ,$opt_G, | sed -e "s,.*${f}:\([0-9][0-9]*\).*,\1,"`
;;
esac
if empty $f; then
test "$force" || continue
fi
test "$save" && rfunc=save_log
$rfunc $f $n $save
done