xref: /illumos-gate/usr/src/cmd/logadm/tester (revision 43449cdcd0600512dd862537f2cf014140dd0844)
1#!/usr/bin/perl -w
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22#
23# Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
24# Copyright 2019 Joyent, Inc.
25#
26#
27# tester - run logadm tests
28#
29# requires a <bindir> argument to say where the various logadm
30# binaries live (conftest, globtest, kwtest, luttest, optstest, and
31# logadm itself).
32#
33# to run all the tests:
34#	tester [-f] <bindir>
35#
36# to run just a few tests, given their names:
37#	tester [-f] <bindir> globtest1 luttest1
38#
39# to setup a test and stop so you can run it by hand:
40#	tester [-f] -s globtest1 <bindir>
41#
42#	tester will tell you what tmp directory it created for
43#	the test.  to run it, cd there and run:
44#		sh runtest
45#	to check the results, run:
46#		sh checktest
47#
48# -f means "fast" -- without it, watchmalloc(3MALLOC) is setup for
49# each test and they run a zillion times slower and produce core
50# dumps when malloc/free problems are detected.
51#
52$watchmalloc=1;		# default is to use watchmalloc
53${ENV} = "/bin";
54umask 002;
55
56# list of tests we run by default
57@tests = (
58	"conftest1",
59	"conftest2",
60	"globtest1",
61	"globtest2",
62	"kwtest1",
63	"kwtest2",
64	"luttest1",
65	"optstest1",
66	"optstest2",
67	"logadmV1",
68	"logadmV2",
69	"logadmr",
70	"logadmw",
71	"logadm1",
72	"logadm1c",
73	"logadm2",
74	"logadm3",
75	"logadm4",
76	"logadm5",
77	"logadm6",
78	"logadm7",
79	"logadm8",
80	"logadm9",
81	"logadm9d",
82	"logadm10",
83	"logadm11",
84	"logadm12",
85	"logadm13",
86	"logadm14",
87	"logadm15",
88	"logadm16",
89	"logadm17",
90	"logadm18",
91	"logadm19",
92	"logadm20",
93	"logadm21",
94	"logadm22",
95	"logadm23",
96	"stderr1"
97);
98
99use Getopt::Std;
100use File::Find;
101
102$usage_summary = '[-s test-name] [-d dir] bindir [test-name...]';
103$usage_getopts = 'fd:s:';
104%usage = (
105	d=>'use dir for tests rather than creating one in /tmp',
106	s=>'setup only, do not run test');
107
108# spew usage message, plus any given message, and exit
109sub usage {
110	my $msg = shift;
111
112	if ($msg) {
113		chomp $msg;
114		warn "$0: $msg\n" if $msg;
115	}
116	warn "Usage: $0 $usage_summary\n";
117	foreach (sort keys %usage) {
118		warn "       -$_ $usage{$_}\n";
119	}
120	exit 1;
121}
122
123#
124# basic argument processing
125#
126$myname = $0;
127$myname =~ s/.*\///;	# just show last component in error mesages
128getopts($usage_getopts) or usage;
129$bindir = shift or usage;
130usage("$bindir does not exist") unless -d $bindir;
131usage("cannot list more than one test with -s option") if $opt_s && @ARGV;
132@tests = @ARGV if @ARGV;
133print "Fast mode\n" if $opt_f;
134$watchmalloc = 0 if $opt_f;
135
136$mydir=`pwd`;
137chomp $mydir;
138
139$dir = $opt_d;
140$dir = "/tmp/logadmtest$$" unless $dir = $opt_d;
141
142if (!-d $dir) {
143	mkdir $dir, 0777 or die "$myname: mkdir $dir: $!\n";
144	$needrmdir = 1;
145}
146
147chdir $dir or die "$myname: $dir: $!\n";
148
149# common commands in runtest by tests
150if ($watchmalloc) {
151	$envsetup =
152		"HOME=$dir export HOME; " .
153		"LD_PRELOAD=watchmalloc.so.1 export LD_PRELOAD; " .
154		"MALLOC_DEBUG=RW export MALLOC_DEBUG";
155} else {
156	$envsetup = "HOME=$dir export HOME; ";
157}
158
159$| = 1;		# a.k.a. setbuf(stdout, NULL)
160
161if ($opt_s) {
162	#
163	# just setup the test, explain how to use it, and exit
164	#
165	$testname = $opt_s;
166	eval "&$opt_s";
167	die "$myname: ERROR: $@" if $@;
168	print "$myname: $testname setup complete, to run, cd to:\n";
169	print "    $dir\n";
170	print "and run the command:\n";
171	print "    sh runtest\n";
172	print "to check the results, run the command:\n";
173	print "    sh checktest\n";
174	exit 0;
175} else {
176	#
177	# run all the tests
178	#
179	foreach (@tests) {
180		$testname = $_;
181		print "Running $testname...";
182		eval "&$_";
183		if ($@) {
184			print " SETUP FAILURE\n";
185			print STDERR "$myname: ERROR: $@";
186			exit 1;
187		}
188		eval "runner('runtest')";
189		if ($@) {
190			print " RUNTEST FAILURE\n";
191			print STDERR "$myname: ERROR: $@";
192			print STDERR "results captured in directory $dir\n";
193			print STDERR "  or use: $myname -s $testname $bindir\n";
194			print STDERR "  to do a fresh setup of this test.\n";
195			exit 1;
196		}
197		eval "runner('checktest', '-x', '> checktest.out 2>&1')";
198		if ($@) {
199			print " CHECKTEST FAILURE\n";
200			print STDERR "$myname: ERROR: $@";
201			print STDERR "results captured in file $dir/checktest.out\n";
202			print STDERR "  or use: $myname -s $testname $bindir\n";
203			print STDERR "  to do a fresh setup of this test.\n";
204			exit 1;
205		}
206		print "pass\n";
207		# sanity...
208		die "unexpected dir $dir" unless $dir =~ m,/.+/,;
209		system("/bin/rm -rf $dir/*");
210	}
211}
212
213# if we were the ones who created $dir, remove it
214if ($needrmdir) {
215	chdir $mydir;
216	rmdir $dir || die "$myname: rmdir $dir: $!\n";
217}
218
219exit 0;
220
221#
222# run a shell script and check for failure
223#
224# the shell scripts generated by this program always "exec" the binary
225# under test so checking here are for exit code, signals, and core dump
226# is actually checking the program under test and not /bin/sh
227#
228sub runner {
229	my ($cmd, $prefix, $suffix) = (@_, '', '');
230
231	my $fullcmd = "/bin/sh $prefix $cmd $suffix";
232	my $rc = 0xffff & system("$fullcmd");
233
234	if ($rc == 0) {
235		return;		# cmd completed normally
236	} elsif ($rc == 0xff00) {
237		die "command \"$cmd\" failed: $!\n";
238	} elsif (($rc & 0xff) == 0) {
239		$rc >>= 8;
240		die "command \"$cmd\" exit $rc\n";
241	} else {
242		my $coremsg;
243		$coremsg = " (core dumped)" if ($rc & 0x80);
244		$rc &= ~0x80;
245		die "command \"$cmd\" signal $rc$coremsg\n" ;
246	}
247}
248
249#
250# set_file(filename [, contents]) -- create a file, optionally with contents
251#
252sub set_file {
253	my $file = shift;
254	my $contents = shift;
255
256	open SF, ">$file" or die "create \"$file\": $!\n";
257	print SF $contents if defined($contents);
258	close SF;
259}
260
261#############
262#############
263#############    THE TESTS START AFTER HERE...
264#############
265#############
266
267# common setup step -- create a testfile.conf
268sub set_testconffile {
269	my $fname = shift;
270	$fname = 'testfile.conf' unless defined($fname);
271
272	set_file($fname, <<'EOF');
273#
274# logadm.conf
275#
276# Default settings for system log file management.
277# The -w option to logadm(1M) is the preferred way to write to this file,
278# but if you do edit it by hand, use "logadm -V" to check it for errors.
279#
280# The format of lines in this file is:
281#       <logname> <options>
282# For each logname listed here, the default options to logadm
283# are given.  Options given on the logadm command line override
284# the defaults contained in this file.
285#
286# logadm typically runs early every morning via an entry in
287# root's crontab (see crontab(1)).
288#
289/var/adm/messages -C 4 -P 'Thu Nov  1 16:56:42 2001' -a 'kill -HUP `cat /var/run/*syslog*pid`'
290/var/cron/log -s 512k -t /var/cron/olog
291/var/lp/logs/lpsched -C 2 -N -t '$file.$N'
292#
293# The entry below is used by turnacct(1M)
294#
295/var/adm/pacct -C 0 -a '/usr/lib/acct/accton pacct' -g adm -m 664 -o adm -p never
296apache -C 24 -a '/usr/apache/bin/apachectl graceful' -p 1m -t '/var/apache/old-logs/$basename.%Y-%m' '/var/apache/logs/*{access,error}_log'
297/var/log/syslog -C 8 -P 'Thu Nov  1 09:16:38 2001' -a 'kill -HUP `cat /var/run/*syslog*pid`'
298/var/apache/logs/access_log -P 'Thu Nov  1 08:27:56 2001'
299/var/apache/logs/error_log -P 'Thu Nov  1 08:27:56 2001'
300/var/apache/logs/suexec_log -P 'Thu Nov  1 08:27:56 2001'
301/var/apache/logs/mod_jserv.log -P 'Thu Nov  1 08:27:56 2001'
302/var/apache/logs/jserv.log -P 'Thu Nov  1 08:27:56 2001'
303EOF
304}
305
306
307###########################################################################
308#
309#	conftest1 -- minimal basic test of the conf.c code
310#
311###########################################################################
312sub conftest1 {
313	set_testconffile;
314
315	set_file('checktest', <<'EOF');
316[ -s std.err ] && { cat std.err; exit 1; }
317/bin/sed '/^conffile <testfile.conf>:$/d' <std.out >sed.out
318exec /bin/diff testfile.conf sed.out
319EOF
320
321	set_file('runtest', <<"EOF");
322# test "conftest1"
323$envsetup
324exec $bindir/conftest testfile.conf >std.out 2>std.err
325EOF
326}
327
328###########################################################################
329#
330#	conftest2 -- error path through conf.c
331#
332###########################################################################
333sub conftest2 {
334	set_file('testfile.conf', 'line fragment');
335
336	set_file('std.err.expect', <<'EOF');
337conftest: Warning: file testfile.conf doesn't end with newline, last line ignored.
338EOF
339
340	set_file('checktest', <<'EOF');
341exec /bin/diff std.err.expect std.err
342EOF
343
344	set_file('runtest', <<"EOF");
345# test "conftest2"
346$envsetup
347$bindir/conftest testfile.conf >std.out 2>std.err || exit 0
348exit 1
349EOF
350}
351
352###########################################################################
353#
354#	globtest1 -- minimal basic test of the glob.c code
355#
356###########################################################################
357sub globtest1 {
358	set_file('fileBname12');
359	sleep 2;	# ensure above name is odler than below name
360	set_file('fileAname12');
361	set_file('fileAname1');
362	set_file('fileAname3');
363	set_file('fileAname5');
364	set_file('fileAname7');
365	set_file('fileAname9');
366	set_file('fileAname11');
367	set_file('fileBname0');
368	set_file('fileBname2');
369	set_file('fileBname4');
370	set_file('fileBname6');
371	set_file('fileBname8');
372	set_file('fileBname10');
373	mkdir 'dir1', 0777 or die "mkdir dir1: $!\n";
374	mkdir 'dir2', 0777 or die "mkdir dir2: $!\n";
375	mkdir 'dir3', 0777 or die "mkdir dir3: $!\n";
376	mkdir 'dir1/dirA', 0777 or die "mkdir dir1/dirA: $!\n";
377	mkdir 'dir1/dirB', 0777 or die "mkdir dir1/dirB: $!\n";
378	mkdir 'dir1/dirC', 0777 or die "mkdir dir1/dirC: $!\n";
379	mkdir 'dir2/dirA', 0777 or die "mkdir dir2/dirA: $!\n";
380	mkdir 'dir2/dirB', 0777 or die "mkdir dir2/dirB: $!\n";
381	mkdir 'dir2/dirC', 0777 or die "mkdir dir2/dirC: $!\n";
382	set_file('dir1/fileAname1');
383	set_file('dir1/fileAname2');
384	set_file('dir1/fileAname3');
385	set_file('dir1/fileAname4');
386	set_file('dir1/fileAname5');
387	set_file('dir1/fileBname1');
388	set_file('dir1/fileBname2');
389	set_file('dir1/fileBname3');
390	set_file('dir1/fileBname4');
391	set_file('dir1/fileBname5');
392	# supply some varying sizes to produce different total size values
393	set_file('dir1/dirA/fileAname4', '4444');
394	sleep 2;	# ensure above file is oldest in dirA
395	set_file('dir1/dirA/fileAname1', '1');
396	set_file('dir1/dirA/fileAname2', '22');
397	set_file('dir1/dirA/fileAname3', '333');
398	set_file('dir1/dirA/fileAname5', '55555');
399	set_file('dir1/dirA/fileBname1', '1');
400	set_file('dir1/dirA/fileBname2', '22');
401	set_file('dir1/dirA/fileBname3', '333');
402	set_file('dir1/dirA/fileBname4', '4444');
403	set_file('dir1/dirA/fileBname5', '55555');
404	set_file('dir1/dirB/fileAname1', '1');
405	set_file('dir1/dirB/fileAname2', '22');
406	set_file('dir1/dirB/fileAname3', '333');
407	set_file('dir1/dirB/fileAname4', '4444');
408	set_file('dir1/dirB/fileAname5', '55555');
409	set_file('dir1/dirB/fileBname1', '1');
410	set_file('dir1/dirB/fileBname2', '22');
411	set_file('dir1/dirB/fileBname3', '333');
412	set_file('dir1/dirB/fileBname4', '4444');
413	set_file('dir1/dirB/fileBname5', '55555');
414	set_file('dir1/dirC/fileAname10', '12345678901');
415	set_file('dir1/dirC/fileAname20', '123456789022');
416	set_file('dir1/dirC/fileAname30', '1234567890333');
417	set_file('dir1/dirC/fileAname40', '12345678904444');
418	set_file('dir1/dirC/fileAname50', '123456789055555');
419	set_file('dir1/dirC/fileBname10', '12345678901');
420	set_file('dir1/dirC/fileBname20', '123456789022');
421	set_file('dir1/dirC/fileBname30', '1234567890333');
422	set_file('dir1/dirC/fileBname40', '12345678904444');
423	set_file('dir1/dirC/fileBname50', '123456789055555');
424
425	set_file('std.out.expect', <<'EOF');
426<file{A,B,C}name*>:
427    <./fileAname12>
428    <./fileAname1>
429    <./fileAname3>
430    <./fileAname5>
431    <./fileAname7>
432    <./fileAname9>
433    <./fileAname11>
434    <./fileBname12>
435    <./fileBname0>
436    <./fileBname2>
437    <./fileBname4>
438    <./fileBname6>
439    <./fileBname8>
440    <./fileBname10>
441total size: 0
442    oldest <./fileBname12>
443    oldest <./fileBname8>
444    oldest <./fileBname6>
445    oldest <./fileBname4>
446    oldest <./fileBname2>
447    oldest <./fileBname10>
448    oldest <./fileBname0>
449    oldest <./fileAname9>
450    oldest <./fileAname7>
451    oldest <./fileAname5>
452    oldest <./fileAname3>
453    oldest <./fileAname12>
454    oldest <./fileAname11>
455    oldest <./fileAname1>
456<file{A,B,C}name>:
457    <fileAname>
458    <fileBname>
459    <fileCname>
460total size: 0
461    oldest <fileCname>
462    oldest <fileBname>
463    oldest <fileAname>
464<dir1/dirA/file*>:
465    <./dir1/dirA/fileAname4>
466    <./dir1/dirA/fileAname1>
467    <./dir1/dirA/fileAname2>
468    <./dir1/dirA/fileAname3>
469    <./dir1/dirA/fileAname5>
470    <./dir1/dirA/fileBname1>
471    <./dir1/dirA/fileBname2>
472    <./dir1/dirA/fileBname3>
473    <./dir1/dirA/fileBname4>
474    <./dir1/dirA/fileBname5>
475total size: 30
476    oldest <./dir1/dirA/fileAname4>
477    oldest <./dir1/dirA/fileBname5>
478    oldest <./dir1/dirA/fileBname4>
479    oldest <./dir1/dirA/fileBname3>
480    oldest <./dir1/dirA/fileBname2>
481    oldest <./dir1/dirA/fileBname1>
482    oldest <./dir1/dirA/fileAname5>
483    oldest <./dir1/dirA/fileAname3>
484    oldest <./dir1/dirA/fileAname2>
485    oldest <./dir1/dirA/fileAname1>
486<dir[13]/[e-z]*>:
487    <./dir1/fileAname1>
488    <./dir1/fileAname2>
489    <./dir1/fileAname3>
490    <./dir1/fileAname4>
491    <./dir1/fileAname5>
492    <./dir1/fileBname1>
493    <./dir1/fileBname2>
494    <./dir1/fileBname3>
495    <./dir1/fileBname4>
496    <./dir1/fileBname5>
497total size: 0
498    oldest <./dir1/fileBname5>
499    oldest <./dir1/fileBname4>
500    oldest <./dir1/fileBname3>
501    oldest <./dir1/fileBname2>
502    oldest <./dir1/fileBname1>
503    oldest <./dir1/fileAname5>
504    oldest <./dir1/fileAname4>
505    oldest <./dir1/fileAname3>
506    oldest <./dir1/fileAname2>
507    oldest <./dir1/fileAname1>
508<dir?/dir[AC]/fileBname[2-9]>:
509    <./dir1/dirA/fileBname2>
510    <./dir1/dirA/fileBname3>
511    <./dir1/dirA/fileBname4>
512    <./dir1/dirA/fileBname5>
513total size: 14
514    oldest <./dir1/dirA/fileBname5>
515    oldest <./dir1/dirA/fileBname4>
516    oldest <./dir1/dirA/fileBname3>
517    oldest <./dir1/dirA/fileBname2>
518<file[A-Z]n.*e([0-9]+)$0>:
519    <./fileBname12>
520    <./fileAname12>
521    <./fileAname1>
522    <./fileAname3>
523    <./fileAname5>
524    <./fileAname7>
525    <./fileAname9>
526    <./fileAname11>
527    <./fileBname0>
528    <./fileBname2>
529    <./fileBname4>
530    <./fileBname6>
531    <./fileBname8>
532    <./fileBname10>
533total size: 0
534    oldest <./fileBname12>
535    oldest <./fileAname12>
536    oldest <./fileAname11>
537    oldest <./fileBname10>
538    oldest <./fileAname9>
539    oldest <./fileBname8>
540    oldest <./fileAname7>
541    oldest <./fileBname6>
542    oldest <./fileAname5>
543    oldest <./fileBname4>
544    oldest <./fileAname3>
545    oldest <./fileBname2>
546    oldest <./fileAname1>
547    oldest <./fileBname0>
548EOF
549
550	set_file('checktest', <<'EOF');
551[ -s std.err ] && { cat std.err; exit 1; }
552exec /bin/diff std.out.expect std.out
553EOF
554
555	$testglobs='\'file{A,B,C}name*\' \'file{A,B,C}name\' \'dir1/dirA/file*\' \'dir[13]/[e-z]*\' \'dir?/dir[AC]/fileBname[2-9]\' -r \'file[A-Z]n.*e([0-9]+)$0\'';
556
557	set_file('runtest', <<"EOF");
558# test "globtest1"
559$envsetup
560exec $bindir/globtest $testglobs >std.out 2>std.err
561EOF
562}
563
564###########################################################################
565#
566#	globtest2 -- error path through glob.c
567#
568###########################################################################
569sub globtest2 {
570	set_file('std.err.expect', <<'EOF');
571globtest: Error: Missing }
572EOF
573
574	set_file('checktest', <<'EOF');
575exec /bin/diff std.err.expect std.err
576EOF
577
578	set_file('runtest', <<"EOF");
579# test "globtest2"
580$envsetup
581$bindir/globtest 'hello{there' >std.out 2>std.err || exit 0
582exit 1
583EOF
584}
585
586###########################################################################
587#
588#	kwtest1 -- minimal basic test of the kw.c code
589#
590###########################################################################
591sub kwtest1 {
592	$domainname = `/bin/domainname`; chomp $domainname;
593	$isa = `/bin/uname -p`; chomp $isa;
594	$platform = `/bin/uname -i`; chomp $platform;
595	$nodename = `/bin/uname -n`; chomp $nodename;
596	$machine = `/bin/uname -m`; chomp $machine;
597	$release = `/bin/uname -r`; chomp $release;
598	# /bin/zonename is in SUNWzoneu and so may not be present
599	if (-f "/bin/zonename") {
600		$zonename = `/bin/zonename`; chomp $zonename;
601	} else {
602		$zonename = "global";
603	}
604$secondblob=<<'EOF';
605expand<$file.$n> n -1 hasn 1 result </var/log/syslog\.([0-9]+)$0>
606expand<$file.$n> n 0 hasn 1 result </var/log/syslog.0>
607expand<$file.$n> n 1 hasn 1 result </var/log/syslog.1>
608expand<moose%d.$n> n -1 hasn 1 result <moose[0-9]+\.([0-9]+)$0>
609expand<moose%d.$n> n 0 hasn 1 result <moose%d.0>
610expand<moose%d.$n> n 1 hasn 1 result <moose%d.1>
611expand</var/logs-%Y/moose-$isa$#porklips%d.$n> n -1 hasn 1 result </var/logs-[0-9]+/moose-ISAporklips[0-9]+\.([0-9]+)$0>
612expand</var/logs-%Y/moose-$isa$#porklips%d.$n> n 0 hasn 1 result </var/logs-%Y/moose-ISAporklips%d.0>
613expand</var/logs-%Y/moose-$isa$#porklips%d.$n> n 1 hasn 1 result </var/logs-%Y/moose-ISAporklips%d.1>
614EOF
615	$percentd = `/bin/env TZ=UTC /bin/date +%d`; chomp $percentd;
616	$percentY = `/bin/env TZ=UTC /bin/date +%Y`; chomp $percentY;
617	$secondblob =~ s/%d/$percentd/mg;
618	$secondblob =~ s/%Y/$percentY/mg;
619	$secondblob =~ s/ISA/$isa/mg;
620	$utcenv = "TZ=UTC export TZ";
621	chomp $secondblob;
622	set_file('sed.out.expect', <<"EOF");
623            basename syslog
624             dirname /var/log
625              domain $domainname
626                file /var/log/syslog
627                home $dir
628                 isa $isa
629             logname $ENV{LOGNAME}
630             machine $machine
631               nfile
632            nodename $nodename
633            platform $platform
634             release $release
635                user $ENV{USER}
636            zonename $zonename
637$secondblob
638EOF
639
640	set_file('checktest', <<'EOF');
641[ -s std.err ] && { cat std.err; exit 1; }
642/bin/sed -e '/^ *secs [0-9][0-9]*$/d'\
643	-e "s/%d/`/bin/env TZ=UTC /bin/date +%d`/g"\
644	-e "s/%Y/`/bin/env TZ=UTC /bin/date +%Y`/g"\
645	<std.out >sed.out
646exec /bin/diff sed.out.expect sed.out
647EOF
648
649	$kwtest='kwtest /var/log/syslog \'$file.$n\' \'moose%d.$n\' \'/var/logs-%Y/moose-$isa$#porklips%d.$n\'';
650	set_file('runtest', <<"EOF");
651# test "kwtest1"
652$envsetup
653$utcenv
654exec $bindir/$kwtest >std.out 2>std.err
655EOF
656}
657
658###########################################################################
659#
660#	kwtest2 -- NULL environment variables test of the kw.c code
661#
662###########################################################################
663sub kwtest2 {
664	$domainname = `/bin/domainname`; chomp $domainname;
665	$isa = `/bin/uname -p`; chomp $isa;
666	$platform = `/bin/uname -i`; chomp $platform;
667	$nodename = `/bin/uname -n`; chomp $nodename;
668	$machine = `/bin/uname -m`; chomp $machine;
669	$release = `/bin/uname -r`; chomp $release;
670	# /bin/zonename is in SUNWzoneu and so may not be present
671	if (-f "/bin/zonename") {
672		$zonename = `/bin/zonename`; chomp $zonename;
673	} else {
674		$zonename = "global";
675	}
676$secondblob=<<'EOF';
677expand<$file.$n> n -1 hasn 1 result </var/log/syslog\.([0-9]+)$0>
678expand<$file.$n> n 0 hasn 1 result </var/log/syslog.0>
679expand<$file.$n> n 1 hasn 1 result </var/log/syslog.1>
680expand<moose%d.$n> n -1 hasn 1 result <moose[0-9]+\.([0-9]+)$0>
681expand<moose%d.$n> n 0 hasn 1 result <moose%d.0>
682expand<moose%d.$n> n 1 hasn 1 result <moose%d.1>
683expand</var/logs-%Y/moose-$isa$#porklips%d.$n> n -1 hasn 1 result </var/logs-[0-9]+/moose-ISAporklips[0-9]+\.([0-9]+)$0>
684expand</var/logs-%Y/moose-$isa$#porklips%d.$n> n 0 hasn 1 result </var/logs-%Y/moose-ISAporklips%d.0>
685expand</var/logs-%Y/moose-$isa$#porklips%d.$n> n 1 hasn 1 result </var/logs-%Y/moose-ISAporklips%d.1>
686EOF
687	$percentd = `/bin/env TZ=UTC /bin/date +%d`; chomp $percentd;
688	$percentY = `/bin/env TZ=UTC /bin/date +%Y`; chomp $percentY;
689	$secondblob =~ s/%d/$percentd/mg;
690	$secondblob =~ s/%Y/$percentY/mg;
691	$secondblob =~ s/ISA/$isa/mg;
692	chomp $secondblob;
693	set_file('sed.out.expect', <<"EOF");
694            basename syslog
695             dirname /var/log
696              domain $domainname
697                file /var/log/syslog
698                home
699                 isa $isa
700             logname
701             machine $machine
702               nfile
703            nodename $nodename
704            platform $platform
705             release $release
706                user
707            zonename $zonename
708$secondblob
709EOF
710
711	set_file('checktest', <<'EOF');
712[ -s std.err ] && { cat std.err; exit 1; }
713/bin/sed -e '/^ *secs [0-9][0-9]*$/d'\
714	-e "s/%d/`/bin/env TZ=UTC /bin/date +%d`/g"\
715	-e "s/%Y/`/bin/env TZ=UTC /bin/date +%Y`/g"\
716	<std.out >sed.out
717exec /bin/diff sed.out.expect sed.out
718EOF
719
720	$kwtest='kwtest /var/log/syslog \'$file.$n\' \'moose%d.$n\' \'/var/logs-%Y/moose-$isa$#porklips%d.$n\'';
721	set_file('runtest', <<"EOF");
722# test "kwtest2"
723$envsetup
724LOGNAME=
725export LOGNAME
726HOME=
727export HOME
728USER=
729export USER
730TZ=UTC
731export TZ
732exec $bindir/$kwtest >std.out 2>std.err
733EOF
734}
735
736###########################################################################
737#
738#	luttest1 -- minimal basic test of the lut.c code
739#
740###########################################################################
741sub luttest1 {
742	set_file('std.out.expect', <<'EOF');
743lut contains:
744<fix> <NULL> (<NULL>)
745<one> <two> (<two>)
746<seven> <eight> (<eight>)
747<six> <NULL> (<NULL>)
748<three> <four> (<four>)
749dup lut contains:
750<fix> <NULL> (<NULL>)
751<one> <two> (<two>)
752<seven> <eight> (<eight>)
753<six> <NULL> (<NULL>)
754<three> <four> (<four>)
755EOF
756
757	set_file('checktest', <<'EOF');
758[ -s std.err ] && { cat std.err; exit 1; }
759exec /bin/diff std.out.expect std.out
760EOF
761
762	set_file('runtest', <<"EOF");
763# test "luttest1"
764$envsetup
765exec $bindir/luttest one=two three=four fix six seven=eight >std.out 2>std.err
766EOF
767}
768
769###########################################################################
770#
771#	optstest1 -- minimal basic test of the opts.c code
772#
773###########################################################################
774sub optstest1 {
775	$options="-a -b moose -c 1h -d 'Fri Nov  2 13:19:55 2001' -e 1k -f 2 one two three";
776	set_file('std.out.expect', <<"EOF");
777options: $options
778EOF
779
780	set_file('checktest', <<'EOF');
781[ -s std.err ] && { cat std.err; exit 1; }
782exec /bin/diff std.out.expect std.out
783EOF
784
785	set_file('runtest', <<"EOF");
786# test "optstest1"
787$envsetup
788exec $bindir/optstest $options >std.out 2>std.err
789EOF
790}
791
792###########################################################################
793#
794#	optstest2 -- error path through opts.c code
795#
796###########################################################################
797sub optstest2 {
798	$options="-a -b -c 1h -d 'Fri Nov  2 13:19:55 2001' -e 1k -f 2 one two three";
799	set_file('std.err.expect', <<'EOF');
800optstest: Error: Option 'b' requires an argument
801optstest: Error: opts parsing failed
802EOF
803
804	set_file('checktest', <<'EOF');
805[ -s std.out ] && exit 1
806exec /bin/diff std.err.expect std.err
807EOF
808
809	set_file('runtest', <<"EOF");
810# test "optstest2"
811$envsetup
812$bindir/optstest $options >std.out 2>std.err || exit 0
813exit 1
814EOF
815}
816
817###########################################################################
818#
819#	logadmV1 -- test of "logadm -V"
820#
821###########################################################################
822sub logadmV1 {
823	set_testconffile;
824
825	set_file('std.out.expect', <<'EOF');
826/var/adm/messages -C 4 -P 'Thu Nov  1 16:56:42 2001' -a 'kill -HUP `cat /var/run/*syslog*pid`'
827/var/cron/log -s 512k -t /var/cron/olog
828/var/lp/logs/lpsched -C 2 -N -t '$file.$N'
829/var/adm/pacct -C 0 -a '/usr/lib/acct/accton pacct' -g adm -m 664 -o adm -p never
830apache -C 24 -a '/usr/apache/bin/apachectl graceful' -p 1m -t '/var/apache/old-logs/$basename.%Y-%m' '/var/apache/logs/*{access,error}_log'
831/var/log/syslog -C 8 -P 'Thu Nov  1 09:16:38 2001' -a 'kill -HUP `cat /var/run/*syslog*pid`'
832/var/apache/logs/access_log -P 'Thu Nov  1 08:27:56 2001'
833/var/apache/logs/error_log -P 'Thu Nov  1 08:27:56 2001'
834/var/apache/logs/suexec_log -P 'Thu Nov  1 08:27:56 2001'
835/var/apache/logs/mod_jserv.log -P 'Thu Nov  1 08:27:56 2001'
836/var/apache/logs/jserv.log -P 'Thu Nov  1 08:27:56 2001'
837EOF
838
839	set_file('checktest', <<'EOF');
840[ -s std.err ] && { cat std.err; exit 1; }
841exec /bin/diff std.out.expect std.out
842EOF
843
844	set_file('runtest', <<"EOF");
845# test "logadmV1"
846$envsetup
847exec $bindir/logadm -f testfile.conf -F testfile.conf -V >std.out 2>std.err
848EOF
849}
850
851###########################################################################
852#
853#	logadmV2 -- test of "logadm -V <entry>"
854#
855###########################################################################
856sub logadmV2 {
857	set_testconffile;
858
859	set_file('std.out.expect', <<'EOF');
860/var/cron/log -s 512k -t /var/cron/olog
861/var/adm/pacct -C 0 -a '/usr/lib/acct/accton pacct' -g adm -m 664 -o adm -p never
862EOF
863
864	set_file('checktest', <<'EOF');
865[ -s std.err ] && { cat std.err; exit 1; }
866exec /bin/diff std.out.expect std.out
867EOF
868
869	set_file('runtest', <<"EOF");
870# test "logadmV2"
871$envsetup
872exec $bindir/logadm -f testfile.conf -F testfile.conf -V /var/cron/log /var/adm/pacct >std.out 2>std.err
873EOF
874}
875
876###########################################################################
877#
878#	logadmr -- test of "logadm -r <entry>"
879#
880###########################################################################
881sub logadmr {
882	set_testconffile;
883	set_testconffile('testfile.conf.orig');
884
885	set_file('diff.out.expect', <<'EOF');
88618d17
887< /var/cron/log -s 512k -t /var/cron/olog
88823d21
889< /var/adm/pacct -C 0 -a '/usr/lib/acct/accton pacct' -g adm -m 664 -o adm -p never
890EOF
891
892	set_file('checktest', <<'EOF');
893[ -s std.err ] && { cat std.err; exit 1; }
894/bin/diff testfile.conf.orig testfile.conf > diff.out
895exec /bin/diff diff.out.expect diff.out
896EOF
897
898	set_file('runtest', <<"EOF");
899# test "logadmr"
900$envsetup
901exec $bindir/logadm -f testfile.conf -F testfile.conf -r /var/cron/log /var/adm/pacct >std.out 2>std.err
902EOF
903}
904
905###########################################################################
906#
907#	logadmw -- test of "logadm -w <entry>"
908#
909###########################################################################
910sub logadmw {
911	set_testconffile;
912	set_testconffile('testfile.conf.orig');
913
914	set_file('diff.out.expect', <<'EOF');
91530a31
916> moose -C 20 -a moose_after_cmd -g pig -m 664 -o cow -p never /moose/file
917EOF
918
919	set_file('checktest', <<'EOF');
920[ -s std.err ] && { cat std.err; exit 1; }
921/bin/diff testfile.conf.orig testfile.conf > diff.out
922exec /bin/diff diff.out.expect diff.out
923EOF
924
925	set_file('runtest', <<"EOF");
926# test "logadmw"
927$envsetup
928exec $bindir/logadm -f testfile.conf -F testfile.conf -w moose -C 20 -a moose_after_cmd -g pig -m 664 -o cow -p never /moose/file >std.out 2>std.err
929EOF
930}
931
932###########################################################################
933#
934#	logadm1 -- minimal basic test of logadm rotation
935#
936###########################################################################
937sub logadm1 {
938	set_file('logfile', 'initially logfile');
939	set_file('logfile.0', 'initially logfile.0');
940	my ($stdev, $stino, $stmode, $stnlink, $stuid, $stgid, $strdev,
941		$stsize, $statime, $stmtime, $stctime, $stblksize, $stblocks) =
942		lstat 'logfile' or die "lstat logfile: $!\n";
943
944	set_file('checktest', <<"EOF");
945[ -s std.err ] && { cat std.err; exit 1; }
946[ -s std.out ] && exit 1
947[ -s logfile ] && exit 1
948[ -f logfile.0 ] || exit 1
949[ "xinitially logfile" = "x`/bin/cat logfile.0`" ] || exit 1
950[ "`/bin/ls -i logfile.0 | /bin/awk '{ print \$1; }'`" = "$stino" ] || exit 1
951[ -f logfile.1 ] || exit 1
952[ "xinitially logfile.0" = "x`/bin/cat logfile.1`" ] || exit 1
953exit 0
954EOF
955
956	set_file('runtest', <<"EOF");
957# test "logadm1"
958$envsetup
959exec $bindir/logadm -f /dev/null -p now logfile >std.out 2>std.err
960EOF
961}
962
963###########################################################################
964#
965#	logadm1c -- same as logadm1 but with -c option
966#
967###########################################################################
968sub logadm1c {
969	set_file('logfile', 'initially logfile');
970	set_file('logfile.0', 'initially logfile.0');
971	my ($stdev, $stino, $stmode, $stnlink, $stuid, $stgid, $strdev,
972		$stsize, $statime, $stmtime, $stctime, $stblksize, $stblocks) =
973		lstat 'logfile' or die "lstat logfile: $!\n";
974
975	set_file('checktest', <<"EOF");
976[ -s std.err ] && { cat std.err; exit 1; }
977[ -s std.out ] && exit 1
978[ -s logfile ] && exit 1
979[ -f logfile.0 ] || exit 1
980[ "xinitially logfile" = "x`/bin/cat logfile.0`" ] || exit 1
981[ "`/bin/ls -i logfile.0 | /bin/awk '{ print \$1; }'`" = "$stino" ] && exit 1
982[ -f logfile.1 ] || exit 1
983[ "xinitially logfile.0" = "x`/bin/cat logfile.1`" ] || exit 1
984exit 0
985EOF
986
987	set_file('runtest', <<"EOF");
988# test "logadm1c"
989$envsetup
990exec $bindir/logadm -f /dev/null -p now -c logfile >std.out 2>std.err
991EOF
992}
993
994###########################################################################
995#
996#	logadm2 -- minimal basic test of logadm expiration
997#
998###########################################################################
999sub logadm2 {
1000	set_file('logfile', 'initially logfile');
1001	set_file('logfile.0', 'initially logfile.0');
1002	set_file('logfile.1', 'initially logfile.1');
1003
1004	set_file('checktest', <<'EOF');
1005[ -s std.err ] && { cat std.err; exit 1; }
1006[ -s std.out ] && exit 1
1007[ -s logfile ] && exit 1
1008[ -f logfile.0 ] || exit 1
1009[ "xinitially logfile" = "x`/bin/cat logfile.0`" ] || exit 1
1010[ -f logfile.1 ] || exit 1
1011[ "xinitially logfile.0" = "x`/bin/cat logfile.1`" ] || exit 1
1012[ -f logfile.2 ] && exit 1
1013exit 0
1014EOF
1015
1016	set_file('runtest', <<"EOF");
1017# test "logadm2"
1018$envsetup
1019exec $bindir/logadm -f /dev/null -p now logfile -C2 >std.out 2>std.err
1020EOF
1021}
1022
1023###########################################################################
1024#
1025#	logadm3 -- minimal basic test of logadm pre/post-commands
1026#
1027###########################################################################
1028sub logadm3 {
1029	set_file('logfile', 'initially logfile');
1030	set_file('logfile.0', 'initially logfile.0');
1031	set_file('logfile.1', 'initially logfile.1');
1032
1033	set_file('checktest', <<'EOF');
1034[ -s std.err ] && { cat std.err; exit 1; }
1035[ -s std.out ] && exit 1
1036[ -s logfile ] && exit 1
1037[ -f logfile.0 ] || exit 1
1038[ "xinitially logfile" = "x`/bin/cat logfile.0`" ] || exit 1
1039[ -f logfile.1 ] || exit 1
1040[ "xinitially logfile.0" = "x`/bin/cat logfile.1`" ] || exit 1
1041[ -f logfile.2 ] && exit 1
1042[ -f pre.out ] || exit 1
1043[ "xpre-command-stuff" = "x`/bin/cat pre.out`" ] || exit 1
1044[ -f post.out ] || exit 1
1045[ "xpost-command-stuff" = "x`/bin/cat post.out`" ] || exit 1
1046exit 0
1047EOF
1048
1049	set_file('runtest', <<"EOF");
1050# test "logadm3"
1051$envsetup
1052exec $bindir/logadm -f /dev/null -p now logfile -C2 -b 'echo pre-command-stuff > pre.out' -a 'echo post-command-stuff > post.out' >std.out 2>std.err
1053EOF
1054}
1055
1056###########################################################################
1057#
1058#	logadm4 -- test of -t template
1059#
1060###########################################################################
1061sub logadm4 {
1062	set_file('logfile', 'initially logfile');
1063
1064	set_file('checktest', <<'EOF');
1065[ -s std.err ] && { cat std.err; exit 1; }
1066[ -s std.out ] && exit 1
1067[ -s logfile ] && exit 1
1068TZ=UTC export TZ
1069d=`/bin/date +%d`
1070[ -f logfile.$d ] || exit 1
1071[ "xinitially logfile" = "x`/bin/cat logfile.$d`" ] || exit 1
1072exit 0
1073EOF
1074
1075	set_file('runtest', <<"EOF");
1076# test "logadm4"
1077$envsetup
1078exec $bindir/logadm -f /dev/null -p now logfile -t '\$file.\%d' >std.out 2>std.err
1079EOF
1080}
1081
1082###########################################################################
1083#
1084#	logadm5 -- test of -R cmd and -E cmd
1085#
1086###########################################################################
1087sub logadm5 {
1088	set_file('logfile', 'initially logfile');
1089	set_file('logfile.0', 'initially logfile.0');
1090
1091	set_file('cmd.out.expect', <<'EOF');
1092just rotated: initially logfile
1093just expired: initially logfile.0
1094EOF
1095
1096	set_file('checktest', <<'EOF');
1097[ -s std.err ] && { cat std.err; exit 1; }
1098[ -s std.out ] && exit 1
1099[ -s logfile ] && exit 1
1100[ -f logfile.0 ] || exit 1
1101[ "xinitially logfile" = "x`/bin/cat logfile.0`" ] || exit 1
1102[ -f logfile.1 ] || exit 1
1103[ "xinitially logfile.0" = "x`/bin/cat logfile.1`" ] || exit 1
1104exec /bin/diff cmd.out.expect cmd.out
1105EOF
1106
1107	set_file('runtest', <<"EOF");
1108# test "logadm5"
1109$envsetup
1110exec $bindir/logadm -f /dev/null -p now logfile -C1 -R 'echo just rotated: `/bin/cat \$file` >>cmd.out' -E 'echo just expired: `/bin/cat \$file` >>cmd.out' >std.out 2>std.err
1111EOF
1112}
1113
1114###########################################################################
1115#
1116#	logadm6 -- test of -m, -o, -g
1117#
1118###########################################################################
1119sub logadm6 {
1120        set_file('logfile', 'initially logfile');
1121
1122        set_file('std.err.expect', <<'EOF');
1123logadm: Warning: command failed: /bin/chown _nonexistentuser_:_nonexistentgroup_ logfile
1124chown: unknown group id _nonexistentgroup_
1125EOF
1126
1127        set_file('checktest', <<'EOF');
1128[ -s std.err ] || exit 1;
1129[ -s std.out ] && exit 1
1130[ -s logfile ] && exit 1
1131[ -f logfile.0 ] || exit 1
1132[ "xinitially logfile" = "x`/bin/cat logfile.0`" ] || exit 1
1133[ "`/bin/ls -l logfile | /bin/awk '{ print $1; }'`" = "-r----x--x" ] || exit 1
1134exec /bin/diff std.err.expect std.err
1135EOF
1136
1137        set_file('runtest', <<"EOF");
1138# test "logadm6"
1139$envsetup
1140exec $bindir/logadm -f /dev/null -p now logfile -m 411 -o _nonexistentuser_ -g _nonexistentgroup_ >std.out 2>std.err
1141EOF
1142}
1143
1144###########################################################################
1145#
1146#       logadm7 -- test running through a conffile
1147#
1148###########################################################################
1149sub logadm7 {
1150	mkdir 'dir1', 0777 or die "mkdir dir1: $!\n";
1151	set_file('dir1/syslog', 'initially dir1/syslog');
1152	set_file('dir1/syslog.0', 'initially dir1/syslog.0');
1153	set_file('dir1/syslog.1', 'initially dir1/syslog.1');
1154	set_file('dir1/syslog.2', 'initially dir1/syslog.2');
1155	set_file('dir1/syslog.3', 'initially dir1/syslog.3');
1156	set_file('dir1/syslog.4', 'initially dir1/syslog.4');
1157	set_file('dir1/syslog.5', 'initially dir1/syslog.5');
1158	set_file('dir1/syslog.6', 'initially dir1/syslog.6');
1159	set_file('dir1/syslog.7', 'initially dir1/syslog.7');
1160	mkdir 'dir2', 0777 or die "mkdir dir2: $!\n";
1161	set_file('dir2/messages', 'initially dir2/messages');
1162	set_file('dir2/messages.0', 'initially dir2/messages.0');
1163	set_file('dir2/messages.1', 'initially dir2/messages.1');
1164	set_file('dir2/messages.2', 'initially dir2/messages.2');
1165	set_file('dir2/messages.3', 'initially dir2/messages.3');
1166
1167	set_file('logadm.conf', <<'EOF');
1168#
1169# logadm.conf
1170#
1171#	this comment # has at least another #-sign in it #...
1172#
1173# Default settings for system log file management.
1174# The -w option to logadm(1M) is the preferred way to write to this file,
1175# but if you do edit it by hand, use "logadm -V" to check it for errors.
1176# but if you do edit it by hand, use "logadm -V" to check it for errors.
1177#
1178# The format of lines in this file is:
1179#       <logname> <options>
1180# For each logname listed here, the default options to logadm
1181# are given.  Options given on the logadm command line override
1182# the defaults contained in this file.
1183#
1184# logadm typically runs early every morning via an entry in
1185# root's crontab (see crontab(1)).
1186#
1187dir1/syslog -C 8 -a 'echo kill -HUP `cat /var/run/*syslog*pid` >> cmd.out'
1188dir2/messages -C 4 -a 'echo kill -HUP `cat /var/run/*syslog*pid` >> cmd.out'
1189#
1190# The entry below is used by turnacct(1M)
1191#
1192/var/adm/pacct -C 0 -a '/usr/lib/acct/accton pacct' -g adm -m 664 -o adm -p never
1193EOF
1194
1195	system("/bin/cp logadm.conf logadm.conf.orig");
1196
1197	$pid=`cat /var/run/*syslog*pid`;
1198	chomp $pid;
1199	set_file('cmd.out.expect', <<"EOF");
1200kill -HUP $pid
1201second kill -HUP $pid
1202EOF
1203
1204	set_file('sed.out.expect', <<'EOF');
1205# This file holds internal data for logadm(1M).
1206# Do not edit.
1207dir1/syslog
1208dir2/messages
1209EOF
1210
1211	set_file('checktest', <<'EOF');
1212[ -s std.err ] && { cat std.err; exit 1; }
1213[ -s std.out ] && exit 1
1214[ -s logadm.timestamps ] || exit 1
1215[ -s std.err2 ] && exit 1
1216[ -s std.out2 ] && exit 1
1217[ -s std.err3 ] && exit 1
1218[ -s std.out3 ] && exit 1
1219[ -s std.err4 ] && exit 1
1220[ -s std.out4 ] && exit 1
1221[ -f dir1/syslog ] || exit 1
1222[ "xsomething" = "x`/bin/cat dir1/syslog`" ] || exit 1
1223[ -f dir1/syslog.0 ] || exit 1
1224[ "xinitially dir1/syslog" = "x`/bin/cat dir1/syslog.0`" ] || exit 1
1225[ -f dir1/syslog.1 ] || exit 1
1226[ "xinitially dir1/syslog.0" = "x`/bin/cat dir1/syslog.1`" ] || exit 1
1227[ -f dir1/syslog.2 ] || exit 1
1228[ "xinitially dir1/syslog.1" = "x`/bin/cat dir1/syslog.2`" ] || exit 1
1229[ -f dir1/syslog.3 ] || exit 1
1230[ "xinitially dir1/syslog.2" = "x`/bin/cat dir1/syslog.3`" ] || exit 1
1231[ -f dir1/syslog.4 ] || exit 1
1232[ "xinitially dir1/syslog.3" = "x`/bin/cat dir1/syslog.4`" ] || exit 1
1233[ -f dir1/syslog.5 ] || exit 1
1234[ "xinitially dir1/syslog.4" = "x`/bin/cat dir1/syslog.5`" ] || exit 1
1235[ -f dir1/syslog.6 ] || exit 1
1236[ "xinitially dir1/syslog.5" = "x`/bin/cat dir1/syslog.6`" ] || exit 1
1237[ -f dir1/syslog.7 ] || exit 1
1238[ "xinitially dir1/syslog.6" = "x`/bin/cat dir1/syslog.7`" ] || exit 1
1239[ -f dir1/syslog.8 ] && exit 1
1240
1241[ -s dir2/messages ] && exit 1
1242[ -f dir2/messages.0 ] || exit 1
1243[ "xsomething" = "x`/bin/cat dir2/messages.0`" ] || exit 1
1244[ -f dir2/messages.1 ] || exit 1
1245[ "xinitially dir2/messages" = "x`/bin/cat dir2/messages.1`" ] || exit 1
1246[ -f dir2/messages.2 ] || exit 1
1247[ "xinitially dir2/messages.0" = "x`/bin/cat dir2/messages.2`" ] || exit 1
1248[ -f dir2/messages.3 ] || exit 1
1249[ "xinitially dir2/messages.1" = "x`/bin/cat dir2/messages.3`" ] || exit 1
1250[ -f dir2/messages.4 ] && exit 1
1251/bin/sed "s/ -P '[^']*' *//" < logadm.timestamps > sed.out
1252/bin/diff sed.out.expect sed.out || exit 1
1253exec /bin/diff logadm.conf.orig logadm.conf
1254EOF
1255
1256        # first logadm call will rotate both syslog and messages
1257        # second one won't because size is zero
1258        # third one won't because of -P timestamps stored in conffile
1259        # fourth one will do messages because of -p now on command line
1260        set_file('runtest', <<"EOF");
1261# test "logadm7"
1262$envsetup
1263$bindir/logadm -f logadm.conf -F logadm.timestamps >std.out 2>std.err || exit 1
1264$bindir/logadm -f logadm.conf -F logadm.timestamps dir1/syslog dir2/messages >std.out2 2>std.err2 || exit 1
1265echo something > dir1/syslog
1266echo something > dir2/messages
1267$bindir/logadm -f logadm.conf -F logadm.timestamps >std.out3 2>std.err3 || exit 1
1268exec $bindir/logadm -f logadm.conf -F logadm.timestamps dir2/messages -p now -a 'echo second kill -HUP `cat /var/run/*syslog*pid` >> cmd.out' >std.out4 2>std.err4
1269EOF
1270}
1271
1272###########################################################################
1273#
1274#       logadm8 -- test of -z
1275#
1276###########################################################################
1277sub logadm8 {
1278	mkdir 'dir1', 0777 or die "mkdir dir1: $!\n";
1279	set_file('dir1/syslog', 'initially dir1/syslog');
1280	set_file('dir1/syslog.0', 'initially dir1/syslog.0');
1281	set_file('dir1/syslog.1', 'initially dir1/syslog.1');
1282	set_file('dir1/syslog.2', 'initially dir1/syslog.2');
1283	system("/bin/gzip dir1/syslog.2");
1284	die "gzip dir1/syslog.2 didn't work\n" unless -f 'dir1/syslog.2.gz';
1285	set_file('dir1/syslog.3', 'initially dir1/syslog.3');
1286	system("/bin/gzip dir1/syslog.3");
1287	die "gzip dir1/syslog.3 didn't work\n" unless -f 'dir1/syslog.3.gz';
1288	set_file('dir1/syslog.4', 'initially dir1/syslog.4');
1289	system("/bin/gzip dir1/syslog.4");
1290	die "gzip dir1/syslog.4 didn't work\n" unless -f 'dir1/syslog.4.gz';
1291	set_file('dir1/syslog.5', 'initially dir1/syslog.5');
1292	system("/bin/gzip dir1/syslog.5");
1293	die "gzip dir1/syslog.5 didn't work\n" unless -f 'dir1/syslog.5.gz';
1294	set_file('dir1/syslog.6', 'initially dir1/syslog.6');
1295	system("/bin/gzip dir1/syslog.6");
1296	die "gzip dir1/syslog.6 didn't work\n" unless -f 'dir1/syslog.6.gz';
1297	set_file('dir1/syslog.7', 'initially dir1/syslog.7');
1298	system("/bin/gzip dir1/syslog.7");
1299	die "gzip dir1/syslog.7 didn't work\n" unless -f 'dir1/syslog.7.gz';
1300
1301	set_file('checktest', <<'EOF');
1302[ -s std.err ] && { cat std.err; exit 1; }
1303[ -s std.out ] && exit 1
1304[ -f dir1/syslog ] || exit 1
1305[ -s dir1/syslog ] && exit 1
1306[ -f dir1/syslog.0 ] || exit 1
1307[ "xinitially dir1/syslog" = "x`/bin/cat dir1/syslog.0`" ] || exit 1
1308[ -f dir1/syslog.1 ] || exit 1
1309[ "xinitially dir1/syslog.0" = "x`/bin/cat dir1/syslog.1`" ] || exit 1
1310[ -f dir1/syslog.2.gz ] || exit 1
1311[ "xinitially dir1/syslog.1" = "x`/bin/gzcat dir1/syslog.2.gz`" ] || exit 1
1312[ -f dir1/syslog.3.gz ] || exit 1
1313[ "xinitially dir1/syslog.2" = "x`/bin/gzcat dir1/syslog.3.gz`" ] || exit 1
1314[ -f dir1/syslog.4.gz ] || exit 1
1315[ "xinitially dir1/syslog.3" = "x`/bin/gzcat dir1/syslog.4.gz`" ] || exit 1
1316[ -f dir1/syslog.5.gz ] || exit 1
1317[ "xinitially dir1/syslog.4" = "x`/bin/gzcat dir1/syslog.5.gz`" ] || exit 1
1318[ -f dir1/syslog.6.gz ] || exit 1
1319[ "xinitially dir1/syslog.5" = "x`/bin/gzcat dir1/syslog.6.gz`" ] || exit 1
1320[ -f dir1/syslog.7.gz ] || exit 1
1321[ "xinitially dir1/syslog.6" = "x`/bin/gzcat dir1/syslog.7.gz`" ] || exit 1
1322[ -f dir1/syslog.8 ] && exit 1
1323[ -f dir1/syslog.8.gz ] && exit 1
1324exit 0
1325EOF
1326
1327        set_file('runtest', <<"EOF");
1328# test "logadm8"
1329$envsetup
1330exec $bindir/logadm -f /dev/null dir1/syslog -z 2 -C 8 >std.out 2>std.err
1331EOF
1332}
1333
1334###########################################################################
1335#
1336#       logadm9 -- test of age check
1337#
1338###########################################################################
1339sub logadm9 {
1340	mkdir 'dir1', 0777 or die "mkdir dir1: $!\n";
1341	set_file('dir1/syslog', 'initially dir1/syslog');
1342	set_file('dir1/syslog.0', 'initially dir1/syslog.0');
1343	set_file('dir1/syslog.1', 'initially dir1/syslog.1');
1344	set_file('dir1/syslog.2', 'initially dir1/syslog.2');
1345	set_file('dir1/syslog.3', 'initially dir1/syslog.3');
1346	set_file('dir1/syslog.4', 'initially dir1/syslog.4');
1347	set_file('dir1/syslog.5', 'initially dir1/syslog.5');
1348	set_file('dir1/syslog.6', 'initially dir1/syslog.6');
1349	set_file('dir1/syslog.7', 'initially dir1/syslog.7');
1350	set_file('dir1/notes', 'initially dir1/notes');
1351	mkdir 'dir2', 0777 or die "mkdir dir2: $!\n";
1352	set_file('dir2/messages', 'initially dir2/messages');
1353	set_file('dir2/messages.0', 'initially dir2/messages.0');
1354	set_file('dir2/messages.1', 'initially dir2/messages.1');
1355	set_file('dir2/messages.2', 'initially dir2/messages.2');
1356	set_file('dir2/messages.3', 'initially dir2/messages.3');
1357	set_file('dir2/log', 'initially dir2/log');
1358
1359	$now = time;
1360	$nowstr = gmtime($now);
1361	# a week minus 30 seconds ago...
1362	# technically not a full week, but the heuristic used by logadm
1363	# should think this is "close enough" to a full week
1364	$closetoweeksecs = $now - (60 * 60 * 24 * 7 - 30);
1365	$closetoweek = gmtime($closetoweeksecs);
1366	# a week minus six hours ago...
1367	$lessthanweeksecs = $now - (60 * 60 * 24 * 7 - 60 * 60 * 6);
1368	$lessthanweek = gmtime($lessthanweeksecs);
1369
1370	set_file('logadm.conf', <<"EOF");
1371# now: $nowstr is $now
1372# $closetoweek is $closetoweeksecs
1373dir1/syslog -C 8 -P '$closetoweek'
1374dir2/log -C 4
1375# $lessthanweek is $lessthanweeksecs
1376dir1/notes -C 2 -P '$lessthanweek'
1377dir2/messages -C 4
1378EOF
1379	set_file('logadm.timestamps', <<"EOF");
1380dir2/log -P '$closetoweek'
1381dir2/messages -P '$lessthanweek'
1382EOF
1383
1384	set_file('sed.out.expect', <<"EOF");
1385# This file holds internal data for logadm(1M).
1386# Do not edit.
1387dir1/syslog
1388dir2/log
1389dir1/notes
1390dir2/messages
1391EOF
1392
1393	set_file('checktest', <<'EOF');
1394[ -s std.err ] && { cat std.err; exit 1; }
1395[ -s std.out ] && exit 1
1396[ -f dir1/syslog ] || exit 1
1397[ -s dir1/syslog ] && exit 1
1398[ -f dir1/syslog.0 ] || exit 1
1399[ "xinitially dir1/syslog" = "x`/bin/cat dir1/syslog.0`" ] || exit 1
1400[ -f dir1/syslog.1 ] || exit 1
1401[ "xinitially dir1/syslog.0" = "x`/bin/cat dir1/syslog.1`" ] || exit 1
1402[ -f dir1/syslog.2 ] || exit 1
1403[ "xinitially dir1/syslog.1" = "x`/bin/cat dir1/syslog.2`" ] || exit 1
1404[ -f dir1/syslog.3 ] || exit 1
1405[ "xinitially dir1/syslog.2" = "x`/bin/cat dir1/syslog.3`" ] || exit 1
1406[ -f dir1/syslog.4 ] || exit 1
1407[ "xinitially dir1/syslog.3" = "x`/bin/cat dir1/syslog.4`" ] || exit 1
1408[ -f dir1/syslog.5 ] || exit 1
1409[ "xinitially dir1/syslog.4" = "x`/bin/cat dir1/syslog.5`" ] || exit 1
1410[ -f dir1/syslog.6 ] || exit 1
1411[ "xinitially dir1/syslog.5" = "x`/bin/cat dir1/syslog.6`" ] || exit 1
1412[ -f dir1/syslog.7 ] || exit 1
1413[ "xinitially dir1/syslog.6" = "x`/bin/cat dir1/syslog.7`" ] || exit 1
1414[ -f dir1/syslog.8 ] && exit 1
1415
1416[ -s dir1/notes ] || exit 1
1417[ "xinitially dir1/notes" = "x`/bin/cat dir1/notes`" ] || exit 1
1418[ -f dir1/notes.0 ] && exit 1
1419
1420[ -f dir2/messages ] || exit 1
1421[ "xinitially dir2/messages" = "x`/bin/cat dir2/messages`" ] || exit 1
1422[ -f dir2/messages.0 ] || exit 1
1423[ "xinitially dir2/messages.0" = "x`/bin/cat dir2/messages.0`" ] || exit 1
1424[ -f dir2/messages.1 ] || exit 1
1425[ "xinitially dir2/messages.1" = "x`/bin/cat dir2/messages.1`" ] || exit 1
1426[ -f dir2/messages.2 ] || exit 1
1427[ "xinitially dir2/messages.2" = "x`/bin/cat dir2/messages.2`" ] || exit 1
1428[ -f dir2/messages.3 ] || exit 1
1429[ "xinitially dir2/messages.3" = "x`/bin/cat dir2/messages.3`" ] || exit 1
1430[ -f dir2/messages.4 ] && exit 1
1431
1432[ -f dir2/log ] || exit 1
1433[ -s dir2/log ] && exit 1
1434[ -f dir2/log.0 ] || exit 1
1435[ "xinitially dir2/log" = "x`/bin/cat dir2/log.0`" ] || exit 1
1436[ -f dir2/log.1 ] && exit 1
1437
1438/bin/sed "s/ -P '[^']*' *//" < logadm.timestamps > sed.out
1439/bin/diff sed.out.expect sed.out || exit 1
1440/bin/sed -n "s/ -P '[^']*' */<&>/p" < logadm.conf > sed.out
1441[ -s sed.out ] && exit 1
1442exit 0
1443EOF
1444
1445        set_file('runtest', <<"EOF");
1446# test "logadm9"
1447$envsetup
1448exec $bindir/logadm -f logadm.conf -F logadm.timestamps >std.out 2>std.err
1449EOF
1450}
1451
1452###########################################################################
1453#
1454#       logadm9d -- test of age check like logadm9, but age is a couple days
1455#
1456###########################################################################
1457sub logadm9d {
1458	mkdir 'dir1', 0777 or die "mkdir dir1: $!\n";
1459	set_file('dir1/syslog', 'initially dir1/syslog');
1460	set_file('dir1/syslog.0', 'initially dir1/syslog.0');
1461	set_file('dir1/syslog.1', 'initially dir1/syslog.1');
1462	set_file('dir1/syslog.2', 'initially dir1/syslog.2');
1463	set_file('dir1/syslog.3', 'initially dir1/syslog.3');
1464	set_file('dir1/syslog.4', 'initially dir1/syslog.4');
1465	set_file('dir1/syslog.5', 'initially dir1/syslog.5');
1466	set_file('dir1/syslog.6', 'initially dir1/syslog.6');
1467	set_file('dir1/syslog.7', 'initially dir1/syslog.7');
1468	mkdir 'dir2', 0777 or die "mkdir dir2: $!\n";
1469	set_file('dir2/messages', 'initially dir2/messages');
1470	set_file('dir2/messages.0', 'initially dir2/messages.0');
1471	set_file('dir2/messages.1', 'initially dir2/messages.1');
1472	set_file('dir2/messages.2', 'initially dir2/messages.2');
1473	set_file('dir2/messages.3', 'initially dir2/messages.3');
1474
1475	$now = time;
1476	$nowstr = gmtime($now);
1477	# a day minus 30 seconds ago...
1478	$closetodaysecs = $now - (60 * 60 * 24 - 30);
1479	$closetoday = gmtime($closetodaysecs);
1480	# a day minus six hours ago...
1481	$lessthandaysecs = $now - (60 * 60 * 24 - 60 * 60 * 6);
1482	$lessthanday = gmtime($lessthandaysecs);
1483
1484	set_file('logadm.conf', <<"EOF");
1485# now: $nowstr is $now
1486# $closetoday is $closetodaysecs
1487dir1/syslog -p 1d -C 8 -P '$closetoday'
1488# $lessthanday is $lessthandaysecs
1489dir2/messages -p 1d -C 4 -P '$lessthanday'
1490EOF
1491
1492	set_file('checktest', <<'EOF');
1493[ -s std.err ] && { cat std.err; exit 1; }
1494[ -s std.out ] && exit 1
1495[ -f dir1/syslog ] || exit 1
1496[ -s dir1/syslog ] && exit 1
1497[ -f dir1/syslog.0 ] || exit 1
1498[ "xinitially dir1/syslog" = "x`/bin/cat dir1/syslog.0`" ] || exit 1
1499[ -f dir1/syslog.1 ] || exit 1
1500[ "xinitially dir1/syslog.0" = "x`/bin/cat dir1/syslog.1`" ] || exit 1
1501[ -f dir1/syslog.2 ] || exit 1
1502[ "xinitially dir1/syslog.1" = "x`/bin/cat dir1/syslog.2`" ] || exit 1
1503[ -f dir1/syslog.3 ] || exit 1
1504[ "xinitially dir1/syslog.2" = "x`/bin/cat dir1/syslog.3`" ] || exit 1
1505[ -f dir1/syslog.4 ] || exit 1
1506[ "xinitially dir1/syslog.3" = "x`/bin/cat dir1/syslog.4`" ] || exit 1
1507[ -f dir1/syslog.5 ] || exit 1
1508[ "xinitially dir1/syslog.4" = "x`/bin/cat dir1/syslog.5`" ] || exit 1
1509[ -f dir1/syslog.6 ] || exit 1
1510[ "xinitially dir1/syslog.5" = "x`/bin/cat dir1/syslog.6`" ] || exit 1
1511[ -f dir1/syslog.7 ] || exit 1
1512[ "xinitially dir1/syslog.6" = "x`/bin/cat dir1/syslog.7`" ] || exit 1
1513[ -f dir1/syslog.8 ] && exit 1
1514
1515[ -f dir2/messages ] || exit 1
1516[ "xinitially dir2/messages" = "x`/bin/cat dir2/messages`" ] || exit 1
1517[ -f dir2/messages.0 ] || exit 1
1518[ "xinitially dir2/messages.0" = "x`/bin/cat dir2/messages.0`" ] || exit 1
1519[ -f dir2/messages.1 ] || exit 1
1520[ "xinitially dir2/messages.1" = "x`/bin/cat dir2/messages.1`" ] || exit 1
1521[ -f dir2/messages.2 ] || exit 1
1522[ "xinitially dir2/messages.2" = "x`/bin/cat dir2/messages.2`" ] || exit 1
1523[ -f dir2/messages.3 ] || exit 1
1524[ "xinitially dir2/messages.3" = "x`/bin/cat dir2/messages.3`" ] || exit 1
1525[ -f dir2/messages.4 ] && exit 1
1526exit 0
1527EOF
1528
1529        set_file('runtest', <<"EOF");
1530# test "logadm9d"
1531$envsetup
1532exec $bindir/logadm -f logadm.conf -F logadm.timestamps >std.out 2>std.err
1533EOF
1534}
1535
1536###########################################################################
1537#
1538#       logadm10 -- test of size-based rotation check
1539#
1540###########################################################################
1541sub logadm10 {
1542	mkdir 'dir1', 0777 or die "mkdir dir1: $!\n";
1543	set_file('dir1/syslog', 'initially dir1/syslogXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
1544	set_file('dir1/syslog.0', 'initially dir1/syslog.0');
1545	set_file('dir1/syslog.1', 'initially dir1/syslog.1');
1546	set_file('dir1/syslog.2', 'initially dir1/syslog.2');
1547	set_file('dir1/syslog.3', 'initially dir1/syslog.3');
1548	set_file('dir1/syslog.4', 'initially dir1/syslog.4');
1549	set_file('dir1/syslog.5', 'initially dir1/syslog.5');
1550	set_file('dir1/syslog.6', 'initially dir1/syslog.6');
1551	set_file('dir1/syslog.7', 'initially dir1/syslog.7');
1552	mkdir 'dir2', 0777 or die "mkdir dir2: $!\n";
1553	set_file('dir2/messages', 'initially dir2/messages');
1554	set_file('dir2/messages.0', 'initially dir2/messages.0');
1555	set_file('dir2/messages.1', 'initially dir2/messages.1');
1556	set_file('dir2/messages.2', 'initially dir2/messages.2');
1557	set_file('dir2/messages.3', 'initially dir2/messages.3');
1558
1559	set_file('logadm.conf', <<"EOF");
1560dir1/syslog -C 8 -s 30b
1561dir2/messages -C 4 -s 30b
1562EOF
1563
1564	set_file('checktest', <<'EOF');
1565[ -s std.err ] && { cat std.err; exit 1; }
1566[ -s std.out ] && exit 1
1567[ -f dir1/syslog ] || exit 1
1568[ -s dir1/syslog ] && exit 1
1569[ -f dir1/syslog.0 ] || exit 1
1570[ "xinitially dir1/syslogXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" = "x`/bin/cat dir1/syslog.0`" ] || exit 1
1571[ -f dir1/syslog.1 ] || exit 1
1572[ "xinitially dir1/syslog.0" = "x`/bin/cat dir1/syslog.1`" ] || exit 1
1573[ -f dir1/syslog.2 ] || exit 1
1574[ "xinitially dir1/syslog.1" = "x`/bin/cat dir1/syslog.2`" ] || exit 1
1575[ -f dir1/syslog.3 ] || exit 1
1576[ "xinitially dir1/syslog.2" = "x`/bin/cat dir1/syslog.3`" ] || exit 1
1577[ -f dir1/syslog.4 ] || exit 1
1578[ "xinitially dir1/syslog.3" = "x`/bin/cat dir1/syslog.4`" ] || exit 1
1579[ -f dir1/syslog.5 ] || exit 1
1580[ "xinitially dir1/syslog.4" = "x`/bin/cat dir1/syslog.5`" ] || exit 1
1581[ -f dir1/syslog.6 ] || exit 1
1582[ "xinitially dir1/syslog.5" = "x`/bin/cat dir1/syslog.6`" ] || exit 1
1583[ -f dir1/syslog.7 ] || exit 1
1584[ "xinitially dir1/syslog.6" = "x`/bin/cat dir1/syslog.7`" ] || exit 1
1585[ -f dir1/syslog.8 ] && exit 1
1586
1587[ -f dir2/messages ] || exit 1
1588[ "xinitially dir2/messages" = "x`/bin/cat dir2/messages`" ] || exit 1
1589[ -f dir2/messages.0 ] || exit 1
1590[ "xinitially dir2/messages.0" = "x`/bin/cat dir2/messages.0`" ] || exit 1
1591[ -f dir2/messages.1 ] || exit 1
1592[ "xinitially dir2/messages.1" = "x`/bin/cat dir2/messages.1`" ] || exit 1
1593[ -f dir2/messages.2 ] || exit 1
1594[ "xinitially dir2/messages.2" = "x`/bin/cat dir2/messages.2`" ] || exit 1
1595[ -f dir2/messages.3 ] || exit 1
1596[ "xinitially dir2/messages.3" = "x`/bin/cat dir2/messages.3`" ] || exit 1
1597[ -f dir2/messages.4 ] && exit 1
1598exit 0
1599EOF
1600
1601        set_file('runtest', <<"EOF");
1602# test "logadm10"
1603$envsetup
1604exec $bindir/logadm -f logadm.conf -F logadm.timestamps >std.out 2>std.err
1605EOF
1606}
1607
1608###########################################################################
1609#
1610#       logadm11 -- test of size-based expiration check
1611#
1612###########################################################################
1613sub logadm11 {
1614	mkdir 'dir1', 0777 or die "mkdir dir1: $!\n";
1615	set_file('dir1/syslog', 'initially dir1/syslog');
1616	set_file('dir1/syslog.0', 'initially dir1/syslog.0');
1617	set_file('dir1/syslog.1', 'initially dir1/syslog.1');
1618	set_file('dir1/syslog.2', 'initially dir1/syslog.2');
1619	set_file('dir1/syslog.3', 'initially dir1/syslog.3');
1620	set_file('dir1/syslog.4', 'initially dir1/syslog.4');
1621	set_file('dir1/syslog.5', 'initially dir1/syslog.5');
1622	set_file('dir1/syslog.6', 'initially dir1/syslog.6');
1623	set_file('dir1/syslog.7', 'initially dir1/syslog.7');
1624	mkdir 'dir2', 0777 or die "mkdir dir2: $!\n";
1625	set_file('dir2/messages', 'initially dir2/messages');
1626	set_file('dir2/messages.0', 'initially dir2/messages.0');
1627	set_file('dir2/messages.1', 'initially dir2/messages.1');
1628	set_file('dir2/messages.2', 'initially dir2/messages.2');
1629	set_file('dir2/messages.3', 'initially dir2/messages.3');
1630
1631	set_file('logadm.conf', <<"EOF");
1632dir1/syslog -C 8 -s 30b -S 75b
1633dir2/messages -C 4 -s 30b -S 75b
1634EOF
1635
1636	set_file('checktest', <<'EOF');
1637[ -s std.err ] && { cat std.err; exit 1; }
1638[ -s std.out ] && exit 1
1639[ -f dir1/syslog ] || exit 1
1640[ "xinitially dir1/syslog" = "x`/bin/cat dir1/syslog`" ] || exit 1
1641[ -f dir1/syslog.0 ] || exit 1
1642[ "xinitially dir1/syslog.0" = "x`/bin/cat dir1/syslog.0`" ] || exit 1
1643[ -f dir1/syslog.1 ] || exit 1
1644[ "xinitially dir1/syslog.1" = "x`/bin/cat dir1/syslog.1`" ] || exit 1
1645[ -f dir1/syslog.2 ] || exit 1
1646[ "xinitially dir1/syslog.2" = "x`/bin/cat dir1/syslog.2`" ] || exit 1
1647[ -f dir1/syslog.3 ] && exit 1
1648[ -f dir1/syslog.4 ] && exit 1
1649[ -f dir1/syslog.5 ] && exit 1
1650[ -f dir1/syslog.6 ] && exit 1
1651[ -f dir1/syslog.7 ] && exit 1
1652[ -f dir1/syslog.8 ] && exit 1
1653
1654[ -f dir2/messages ] || exit 1
1655[ "xinitially dir2/messages" = "x`/bin/cat dir2/messages`" ] || exit 1
1656[ -f dir2/messages.0 ] || exit 1
1657[ "xinitially dir2/messages.0" = "x`/bin/cat dir2/messages.0`" ] || exit 1
1658[ -f dir2/messages.1 ] || exit 1
1659[ "xinitially dir2/messages.1" = "x`/bin/cat dir2/messages.1`" ] || exit 1
1660[ -f dir2/messages.2 ] || exit 1
1661[ "xinitially dir2/messages.2" = "x`/bin/cat dir2/messages.2`" ] || exit 1
1662[ -f dir2/messages.3 ] && exit 1
1663[ -f dir2/messages.4 ] && exit 1
1664exit 0
1665EOF
1666
1667        set_file('runtest', <<"EOF");
1668# test "logadm11"
1669$envsetup
1670exec $bindir/logadm -f logadm.conf -F logadm.timestamps >std.out 2>std.err
1671EOF
1672}
1673
1674###########################################################################
1675#
1676#	logadm12 -- ENOENT error path
1677#
1678###########################################################################
1679sub logadm12 {
1680	set_file('std.err.expect', <<'EOF');
1681logadm: Warning: logfile: No such file or directory
1682EOF
1683
1684	set_file('checktest', <<"EOF");
1685[ -s std.out ] && exit 1
1686exec /bin/diff std.err.expect std.err
1687EOF
1688
1689	set_file('runtest', <<"EOF");
1690# test "logadm12"
1691$envsetup
1692exec $bindir/logadm -f /dev/null logfile >std.out 2>std.err
1693EOF
1694}
1695
1696###########################################################################
1697#
1698#	logadm13 -- ENOENT error path with -N flag
1699#
1700###########################################################################
1701sub logadm13 {
1702	set_file('checktest', <<"EOF");
1703[ -s std.err ] && { cat std.err; exit 1; }
1704[ -s std.out ] && exit 1
1705exit 0
1706EOF
1707
1708	set_file('runtest', <<"EOF");
1709# test "logadm13"
1710$envsetup
1711exec $bindir/logadm -N -f /dev/null logfile >std.out 2>std.err
1712EOF
1713}
1714
1715###########################################################################
1716#
1717#       logadm14 -- test of -n and -v flags
1718#
1719###########################################################################
1720sub logadm14 {
1721	mkdir 'dir1', 0777 or die "mkdir dir1: $!\n";
1722	set_file('dir1/syslog', 'initially dir1/syslog');
1723	set_file('dir1/syslog.0', 'initially dir1/syslog.0');
1724	set_file('dir1/syslog.1', 'initially dir1/syslog.1');
1725	set_file('dir1/syslog.2', 'initially dir1/syslog.2');
1726	set_file('dir1/syslog.3', 'initially dir1/syslog.3');
1727	set_file('dir1/syslog.4', 'initially dir1/syslog.4');
1728	set_file('dir1/syslog.5', 'initially dir1/syslog.5');
1729	set_file('dir1/syslog.6', 'initially dir1/syslog.6');
1730	set_file('dir1/syslog.7', 'initially dir1/syslog.7');
1731	mkdir 'dir2', 0777 or die "mkdir dir2: $!\n";
1732	set_file('dir2/messages', 'initially dir2/messages');
1733	set_file('dir2/messages.0', 'initially dir2/messages.0');
1734	set_file('dir2/messages.1', 'initially dir2/messages.1');
1735	set_file('dir2/messages.2', 'initially dir2/messages.2');
1736	set_file('dir2/messages.3', 'initially dir2/messages.3');
1737
1738	set_file('logadm.conf', <<'EOF');
1739#
1740# logadm.conf
1741#
1742# Default settings for system log file management.
1743# The -w option to logadm(1M) is the preferred way to write to this file,
1744# but if you do edit it by hand, use "logadm -V" to check it for errors.
1745# but if you do edit it by hand, use "logadm -V" to check it for errors.
1746#
1747# The format of lines in this file is:
1748#       <logname> <options>
1749# For each logname listed here, the default options to logadm
1750# are given.  Options given on the logadm command line override
1751# the defaults contained in this file.
1752#
1753# logadm typically runs early every morning via an entry in
1754# root's crontab (see crontab(1)).
1755#
1756dir1/syslog -C 8 -a 'echo kill -HUP `cat /var/run/*syslog*pid` >> cmd.out'
1757dir2/messages -C 4 -a 'echo kill -HUP `cat /var/run/*syslog*pid` >> cmd.out'
1758#
1759# The entry below is used by turnacct(1M)
1760#
1761/var/adm/pacct -C 0 -a '/usr/lib/acct/accton pacct' -g adm -m 664 -o adm -p never
1762EOF
1763
1764	$gid = $);
1765	$gid =~ s/ .*//;
1766	set_file('grep.out.expect', <<'EOF'.<<"EOF".<<'EOF'.<<"EOF".<<'EOF');
1767# loading logadm.conf
1768# processing logname: dir1/syslog
1769#     using default rotate rules: -s1b -p1w
1770#     using default template: $file.$n
1771mkdir -p dir1 # verify directory exists
1772mv -f dir1/syslog.7 dir1/syslog.8 # rotate log file
1773mkdir -p dir1 # verify directory exists
1774mv -f dir1/syslog.6 dir1/syslog.7 # rotate log file
1775mkdir -p dir1 # verify directory exists
1776mv -f dir1/syslog.5 dir1/syslog.6 # rotate log file
1777mkdir -p dir1 # verify directory exists
1778mv -f dir1/syslog.4 dir1/syslog.5 # rotate log file
1779mkdir -p dir1 # verify directory exists
1780mv -f dir1/syslog.3 dir1/syslog.4 # rotate log file
1781mkdir -p dir1 # verify directory exists
1782mv -f dir1/syslog.2 dir1/syslog.3 # rotate log file
1783mkdir -p dir1 # verify directory exists
1784mv -f dir1/syslog.1 dir1/syslog.2 # rotate log file
1785mkdir -p dir1 # verify directory exists
1786mv -f dir1/syslog.0 dir1/syslog.1 # rotate log file
1787mkdir -p dir1 # verify directory exists
1788mv -f dir1/syslog dir1/syslog.0 # rotate log file
1789touch dir1/syslog
1790EOF
1791chown $>:$gid dir1/syslog
1792EOF
1793chmod 664 dir1/syslog
1794# processing logname: dir2/messages
1795#     using default rotate rules: -s1b -p1w
1796#     using default template: $file.$n
1797mkdir -p dir2 # verify directory exists
1798mv -f dir2/messages.3 dir2/messages.4 # rotate log file
1799mkdir -p dir2 # verify directory exists
1800mv -f dir2/messages.2 dir2/messages.3 # rotate log file
1801mkdir -p dir2 # verify directory exists
1802mv -f dir2/messages.1 dir2/messages.2 # rotate log file
1803mkdir -p dir2 # verify directory exists
1804mv -f dir2/messages.0 dir2/messages.1 # rotate log file
1805mkdir -p dir2 # verify directory exists
1806mv -f dir2/messages dir2/messages.0 # rotate log file
1807touch dir2/messages
1808EOF
1809chown $>:$gid dir2/messages
1810EOF
1811chmod 664 dir2/messages
1812# processing logname: /var/adm/pacct
1813#     using default template: $file.$n
1814sh -c echo kill -HUP `cat /var/run/*syslog*pid` >> cmd.out # -a cmd
1815# logadm.conf and logadm.timestamps unchanged
1816EOF
1817
1818	set_file('checktest', <<'EOF');
1819[ -s std.err ] && { cat std.err; exit 1; }
1820[ -f std.out ] || exit 1
1821[ -f dir1/syslog ] || exit 1
1822[ "xinitially dir1/syslog" = "x`/bin/cat dir1/syslog`" ] || exit 1
1823[ -f dir1/syslog.0 ] || exit 1
1824[ "xinitially dir1/syslog.0" = "x`/bin/cat dir1/syslog.0`" ] || exit 1
1825[ -f dir1/syslog.1 ] || exit 1
1826[ "xinitially dir1/syslog.1" = "x`/bin/cat dir1/syslog.1`" ] || exit 1
1827[ -f dir1/syslog.2 ] || exit 1
1828[ "xinitially dir1/syslog.2" = "x`/bin/cat dir1/syslog.2`" ] || exit 1
1829[ -f dir1/syslog.3 ] || exit 1
1830[ "xinitially dir1/syslog.3" = "x`/bin/cat dir1/syslog.3`" ] || exit 1
1831[ -f dir1/syslog.4 ] || exit 1
1832[ "xinitially dir1/syslog.4" = "x`/bin/cat dir1/syslog.4`" ] || exit 1
1833[ -f dir1/syslog.5 ] || exit 1
1834[ "xinitially dir1/syslog.5" = "x`/bin/cat dir1/syslog.5`" ] || exit 1
1835[ -f dir1/syslog.6 ] || exit 1
1836[ "xinitially dir1/syslog.6" = "x`/bin/cat dir1/syslog.6`" ] || exit 1
1837[ -f dir1/syslog.7 ] || exit 1
1838[ "xinitially dir1/syslog.7" = "x`/bin/cat dir1/syslog.7`" ] || exit 1
1839[ -f dir1/syslog.8 ] && exit 1
1840
1841[ -f dir2/messages ] || exit 1
1842[ "xinitially dir2/messages" = "x`/bin/cat dir2/messages`" ] || exit 1
1843[ -f dir2/messages.0 ] || exit 1
1844[ "xinitially dir2/messages.0" = "x`/bin/cat dir2/messages.0`" ] || exit 1
1845[ -f dir2/messages.1 ] || exit 1
1846[ "xinitially dir2/messages.1" = "x`/bin/cat dir2/messages.1`" ] || exit 1
1847[ -f dir2/messages.2 ] || exit 1
1848[ "xinitially dir2/messages.2" = "x`/bin/cat dir2/messages.2`" ] || exit 1
1849[ -f dir2/messages.3 ] || exit 1
1850[ "xinitially dir2/messages.3" = "x`/bin/cat dir2/messages.3`" ] || exit 1
1851[ -f dir2/messages.4 ] && exit 1
1852/bin/grep -v 'recording rotation date' std.out > grep.out
1853exec /bin/diff grep.out.expect grep.out
1854EOF
1855
1856        set_file('runtest', <<"EOF");
1857# test "logadm14"
1858$envsetup
1859exec $bindir/logadm -nv -f logadm.conf -F logadm.timestamps >std.out 2>std.err
1860EOF
1861}
1862
1863###########################################################################
1864#
1865#	logadm15 -- test of -T
1866#
1867###########################################################################
1868sub logadm15 {
1869	set_file('logfile', '');
1870	set_file('logfile.0', 'initially logfile.0');
1871	set_file('logfile.1', 'initially logfile.1');
1872	set_file('logfile.2', 'initially logfile.2');
1873	set_file('logfile.3', 'initially logfile.3');
1874	set_file('logfile.4', 'initially logfile.4');
1875	set_file('logfile.5', 'initially logfile.5');
1876	set_file('logfile.6', 'initially logfile.6');
1877	set_file('logfile.7', 'initially logfile.7');
1878	set_file('logfile.8', 'initially logfile.8');
1879	set_file('logfile.9', 'initially logfile.9');
1880
1881	set_file('checktest', <<'EOF');
1882[ -s std.err ] && { cat std.err; exit 1; }
1883[ -s std.out ] && exit 1
1884[ -f logfile ] || exit 1
1885[ "x" = "x`/bin/cat logfile`" ] || exit 1
1886[ -f logfile.0 ] || exit 1
1887[ "xinitially logfile.0" = "x`/bin/cat logfile.0`" ] || exit 1
1888[ -f logfile.1 ] || exit 1
1889[ "xinitially logfile.1" = "x`/bin/cat logfile.1`" ] || exit 1
1890[ -f logfile.2 ] || exit 1
1891[ "xinitially logfile.2" = "x`/bin/cat logfile.2`" ] || exit 1
1892[ -f logfile.3 ] && exit 1
1893[ -f logfile.4 ] || exit 1
1894[ "xinitially logfile.4" = "x`/bin/cat logfile.4`" ] || exit 1
1895[ -f logfile.5 ] && exit 1
1896[ -f logfile.6 ] || exit 1
1897[ "xinitially logfile.6" = "x`/bin/cat logfile.6`" ] || exit 1
1898[ -f logfile.7 ] && exit 1
1899[ -f logfile.8 ] || exit 1
1900[ "xinitially logfile.8" = "x`/bin/cat logfile.8`" ] || exit 1
1901[ -f logfile.9 ] && exit 1
1902[ -f logfile.10 ] && exit 1
1903exit 0
1904EOF
1905
1906	set_file('runtest', <<"EOF");
1907# test "logadm15"
1908$envsetup
1909exec $bindir/logadm -f /dev/null logfile -C1 -T '*.[13579]'>std.out 2>std.err
1910EOF
1911}
1912
1913###########################################################################
1914#
1915#	logadm16 -- test of -h
1916#
1917###########################################################################
1918sub logadm16 {
1919	set_file('std.err.expect', <<'EOF');
1920Usage: logadm [options]
1921       (processes all entries in /etc/logadm.conf or conffile given by -f)
1922   or: logadm [options] logname...
1923       (processes the given lognames)
1924
1925General options:
1926        -e mailaddr     mail errors to given address
1927        -F timestamps   use timestamps instead of /var/logadm/timestamps
1928        -f conffile     use conffile instead of /etc/logadm.conf
1929        -h              display help
1930        -N              not an error if log file nonexistent
1931        -n              show actions, don't perform them
1932        -r              remove logname entry from conffile
1933        -V              ensure conffile entries exist, correct
1934        -v              print info about actions happening
1935        -w entryname    write entry to config file
1936
1937Options which control when a logfile is rotated:
1938(default is: -s1b -p1w if no -s or -p)
1939        -p period       only rotate if period passed since last rotate
1940        -P timestamp    used to store rotation date in conffile
1941        -s size         only rotate if given size or greater
1942
1943Options which control how a logfile is rotated:
1944(default is: -t '$file.$n', owner/group/mode taken from log file)
1945        -a cmd          execute cmd after taking actions
1946        -b cmd          execute cmd before taking actions
1947        -c              copy & truncate logfile, don't rename
1948        -g group        new empty log file group
1949        -l              rotate log file with local time rather than UTC
1950        -m mode         new empty log file mode
1951        -M cmd          execute cmd to rotate the log file
1952        -o owner        new empty log file owner
1953        -R cmd          run cmd on file after rotate
1954        -t template     template for naming old logs
1955        -z count        gzip old logs except most recent count
1956
1957Options which control the expiration of old logfiles:
1958(default is: -C10 if no -A, -C, or -S)
1959        -A age          expire logs older than age
1960        -C count        expire old logs until count remain
1961        -E cmd          run cmd on file to expire
1962        -S size         expire until space used is below size
1963        -T pattern      pattern for finding old logs
1964EOF
1965
1966	set_file('checktest', <<'EOF');
1967[ -s std.out ] && exit 1
1968exec /bin/diff std.err.expect std.err
1969EOF
1970
1971	set_file('runtest', <<"EOF");
1972# test "logadm16"
1973$envsetup
1974exec $bindir/logadm -h >std.out 2>std.err
1975EOF
1976}
1977
1978###########################################################################
1979#
1980#       logadm17 -- test that mkdir -p happens as necessary
1981#
1982###########################################################################
1983sub logadm17 {
1984	set_file('logfile', 'initially logfile');
1985
1986	set_file('checktest', <<'EOF');
1987[ -s std.err ] && { cat std.err; exit 1; }
1988[ -s std.out ] && exit 1
1989[ -f dir1/dir2/logfile ] || exit 1
1990[ -f logfile ] || exit 1
1991[ "xinitially logfile" = "x`/bin/cat dir1/dir2/logfile`" ] || exit 1
1992exit 0
1993EOF
1994
1995        set_file('runtest', <<"EOF");
1996# test "logadm17"
1997$envsetup
1998exec $bindir/logadm -f /dev/null -t 'dir1/dir2/\$basename' logfile -p now >std.out 2>std.err
1999EOF
2000}
2001
2002###########################################################################
2003#
2004#       logadm18 -- test of -M option
2005#
2006###########################################################################
2007sub logadm18 {
2008	mkdir 'dir1', 0777 or die "mkdir dir1: $!\n";
2009	set_file('dir1/syslog', 'initially dir1/syslog');
2010	set_file('dir1/syslog.0', 'initially dir1/syslog.0');
2011	set_file('dir1/syslog.1', 'initially dir1/syslog.1');
2012	set_file('dir1/syslog.2', 'initially dir1/syslog.2');
2013	set_file('dir1/syslog.3', 'initially dir1/syslog.3');
2014	set_file('dir1/syslog.4', 'initially dir1/syslog.4');
2015	set_file('dir1/syslog.5', 'initially dir1/syslog.5');
2016	set_file('dir1/syslog.6', 'initially dir1/syslog.6');
2017	set_file('dir1/syslog.7', 'initially dir1/syslog.7');
2018
2019	set_file('logadm.conf', <<"EOF");
2020dir1/syslog -C 8 -s 1b -M '/bin/tr [a-z] [A-Z] < \$file > \$nfile; /bin/rm -f \$file'
2021EOF
2022
2023	set_file('checktest', <<'EOF');
2024[ -s std.err ] && { cat std.err; exit 1; }
2025[ -s std.out ] && exit 1
2026[ -f dir1/syslog ] || exit 1
2027[ -s dir1/syslog ] && exit 1
2028[ -f dir1/syslog.0 ] || exit 1
2029[ "xINITIALLY DIR1/SYSLOG" = "x`/bin/cat dir1/syslog.0`" ] || exit 1
2030[ -f dir1/syslog.1 ] || exit 1
2031[ "xinitially dir1/syslog.0" = "x`/bin/cat dir1/syslog.1`" ] || exit 1
2032[ -f dir1/syslog.2 ] || exit 1
2033[ "xinitially dir1/syslog.1" = "x`/bin/cat dir1/syslog.2`" ] || exit 1
2034[ -f dir1/syslog.3 ] || exit 1
2035[ "xinitially dir1/syslog.2" = "x`/bin/cat dir1/syslog.3`" ] || exit 1
2036[ -f dir1/syslog.4 ] || exit 1
2037[ "xinitially dir1/syslog.3" = "x`/bin/cat dir1/syslog.4`" ] || exit 1
2038[ -f dir1/syslog.5 ] || exit 1
2039[ "xinitially dir1/syslog.4" = "x`/bin/cat dir1/syslog.5`" ] || exit 1
2040[ -f dir1/syslog.6 ] || exit 1
2041[ "xinitially dir1/syslog.5" = "x`/bin/cat dir1/syslog.6`" ] || exit 1
2042[ -f dir1/syslog.7 ] || exit 1
2043[ "xinitially dir1/syslog.6" = "x`/bin/cat dir1/syslog.7`" ] || exit 1
2044[ -f dir1/syslog.8 ] && exit 1
2045
2046exit 0
2047EOF
2048
2049        set_file('runtest', <<"EOF");
2050# test "logadm18"
2051$envsetup
2052exec $bindir/logadm -f logadm.conf -F logadm.timestamps >std.out 2>std.err
2053EOF
2054}
2055
2056#############################################################################
2057#
2058#         logadm19 -- test of  -l
2059#
2060#############################################################################
2061sub logadm19 {
2062        set_file('logfile', 'initially logfile');
2063
2064        set_file('checktest', <<'EOF');
2065[ -s std.err ] && { cat std.err; exit 1; }
2066[ -s std.out ] && exit 1
2067[ -s logfile ] && exit 1
2068TZ= export TZ
2069d=`/bin/date +\%d\%H\%M`
2070[ -f logfile.$d ] || exit 1
2071[ "xinitially logfile" = "x`/bin/cat logfile.$d`" ] || exit 1
2072exit 0
2073EOF
2074
2075        set_file('runtest', <<"EOF");
2076# test "logadm19"
2077$envsetup
2078exec $bindir/logadm -f /dev/null -l -p now logfile -t '\$file.\%d\%H\%M' >std.out 2>std.err
2079EOF
2080}
2081
2082#############################################################################
2083#
2084#         logadm20 -- test of unquotables/error handling
2085#
2086#############################################################################
2087sub logadm20 {
2088	set_file('logadm.conf', <<'EOF');
2089# non-trivial entry
2090/var/log/syslog -C 8 -a 'kill -HUP `cat /var/run/*syslog*pid`'
2091EOF
2092
2093	set_file('std.err.expect', <<'EOF');
2094logadm: Error: Can't protect quotes in </bin/echo "She can't take anymore, Cap'n!">
2095logadm: Error: unsafe to update configuration file or timestamps
2096logadm: Error: bailing out due to command line errors
2097Use "logadm -h" for help.
2098exit=1
2099EOF
2100
2101        set_file('checktest', <<'EOF');
2102[ -s std.err ] || exit 1
2103[ -s std.out ] && exit 1
2104[ -f logadm.conf????? ] && exit 1
2105[ -f logadm.timestamps????? ] && exit 1
2106exec /bin/diff std.err.expect std.err
2107EOF
2108
2109        set_file('runtest', <<"EOF");
2110# test "logadm20"
2111$envsetup
2112$bindir/logadm -f logadm.conf -F logadm.timestamps -w /a/b/c -p 1w -l -b "/bin/echo \\"She can't take anymore, Cap'n!\\"" >std.out 2>std.err
2113echo exit=\$? >>std.err
2114EOF
2115}
2116
2117#############################################################################
2118#
2119#         logadm21 -- test of busted configuration file
2120#
2121#############################################################################
2122sub logadm21 {
2123	set_file('logadm.conf', <<'EOF');
2124poop
2125EOF
2126	set_file('checktest', <<'EOF');
2127[ -s std.err ] || exit 1
2128grep Warning std.err > /dev/null
2129EOF
2130
2131        set_file('runtest', <<"EOF");
2132# test "logadm21"
2133$envsetup
2134$bindir/logadm -f logadm.conf -F /dev/null 2>std.err
2135exit 0
2136EOF
2137}
2138
2139#############################################################################
2140#
2141#         logadm22 - test for keeping timestamps in timestamps file on -w
2142#
2143#############################################################################
2144
2145sub logadm22 {
2146	set_file('logadm.conf', <<'EOF');
2147wildcard_test -A 3d dir1/*.log
2148regular_test -A 3d dir2/test.log
2149EOF
2150
2151set_file('logadm.conf.expect', <<'EOF');
2152wildcard_test -A 3d dir1/*.log
2153regular_test -A 3d dir2/test.log
2154dir3/test.log -A 3d
2155EOF
2156
2157	set_file('logadm.timestamps', <<'EOF');
2158# This file holds internal data for logadm(1M).
2159# Do not edit.
2160dir1/foo.log -P 'Thu Nov  1 16:56:42 2001'
2161dir2/test.log -P 'Thu Nov  1 16:56:42 2001'
2162EOF
2163	system("/bin/cp logadm.timestamps logadm.timestamps.expect");
2164
2165	set_file('checktest', <<'EOF');
2166[ -s std.err ] && { cat std.err; exit 1; }
2167/bin/diff logadm.conf.expect logadm.conf || exit 1
2168/bin/diff logadm.timestamps.expect logadm.timestamps || exit 1
2169EOF
2170
2171	set_file('runtest', <<"EOF");
2172# test "logadm22"
2173$envsetup
2174$bindir/logadm -f logadm.conf -F logadm.timestamps -w dir3/test.log -A 3d 2>std.err
2175exit 0
2176EOF
2177
2178}
2179
2180#############################################################################
2181#
2182#         logadm23 - test for keeping timestamps in timestamps file on -r
2183#
2184#############################################################################
2185
2186sub logadm23 {
2187	set_file('logadm.conf', <<'EOF');
2188wildcard_test -A 3d dir1/*.log
2189regular_test -A 3d dir2/test.log
2190EOF
2191
2192set_file('logadm.conf.expect', <<'EOF');
2193wildcard_test -A 3d dir1/*.log
2194EOF
2195
2196	set_file('logadm.timestamps', <<'EOF');
2197# This file holds internal data for logadm(1M).
2198# Do not edit.
2199dir1/foo.log -P 'Thu Nov  1 16:56:42 2001'
2200dir2/test.log -P 'Thu Nov  1 16:56:42 2001'
2201EOF
2202	system("/bin/cp logadm.timestamps logadm.timestamps.expect");
2203
2204	set_file('checktest', <<'EOF');
2205[ -s std.err ] && { cat std.err; exit 1; }
2206/bin/diff logadm.conf.expect logadm.conf || exit 1
2207/bin/diff logadm.timestamps.expect logadm.timestamps || exit 1
2208EOF
2209
2210	set_file('runtest', <<"EOF");
2211# test "logadm23"
2212$envsetup
2213$bindir/logadm -f logadm.conf -F logadm.timestamps -r regular_test 2>std.err
2214exit 0
2215EOF
2216
2217}
2218
2219###########################################################################
2220#
2221#	stderr1 -- ensure verbose stderr does not deadlock
2222#
2223###########################################################################
2224sub stderr1 {
2225	set_file('logfile', 'initially logfile');
2226
2227	set_file('std.err.uniq.expect', <<'EOF');
2228   1 logadm: Warning: command failed: /bin/sh -c exec 1>&2; for i in {1..250000}; do echo pre-command-stuff; done
2229250000 pre-command-stuff
2230   1 logadm: Warning: command failed: /bin/sh -c exec 1>&2; for i in {1..250000}; do echo post-command-stuff; done
2231250000 post-command-stuff
2232EOF
2233
2234	set_file('checktest', <<'EOF');
2235[ -s std.out ] && exit 1
2236/bin/diff -u std.err.uniq.expect std.err.uniq || exit 1
2237exit 0
2238EOF
2239
2240	# The output redirection below looks wrong, but it is not.  The redirect
2241	# of stderr before the redirect of stdout causes stderr to be piped to
2242	# uniq.
2243	set_file('runtest', <<"EOF");
2244# test "stderr1"
2245$envsetup
2246exec $bindir/logadm -f /dev/null -p now logfile \\
2247    -b 'exec 1>&2; for i in {1..250000}; do echo pre-command-stuff; done' \\
2248    -a 'exec 1>&2; for i in {1..250000}; do echo post-command-stuff; done' \\
2249    2>&1 >std.out | uniq -c >std.err.uniq
2250EOF
2251}
2252