;# $Id: plsave.pl,v 3.0.1.1 1996/12/24 14:57:58 ram Exp $
;#
;#  Copyright (c) 1990-1993, Raphael Manfredi
;#  
;#  You may redistribute only under the terms of the Artistic License,
;#  as specified in the README file that comes with the distribution.
;#  You may reuse parts of this distribution only within the terms of
;#  that same Artistic License; a copy of which may be found at the root
;#  of the source tree for mailagent 3.0.
;#
;# $Log: plsave.pl,v $
;# Revision 3.0.1.1  1996/12/24 14:57:58  ram
;# patch45: allow '-' in package names
;#
;# Revision 3.0  1993/11/29  13:49:06  ram
;# Baseline for mailagent 3.0 netwide release.
;#
;#
;# This file relies on the following external conditions:
;#    - operation &fatal() available for fatal errors
;#    - the configuration variables are properly set
;#    - logging is done via &add_log()
;#    - routines for locking files are available
;#
# Read stored informations for archived systems. The format of
# the file is the following:
#	system version patchlevel mtime
# where:
#	- system is the name of the system
#	- version is the version number or --- if none
#	- patchlevel is the current patchlevel, or -2 if no PL
#	- mtime is the modification time of the archive
#
# The function builds the following associative array, indexed
# by the system's name and version number (which has to be a null
# string for systems with no version number, marked '---'):
#
# name          indexed by       information
#
# %PSystem      name + version   true if line seen
# %Patch_level  name + version   current patch level
# %Mtime        name + version   last modification time
#
# If the 'plsave' file is not found, a new empty one is created
#
sub read_plsave {
	local($fullname);
	if (!open(PATLIST, "$cf'plsave")) {
		&add_log("creating new patlist file") if $loglvl > 8;
		system 'cp', '/dev/null', $cf'plsave;
		open(PATLIST, "$cf'plsave") ||
			&fatal("cannot open patlist file");
	}
	while (<PATLIST>) {
		next if /^\s*#/;	# skip comments
		next if /^\s*$/;	# skip empty lines
		next unless s/^\s*([\w-]+)\s+([\w\.]+)//;
		$fullname = $1 . "|" . ($2 eq '---'? "0" : $2);
		if (defined($PSystem{$fullname})) {
			&add_log("WARNING duplicate patlist entry $1 $2 ignored")
				if $loglvl > 5;
			next;
		}
		$PSystem{$fullname}++;
		unless (/^\s*([\-\d]+)\s+(\d+)/) {
			&add_log("WARNING bad patlist description line $.")
				if $loglvl > 5;
			next;	# Ignore, but it may corrupt further processing
		}
		$Patch_level{$fullname} = $1;
		$Mtime{$fullname} = $2;
	}
	close PATLIST;
}

# Write the new 'plsave', but only if the distributions are found
# in the %Program array (I assume read_dist() has been called).
# The 'plsave' file is locked during the updating process, so that
# no conflicting access occurs. There is a small chance that the
# file we write is not correct, in case the distribution file changed
# while we were processing a mail. However, it isn't a big problem.
sub write_plsave {
	local($lockext) = ".lock";		# Needed by checklock (via acs_rqst)
	local($system);
	local($version);
	if (0 != &acs_rqst($cf'plsave)) {
		&add_log("WARNING updating unlocked patlist file") if $loglvl > 5;
	}
	if (!open(PATLIST, ">$cf'plsave")) {
		&add_log("ERROR unable to update $cf'plsave") if $loglvl;
		return;
	}
	print PATLIST
"# This file was automatically generated by $prog_name.
# It records the archived distributions, their patch level if any, and
# the modification time of the archive, so that these informations can
# be updated when necessary. Do not edit this file.

";
	foreach $pname (keys %PSystem) {
		if ($Archived{$pname}) {
			($system, $version) = $pname =~ /^([\w-]+)\|([\w\.]+)*$/;
			$version = '---' if $version eq '0';
			print PATLIST "$system $version ";
			print PATLIST "$Patch_level{$pname} $Mtime{$pname}\n";
			&add_log("updated patlist for $system $version") if $loglvl > 18;
		} else {
			&add_log("$system $version removed from patlist") if $loglvl > 18;
		}
	}
	close PATLIST;
	&free_file($cf'plsave);
}

