xref: /openbsd/usr.sbin/pkg_add/OpenBSD/Log.pm (revision 9acbf608)
1# ex:ts=8 sw=4:
2# $OpenBSD: Log.pm,v 1.11 2024/10/01 18:48:29 tb Exp $
3#
4# Copyright (c) 2007-2010 Marc Espie <espie@openbsd.org>
5#
6# Permission to use, copy, modify, and distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17#
18
19use v5.36;
20
21package OpenBSD::Log;
22
23sub new($class, $printer)
24{
25	bless { p => $printer }, $class;
26}
27
28sub set_context($self, $context)
29{
30	$self->{context} = $context;
31}
32
33sub messages($self)
34{
35	$self->{context} //= "???";
36	return $self->{messages}{$self->{context}} //= [];
37}
38
39sub errmessages($self)
40{
41	$self->{context} //= "???";
42	return $self->{errmessages}{$self->{context}} //= [];
43}
44
45sub f($self, @p)
46{
47	$self->{p}->f(@p);
48}
49
50sub print($self, @p)
51{
52	push(@{$self->messages}, $self->f(@p));
53}
54
55sub say($self, @p)
56{
57	push(@{$self->messages}, $self->f(@p)."\n");
58}
59
60sub errprint($self, @p)
61{
62	push(@{$self->errmessages}, $self->f(@p));
63}
64
65sub errsay($self, @p)
66{
67	push(@{$self->errmessages}, $self->f(@p)."\n");
68}
69
70sub specialsort(@p)
71{
72	return ((sort grep { /^\-/ } @p), (sort grep { /^\+/} @p),
73	    (sort grep { !/^[\-+]/ } @p));
74}
75
76sub dump($self)
77{
78	for my $ctxt (specialsort keys %{$self->{errmessages}}) {
79		my $msgs = $self->{errmessages}{$ctxt};
80		if (@$msgs > 0) {
81			$self->{p}->errsay("--- #1 -------------------", $ctxt);
82			$self->{p}->_errprint(@$msgs);
83		}
84	}
85	$self->{errmessages} = {};
86	for my $ctxt (specialsort keys %{$self->{messages}}) {
87		my $msgs = $self->{messages}{$ctxt};
88		if (@$msgs > 0) {
89			$self->{p}->say("--- #1 -------------------", $ctxt);
90			$self->{p}->_print(@$msgs);
91		}
92	}
93	$self->{messages} = {};
94}
95
96sub fatal($self, @p)
97{
98	if (defined $self->{context}) {
99		$self->{p}->_fatal($self->{context}, ":", $self->f(@p));
100	}
101
102	$self->{p}->_fatal($self->f(@p));
103}
104
105sub system($self, @p)
106{
107	my ($todo, $todo2);
108	if (ref $p[0] eq 'CODE') {
109		$todo = shift @p;
110	} else {
111		$todo = sub() {};
112	}
113	if (ref $p[0] eq 'CODE') {
114		$todo2 = shift @p;
115	} else {
116		$todo2 = sub() {};
117	}
118	my $child_pid = open(my $grab, "-|");
119	if (!defined $child_pid) {
120		$self->{p}->say("system(#1) was not run: #2 #3",
121		    join(", ", @p), $!, $self->{p}->child_error);
122	}
123	if ($child_pid) {
124		&$todo2();
125		while (<$grab>) {
126			$self->{p}->_print($_);
127		}
128		if (!close $grab) {
129			$self->{p}->say("system(#1) failed: #2 #3",
130			    join(", ", @p), $!,
131			    $self->{p}->child_error);
132		}
133		return $?;
134	} else {
135		$DB::inhibit_exit = 0;
136		&$todo();
137		exec {$p[0]} (@p) or exit 1;
138	}
139}
140
1411;
142