<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!/usr/bin/perl -w
# This file was preprocessed, do not edit!


package Debconf::DbDriver::Directory;
use strict;
use Debconf::Log qw(:all);
use IO::File;
use POSIX ();
use Fcntl qw(:DEFAULT :flock);
use Debconf::Iterator;
use base 'Debconf::DbDriver::Cache';


use fields qw(directory extension lock format);


sub init {
	my $this=shift;

	$this-&gt;{extension} = "" unless exists $this-&gt;{extension};
	$this-&gt;{format} = "822" unless exists $this-&gt;{format};
	$this-&gt;{backup} = 1 unless exists $this-&gt;{backup};
	
	$this-&gt;error("No format specified") unless $this-&gt;{format};
	eval "use Debconf::Format::$this-&gt;{format}";
	if ($@) {
		$this-&gt;error("Error setting up format object $this-&gt;{format}: $@");
	}
	$this-&gt;{format}="Debconf::Format::$this-&gt;{format}"-&gt;new;
	if (not ref $this-&gt;{format}) {
		$this-&gt;error("Unable to make format object");
	}

	$this-&gt;error("No directory specified") unless $this-&gt;{directory};
	if (not -d $this-&gt;{directory} and not $this-&gt;{readonly}) {
		mkdir $this-&gt;{directory} ||
			$this-&gt;error("mkdir $this-&gt;{directory}:$!");
	}
	if (not -d $this-&gt;{directory}) {
		$this-&gt;error($this-&gt;{directory}." does not exist");
	}
	debug "db $this-&gt;{name}" =&gt; "started; directory is $this-&gt;{directory}";
	
	if (! $this-&gt;{readonly}) {
		open ($this-&gt;{lock}, "&gt;".$this-&gt;{directory}."/.lock") or
			$this-&gt;error("could not lock $this-&gt;{directory}: $!");
		while (! flock($this-&gt;{lock}, LOCK_EX | LOCK_NB)) {
			next if $! == &amp;POSIX::EINTR;
			$this-&gt;error("$this-&gt;{directory} is locked by another process: $!");
			last;
		}
	}
}


sub load {
	my $this=shift;
	my $item=shift;

	debug "db $this-&gt;{name}" =&gt; "loading $item";
	my $file=$this-&gt;{directory}.'/'.$this-&gt;filename($item);
	return unless -e $file;

	my $fh=IO::File-&gt;new;
	open($fh, $file) or $this-&gt;error("$file: $!");
	$this-&gt;cacheadd($this-&gt;{format}-&gt;read($fh));
	close $fh;
}


sub save {
	my $this=shift;
	my $item=shift;
	my $data=shift;
	
	return unless $this-&gt;accept($item);
	return if $this-&gt;{readonly};
	debug "db $this-&gt;{name}" =&gt; "saving $item";
	
	my $file=$this-&gt;{directory}.'/'.$this-&gt;filename($item);

	my $fh=IO::File-&gt;new;
	if ($this-&gt;ispassword($item)) {
		sysopen($fh, $file."-new", O_WRONLY|O_TRUNC|O_CREAT, 0600)
			or $this-&gt;error("$file-new: $!");
	}
	else {
		open($fh, "&gt;$file-new") or $this-&gt;error("$file-new: $!");
	}
	$this-&gt;{format}-&gt;beginfile;
	$this-&gt;{format}-&gt;write($fh, $data, $item)
		or $this-&gt;error("could not write $file-new: $!");
	$this-&gt;{format}-&gt;endfile;
	
	$fh-&gt;flush or $this-&gt;error("could not flush $file-new: $!");
	$fh-&gt;sync or $this-&gt;error("could not sync $file-new: $!");
	close $fh or $this-&gt;error("could not close $file-new: $!");
	
	if (-e $file &amp;&amp; $this-&gt;{backup}) {
		rename($file, $file."-old") or
			debug "db $this-&gt;{name}" =&gt; "rename failed: $!";
	}
	rename("$file-new", $file) or $this-&gt;error("rename failed: $!");
}


sub shutdown {
	my $this=shift;
	
	$this-&gt;SUPER::shutdown(@_);
	delete $this-&gt;{lock};
	return 1;
}


sub exists {
	my $this=shift;
	my $name=shift;
	
	my $incache=$this-&gt;SUPER::exists($name);
	return $incache if (!defined $incache or $incache);

	return -e $this-&gt;{directory}.'/'.$this-&gt;filename($name);
}


sub remove {
	my $this=shift;
	my $name=shift;

	return if $this-&gt;{readonly} or not $this-&gt;accept($name);
	debug "db $this-&gt;{name}" =&gt; "removing $name";
	my $file=$this-&gt;{directory}.'/'.$this-&gt;filename($name);
	unlink $file or return undef;
	if (-e $file."-old") {
		unlink $file."-old" or return undef;
	}
	return 1;
}


sub accept {
	my $this=shift;
	my $name=shift;

	return if $name=~m#\.\./# or $name=~m#/\.\.#;
	$this-&gt;SUPER::accept($name, @_);
}


1
</pre></body></html>