xref: /openbsd-src/usr.sbin/pkg_add/OpenBSD/PackageRepository/Persistent.pm (revision 039cbdaaca23c9e872a2bab23f91224c76c0f23b)
1a3144174Skspillner# ex:ts=8 sw=4:
2*039cbdaaSespie# $OpenBSD: Persistent.pm,v 1.4 2023/06/13 09:07:18 espie Exp $
3a3144174Skspillner#
4a3144174Skspillner# Copyright (c) 2003-2014 Marc Espie <espie@openbsd.org>
5a3144174Skspillner#
6a3144174Skspillner# Permission to use, copy, modify, and distribute this software for any
7a3144174Skspillner# purpose with or without fee is hereby granted, provided that the above
8a3144174Skspillner# copyright notice and this permission notice appear in all copies.
9a3144174Skspillner#
10a3144174Skspillner# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11a3144174Skspillner# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12a3144174Skspillner# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13a3144174Skspillner# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14a3144174Skspillner# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15a3144174Skspillner# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16a3144174Skspillner# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17a3144174Skspillner
18*039cbdaaSespieuse v5.36;
19a3144174Skspillner
20a3144174Skspillnerpackage OpenBSD::PackageRepository::Persistent;
21a3144174Skspillnerour @ISA=qw(OpenBSD::PackageRepository::Distant);
22a3144174Skspillner
23a3144174Skspillnerour %distant = ();
24a3144174Skspillner
25*039cbdaaSespiesub may_exist($self, $name)
26a3144174Skspillner{
27a3144174Skspillner	my $l = $self->list;
28a3144174Skspillner	return grep {$_ eq $name } @$l;
29a3144174Skspillner}
30a3144174Skspillner
31*039cbdaaSespiesub grab_object($self, $object)
32a3144174Skspillner{
33a3144174Skspillner	my $cmdfh = $self->{cmdfh};
34a3144174Skspillner	my $getfh = $self->{getfh};
35a3144174Skspillner
36a3144174Skspillner	print $cmdfh "ABORT\n";
37a3144174Skspillner	while (<$getfh>) {
38a3144174Skspillner		last if m/^ABORTED/o;
39a3144174Skspillner	}
40a3144174Skspillner	print $cmdfh "GET ", $self->{path}.$object->{name}.".tgz", "\n";
413c9e9c75Sespie	CORE::close($cmdfh);
42a3144174Skspillner	$_ = <$getfh>;
43a3144174Skspillner	chomp;
44a3144174Skspillner	if (m/^ERROR:/o) {
45a3144174Skspillner		$self->{state}->fatal("transfer error: #1", $_);
46a3144174Skspillner	}
47a3144174Skspillner	if (m/^TRANSFER:\s+(\d+)/o) {
48a3144174Skspillner		my $buffsize = 10 * 1024;
49a3144174Skspillner		my $buffer;
50a3144174Skspillner		my $size = $1;
51a3144174Skspillner		my $remaining = $size;
52a3144174Skspillner		my $n;
53a3144174Skspillner
54a3144174Skspillner		do {
55a3144174Skspillner			$n = read($getfh, $buffer,
56a3144174Skspillner				$remaining < $buffsize ? $remaining :$buffsize);
57a3144174Skspillner			if (!defined $n) {
58a3144174Skspillner				$self->{state}->fatal("Error reading: #1", $!);
59a3144174Skspillner			}
60a3144174Skspillner			$remaining -= $n;
61a3144174Skspillner			if ($n > 0) {
62a3144174Skspillner				syswrite STDOUT, $buffer;
63a3144174Skspillner			}
64a3144174Skspillner		} while ($n != 0 && $remaining != 0);
65a3144174Skspillner	}
663c9e9c75Sespie	delete $self->{controller};
673c9e9c75Sespie	CORE::close($getfh);
68a3144174Skspillner}
69a3144174Skspillner
70*039cbdaaSespiesub maxcount($)
71a3144174Skspillner{
72a3144174Skspillner	return 1;
73a3144174Skspillner}
74a3144174Skspillner
75*039cbdaaSespiesub opened($self)
76a3144174Skspillner{
77a3144174Skspillner	my $k = $self->{host};
78a3144174Skspillner	if (!defined $distant{$k}) {
79a3144174Skspillner		$distant{$k} = [];
80a3144174Skspillner	}
81a3144174Skspillner	return $distant{$k};
82a3144174Skspillner}
83a3144174Skspillner
84*039cbdaaSespiesub list($self)
85a3144174Skspillner{
86a3144174Skspillner	if (!defined $self->{list}) {
87a3144174Skspillner		if (!defined $self->{controller}) {
88a3144174Skspillner			$self->initiate;
89a3144174Skspillner		}
90a3144174Skspillner		my $cmdfh = $self->{cmdfh};
91a3144174Skspillner		my $getfh = $self->{getfh};
92a3144174Skspillner		my $path = $self->{path};
93a3144174Skspillner		my $l = [];
94a3144174Skspillner		print $cmdfh "LIST $path\n";
95a3144174Skspillner		$_ = <$getfh>;
96a3144174Skspillner		if (!defined $_) {
97a3144174Skspillner			$self->{state}->fatal("Could not initiate #1 session",
98a3144174Skspillner			    $self->urlscheme);
99a3144174Skspillner		}
100a3144174Skspillner		chomp;
101a3144174Skspillner		if (m/^ERROR:/o) {
102a3144174Skspillner			$self->{state}->fatal("#1", $_);
103a3144174Skspillner		}
104a3144174Skspillner		if (!m/^SUCCESS:/o) {
105a3144174Skspillner			$self->{state}->fatal("Synchronization error");
106a3144174Skspillner		}
107a3144174Skspillner		while (<$getfh>) {
108a3144174Skspillner			chomp;
109a3144174Skspillner			last if $_ eq '';
110a3144174Skspillner			push(@$l, $_);
111a3144174Skspillner		}
112a3144174Skspillner		$self->{list} = $l;
113a3144174Skspillner	}
114a3144174Skspillner	return $self->{list};
115a3144174Skspillner}
116a3144174Skspillner
117*039cbdaaSespiesub cleanup($self)
118a3144174Skspillner{
119a3144174Skspillner	if (defined $self->{controller}) {
120a3144174Skspillner		my $cmdfh = $self->{cmdfh};
121a3144174Skspillner		my $getfh = $self->{getfh};
122a3144174Skspillner		print $cmdfh "ABORT\nBYE\nBYE\n";
123a3144174Skspillner		CORE::close($cmdfh);
124a3144174Skspillner		CORE::close($getfh);
125a3144174Skspillner		waitpid($self->{controller}, 0);
1267b25c30aSespie		delete $self->{controller};
127a3144174Skspillner	}
128a3144174Skspillner}
129a3144174Skspillner
130*039cbdaaSespiesub dont_cleanup($self)
1317b25c30aSespie{
1327b25c30aSespie	CORE::close($self->{cmdfh});
1337b25c30aSespie	CORE::close($self->{getfh});
1347b25c30aSespie	delete $self->{controller};
1357b25c30aSespie}
1367b25c30aSespie
137*039cbdaaSespiesub reinitialize($self)
138a3144174Skspillner{
139a3144174Skspillner	$self->initiate;
140a3144174Skspillner}
141a3144174Skspillner
142a3144174Skspillner1;
143