[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

apt cron script changes



greetings.

i made what i think are improvements to the /etc/cron.daily/apt script.

i currently use ubuntu breezy, fully updated.

im not sure if the script could have been changed or worked on in later debian versions (unstable), so i am attaching the full file incase the patch doesnt apply.

im still working on one area of the 'check_size_constraints' function, just below the '#check size' comment.


i am not subscribed to the list so please cc me in any response.

thanks.


--- apt.orig	2006-03-11 20:16:48.000000000 +0200
+++ apt	2006-04-19 12:59:40.000000000 +0200
@@ -1,30 +1,29 @@
 #!/bin/sh
 #
 
-#set -e
 #
 # This file understands the following apt configuration variables:
 #
-#  "APT::Periodic::Update-Package-Lists=1"
+#  APT::Periodic::Update-Package-Lists "1";
 #  - Do "apt-get update" automatically every n-days (0=disable)
 #    
-#  "APT::Periodic::Download-Upgradeable-Packages=0",
+#  APT::Periodic::Download-Upgradeable-Packages "1";
 #  - Do "apt-get upgrade --download-only" every n-days (0=disable)
 # 
-#  "APT::Periodic::AutocleanInterval"
+#  APT::Periodic::AutocleanInterval" "1";
 #  - Do "apt-get autoclean" every n-days (0=disable)
 #
-#  "APT::Archives::MaxAge",
+#  APT::Archives::MaxAge",
 #  - Set maximum allowed age of a cache package file. If a cache 
 #    package file is older it is deleted (0=disable)
 #
-#  "APT::Archives::MaxSize",
+#  APT::Archives::MaxSize",
 #  - Set maximum size of the cache in MB (0=disable). If the cache
 #    is bigger, cached package files are deleted until the size
 #    requirement is met (the biggest packages will be deleted 
 #    first).
 #
-#  "APT::Archives::MinAge"
+#  APT::Archives::MinAge"
 #  - Set minimum age of a package file. If a file is younger it
 #    will not be deleted (0=disable). Usefull to prevent races 
 #    and to keep backups of the packages for emergency.
@@ -32,39 +31,115 @@
 
 check_stamp()
 {
-    stamp="$1"
-    interval="$2"
+
+    if [[ "$#" -ne 2 ]]; then
+	echo "check_stamp: arguments to function does not equal 2, returning 1." 1>&2
+	return 1
+    fi
+
+
+    local file="$1"
+    local file_mod_time=""
+    local now=""
+
+    declare -i now_seconds=""
+    declare -i stamp=0
+    declare -i interval="$2"
+    declare -i delta=0
+    declare -i stamp_error=0
 
     if [ $interval -eq 0 ]; then
         return 1
     fi
 
-    if [ ! -f $stamp ]; then
+    if [ ! -f "$file" ]; then
         return 0
     fi
 
-    # compare midnight today to midnight the day the stamp was updated
-    stamp=$(date --date=$(date -r $stamp --iso-8601) +%s)
-    now=$(date --date=$(date --iso-8601) +%s)
-    delta=$(($now-$stamp))
-
-    # intervall is in days,
-    interval=$(($interval*60*60*24))
-    #echo "stampfile: $1"
-    #echo "interval=$interval, now=$now, stamp=$stamp, delta=$delta"
+    if file_mod_time=$(date -r $file --iso-8601 2>/dev/null); then
+	if [[ "$file_mod_time" =~ '^[0-9]{4}-[0-9]{2}-[0-9]{2}$' ]]; then
+		if stamp=$(date --date=${file_mod_time} +%s 2>/dev/null); then
+			if [[ "$stamp" -gt 0 ]]; then
+				if now=$(date --iso-8601 2>/dev/null); then
+					if [[ "$now" =~ '^[0-9]{4}-[0-9]{2}-[0-9]{2}$' ]]; then
+						if now_seconds=$(date --date=${now} +%s 2>/dev/null); then
+							if [[ "$now_seconds" -gt 0 ]]; then
+								delta=$((${now_seconds}-${stamp}))
+									if ! [[ "$delta" -ge 0 ]]; then
+										stamp_error=1
+									fi	
+							else
+								stamp_error=1
+							fi
+						else
+							stamp_error=1
+						fi
+					else
+						stamp_error=1
+					fi
+				else
+					stamp_error=1
+				fi
+			else
+				stamp_error=1
+			fi
+		else
+			stamp_error=1
+		fi
+	else
+		stamp_error=1
+	fi
+    else
+	stamp_error=1
+    fi
+
+
+    if [[ "$stamp_error" -eq 1 ]]; then
+	echo "timestamp calculation failed somewhere, file is ${file}, returning 1." 1>&2
+	return 1
+    fi				
+				
+
+    # interval is in days,
+    interval=$((${interval}*60*60*24))
+
+    if ! [[ "$interval" -gt 0 ]]; then
+	echo "check_stamp: variable 'interval' is not > 0, returning 1" 1>&2
+	return 1
+    fi
 
-    if [ $delta -ge $interval ]; then
+
+    if [ "$delta" -ge "$interval" ]; then
         return 0
+    else
+	return 1
     fi
 
-    return 1
 }
 
 update_stamp()
 {
-    stamp="$1"
 
-    touch $stamp
+
+    if [[ "$#" -ne 1 ]]; then
+	echo "update_stamp: number of arguments to functions is not exactly 1, returning 1." 1>&2
+	return 1
+
+    fi
+
+    local file="$1"
+
+
+    if [ ! -f "$file" ]; then
+        return 1
+    fi
+
+    if touch $file; then
+	return 0
+    else
+	return 1
+    fi
+
 }
 
 
@@ -72,33 +147,113 @@
 # we check here if autoclean was enough sizewise
 check_size_constraints()
 {
+
+    set --
+
     # min-age in days
-    MaxAge=0
-    MinAge=2
-    MaxSize=0
-    CacheDir="var/cache/apt"
-    CacheArchive="archives/"
-    eval $(apt-config shell MaxAge APT::Archives::MaxAge)
-    eval $(apt-config shell MinAge APT::Archives::MinAge)
-    eval $(apt-config shell MaxSize APT::Archives::MaxSize)
-    eval $(apt-config shell Dir Dir)
-    eval $(apt-config shell CacheDir Dir::Cache)
-    eval $(apt-config shell CacheArchive Dir::Cache::archives)
+    declare -i MaxAge=0
+    declare -i MinAge=2
+    declare -i MaxSize=0
+    local Dir="/"
+    local CacheDir="var/cache/apt"
+    local CacheArchive="archives/"
+    local to_run=""
+    local Cache=""
+    local tempfile=""
+    local tempdir=""
+    local filename=""
+
+    if ! to_run=$(apt-config shell MaxAge APT::Archives::MaxAge MinAge APT::Archives::MinAge MaxSize APT::Archives::MaxSize Dir Dir CacheDir Dir::Cache CacheArchive Dir::Cache::archives); then
+        echo "check_size_constraints: could not retrieve apt variables with apt-config, returning 1." 1>&2
+        return 1
+    fi
+
+    if ! eval "$to_run"; then
+       	echo "check_size_constraints: could not initialize apt variables, returning  1." 1>&2
+       	return 1
+    fi
+
 
     # sanity check
-    if [ -z "$CacheDir" -o -z "$CacheArchive" ]; then
-	echo "empty Dir::Cache or Dir::Cache::archives, exiting"
-	exit
+    if [ -z "$CacheDir" -o -z "$CacheArchive" -o -z "$Dir" ]; then
+	echo "check_size_constraints: empty Dir::Cache or Dir::Cache::archives or Dir in apt config, returning 1." 1>&2
+	return 1
     fi
+
+    if ! [[ "$MaxAge" -ge 0 && "$MinAge" -ge 0 && "$MaxSize" -ge 0 ]]; then
+	echo "check_size_constraints: variable MaxAge or MinAge or MaxSize is not >= 0, returning 1." 1>&2
+	return 1
+    fi
+
+    if ! [[ "$CacheDir" =~ '^[a-zA-Z0-9/_-]+$' && "$Dir" =~ '^[a-zA-Z0-9/_-]+$' && "$CacheArchive" =~ '^[a-zA-Z0-9/_-]+$' ]]; then
+	echo "check_size_constraints: variables CacheDir or Dir or CacheArchive failed syntax check, returning 1." 1>&2
+	return 1
+    fi
+
+
     
-    Cache="${Dir%/}/${CacheDir%/}/${CacheArchive%/}/"
+
+    Cache="${Dir%/}/${CacheDir%/}/${CacheArchive%/}"
+
+
+    if ! [[ -d "$Cache" && -r "$Cache" && -w "$Cache" ]]; then
+	echo "check_size_constraints: directory '$Cache' does not exist or is not readable or writable, returning 1." 1>&2
+	return 1
+    fi
+
+
 
     # check age
-    if [ ! $MaxAge -eq 0 ] && [ ! $MinAge -eq 0 ]; then
-	find $Cache -name "*.deb"  \( -mtime +$MaxAge -and -ctime +$MaxAge \) -and -not \( -mtime -$MinAge -or -ctime -$MinAge \) -print0 | xargs -r -0 rm -f
-    elif [ ! $MaxAge -eq 0 ]; then
-	find $Cache -name "*.deb"  -ctime +$MaxAge -and -mtime +$MaxAge -print0 | xargs -r -0 rm -f
+    if [[ "$MaxAge" -gt 0 ]]; then
+
+	TMPDIR=""
+
+	if [[ -d "/var/tmp" && -r "/var/tmp" && -w "/var/tmp" ]]; then
+		tmpdir="/var/tmp"
+	else
+		tmpdir="/tmp"
+	fi
+
+	
+	trap "rm -f $tempfile" 1 2 3 15 
+	if tempfile=$(mktemp -p $tmpdir aptcronscript.XXXXXX); then
+
+		#the reason why MaxAge is reduced by 1:
+		#in find(1)
+		#When find figures out how many 24-hour periods ago the file was last accessed,
+		#any fractional part is ignored, so to match -atime +1, a file has to have been modified at least two days ago.	
+		#same seems to apply for ctime and mtime
+
+    		if [ ! $MaxAge -eq 0 ] && [ ! $MinAge -eq 0 ]; then
+	 		find $Cache -name "*.deb"  \( -mtime +$(($MaxAge - 1)) -and -ctime +$(($MaxAge -1 )) \) -and -not \( -mtime -$MinAge -or -ctime -$MinAge \) > $tempfile
+    		elif [ ! $MaxAge -eq 0 ]; then
+			find $Cache -name "*.deb"  -ctime +$(($MaxAge - 1)) -and -mtime +$(($MaxAge - 1)) > $tempfile
+    		fi
+
+
+		if [[ -s "$tempfile" ]]; then
+			{
+				while read filename; do
+					if ! rm -f $filename; then
+						echo "check_size_constraints: failed to remove file '$filename'" 1>&2
+					fi
+				done;
+			} < ${tempfile}
+		fi
+
+
+	else
+		echo "check_size_constraints: creating temp file returned non-zero status, returning 1." 1>&2
+		return 1
+	fi
+
+	rm -f $tempfile
+	trap - 1 2 3 15
+
     fi
+
+
+
     
     # check size
     if [ ! $MaxSize -eq 0 ]; then
@@ -111,11 +266,13 @@
 
 	# reverse-sort by mtime
 	for file in $(ls -rt $Cache/*.deb 2>/dev/null); do 
+echo "$file"
 	    du=$(du -s $Cache)
 	    size=${du%%/*}
 	    # check if the cache is small enough
 	    if [ $size -lt $MaxSize ]; then
-		break
+		#break
+		continue
 	    fi
 
 	    # check for MinAge of the file
@@ -131,7 +288,8 @@
 		#echo "$file ($delta), $MinAge"
 		if [ $delta -le $MinAge ]; then
 		    #echo "Skiping $file (delta=$delta)"
-		    break
+		    #break
+		    continue
 		fi
 	    fi
 
@@ -142,11 +300,48 @@
 }
 
 
-UpdateInterval=0
-DownloadUpgradeableInterval=0
-eval $(apt-config shell UpdateInterval APT::Periodic::Update-Package-Lists DownloadUpgradeableInterval APT::Periodic::Download-Upgradeable-Packages)
-AutocleanInterval=$DownloadUpgradeableInterval
-eval $(apt-config shell AutocleanInterval APT::Periodic::Autoclean)
+declare -i UpdateInterval=0
+declare -i DownloadUpgradeableInterval=0
+declare -i AutocleanInterval=0
+
+to_run=""
+
+if ! to_run=$(apt-config shell UpdateInterval APT::Periodic::Update-Package-Lists DownloadUpgradeableInterval APT::Periodic::Download-Upgradeable-Packages AutocleanInterval APT::Periodic::AutocleanInterval 2>/dev/null); then
+	echo "could not retrieve apt variables with apt-config, exiting." 1>&2
+	exit 1
+fi
+
+if ! eval "$to_run"; then
+	echo "could not initialize apt variables, exiting." 1>&2
+	exit 1
+fi
+
+if ! [[ "$UpdateInterval" -ge 0 && "$DownloadUpgradeableInterval" -ge 0 && "$AutocleanInterval" -ge 0 ]]; then
+	echo "variable UpdateInterval or DownloadUpgradeableInterval is not >= 0, exiting." 1>&2
+	exit 1
+fi
+
+
+if [[ "$UpdateInterval" -eq 0 && "$DownloadUpgradeableInterval" -gt 0 ]]; then
+	echo "note : package index file syncronization has been disabled, yet upgradeable package downloads have been enabled." 1>&2
+fi
+
+
+if [[ "$DownloadUpgradeableInterval" -lt "$UpdateInterval" ]]; then
+	echo "note : the package index file synchronization interval is longer then the upgradeable package download interval." 1>&2
+fi
+
+
+
+declare -i AutocleanInterval=${AutocleanInterval:-DownloadUpgradeableInterval}
+
+if ! [[ "$AutocleanInterval" -ge 0 ]]; then
+	echo "variable AutocleanInterval is not >= 0, exiting." 1>&2
+	exit 1
+fi
+
+
+
 
 # laptop check, on_ac_power returns:
 #       0 (true)    System is on mains power
@@ -156,31 +351,97 @@
 if which on_ac_power >/dev/null; then
     on_ac_power
     if [ $? -eq 1 ]; then
+	echo "on_ac_power determined system to not be powered by mains, exiting." 1>&2
 	exit 0
     fi
 fi
 
-UPDATE_STAMP=/var/lib/apt/periodic/update-stamp
+
+# since we're working with timestamps in the directory, non-root users should not be able to change timestamps of files
+# within the directory, if it looks like users can do this, the script exits.
+# note: this only accomodates for the standard unix permissions model, ACL's could still allow a non-root user to change timestamps
+# of files in the directory.
+
+if ! [[ "$(stat -c %u /var/lib/apt/periodic 2>/dev/null)" == "0" && "$(stat -c %a /var/lib/apt/periodic 2>/dev/null)" == "755" ]]; then
+        echo "directory /var/lib/apt/periodic isnt owned by root or doesnt have permissions 755, exiting." 1>&2
+	exit 1
+fi
+
+
+
+UPDATE_STAMP="/var/lib/apt/periodic/update-stamp"
 if check_stamp $UPDATE_STAMP $UpdateInterval; then
-    if apt-get -qq update 2>/dev/null; then
+    echo "--- running apt-get update ---" 1>&2
+
+    #not pipeing stderr to /dev/null since we want to see the errors if the command fails
+    #since this script is run by cron, errors of this command will be in the mail cron sends, which is usefull
+
+    apt-get -qq update 
+    if [[ "$?" -eq 0 ]]; then
 	if which dbus-send >/dev/null; then
 	    dbus-send --system / app.apt.dbus.updated boolean:true
 	fi
-        update_stamp $UPDATE_STAMP
+
+        if ! update_stamp $UPDATE_STAMP; then
+		echo "updating timestamp of file '$UPDATE_STAMP' failed." 1>&2
+	fi
+    else
+	echo "" 1>&2
+	echo "'apt-get update' returned non-zero status, exiting." 1>&2
+	exit 1
     fi
 fi
 
-DOWNLOAD_UPGRADEABLE_STAMP=/var/lib/apt/periodic/download-upgradeable-stamp
+
+
+
+DOWNLOAD_UPGRADEABLE_STAMP="/var/lib/apt/periodic/download-upgradeable-stamp"
 if check_stamp $DOWNLOAD_UPGRADEABLE_STAMP $DownloadUpgradeableInterval; then
-    apt-get -qq -d dist-upgrade 2>/dev/null
-    update_stamp $DOWNLOAD_UPGRADEABLE_STAMP
+    echo "---running apt-get -d dist-upgrade ---" 1>&2
+
+    #not pipeing stderr to /dev/null since we want to see the errors if the command fails
+    #since this script is run by cron, errors of this command will be in the mail cron sends, which is usefull
+
+    apt-get -qq -d dist-upgrade
+    if [[ "$?" -eq 0 ]]; then
+    	if ! update_stamp $DOWNLOAD_UPGRADEABLE_STAMP; then
+		echo "updating timestamp of file '$DOWNLOAD_UPGRADEABLE_STAMP' failed." 1>&2
+	fi
+    else
+	echo "" 1>&2
+	echo "'apt-get -d dist-upgrade' returned non-zero status, exiting." 1>&2
+	exit 1
+    fi
 fi
 
-AUTOCLEAN_STAMP=/var/lib/apt/periodic/autoclean-stamp
+
+
+
+AUTOCLEAN_STAMP="/var/lib/apt/periodic/autoclean-stamp"
 if check_stamp $AUTOCLEAN_STAMP $AutocleanInterval; then
+    echo "---running apt-get autoclean ---" 1>&2
+
+    #not pipeing stderr to /dev/null since we want to see the errors if the command fails
+    #since this script is run by cron, errors of this command will be in the mail cron sends, which is usefull
+
     apt-get -qq autoclean
-    update_stamp $AUTOCLEAN_STAMP
+    if [[ "$?" -eq 0 ]]; then
+    	if ! update_stamp $AUTOCLEAN_STAMP; then
+		echo "updateing timestamp of file '$AUTOCLEAN_STAMP' failed." 1>&2
+	fi
+    else
+	echo "" 1>&2
+	echo "'apt-get autoclean' returned non-zero status." 1>&2
+    fi
 fi
 
+
+
 # check cache size 
-check_size_constraints
+if ! check_size_constraints; then
+	echo "function check_size_constraints returned with a non-zero status!." 1>&2
+fi
+
+
+
+

#!/bin/sh
#

#
# This file understands the following apt configuration variables:
#
#  APT::Periodic::Update-Package-Lists "1";
#  - Do "apt-get update" automatically every n-days (0=disable)
#    
#  APT::Periodic::Download-Upgradeable-Packages "1";
#  - Do "apt-get upgrade --download-only" every n-days (0=disable)
# 
#  APT::Periodic::AutocleanInterval" "1";
#  - Do "apt-get autoclean" every n-days (0=disable)
#
#  APT::Archives::MaxAge",
#  - Set maximum allowed age of a cache package file. If a cache 
#    package file is older it is deleted (0=disable)
#
#  APT::Archives::MaxSize",
#  - Set maximum size of the cache in MB (0=disable). If the cache
#    is bigger, cached package files are deleted until the size
#    requirement is met (the biggest packages will be deleted 
#    first).
#
#  APT::Archives::MinAge"
#  - Set minimum age of a package file. If a file is younger it
#    will not be deleted (0=disable). Usefull to prevent races 
#    and to keep backups of the packages for emergency.
# 

check_stamp()
{

    if [[ "$#" -ne 2 ]]; then
	echo "check_stamp: arguments to function does not equal 2, returning 1." 1>&2
	return 1
    fi


    local file="$1"
    local file_mod_time=""
    local now=""

    declare -i now_seconds=""
    declare -i stamp=0
    declare -i interval="$2"
    declare -i delta=0
    declare -i stamp_error=0

    if [ $interval -eq 0 ]; then
        return 1
    fi

    if [ ! -f "$file" ]; then
        return 0
    fi

    if file_mod_time=$(date -r $file --iso-8601 2>/dev/null); then
	if [[ "$file_mod_time" =~ '^[0-9]{4}-[0-9]{2}-[0-9]{2}$' ]]; then
		if stamp=$(date --date=${file_mod_time} +%s 2>/dev/null); then
			if [[ "$stamp" -gt 0 ]]; then
				if now=$(date --iso-8601 2>/dev/null); then
					if [[ "$now" =~ '^[0-9]{4}-[0-9]{2}-[0-9]{2}$' ]]; then
						if now_seconds=$(date --date=${now} +%s 2>/dev/null); then
							if [[ "$now_seconds" -gt 0 ]]; then
								delta=$((${now_seconds}-${stamp}))
									if ! [[ "$delta" -ge 0 ]]; then
										stamp_error=1
									fi	
							else
								stamp_error=1
							fi
						else
							stamp_error=1
						fi
					else
						stamp_error=1
					fi
				else
					stamp_error=1
				fi
			else
				stamp_error=1
			fi
		else
			stamp_error=1
		fi
	else
		stamp_error=1
	fi
    else
	stamp_error=1
    fi


    if [[ "$stamp_error" -eq 1 ]]; then
	echo "timestamp calculation failed somewhere, file is ${file}, returning 1." 1>&2
	return 1
    fi				
				

    # interval is in days,
    interval=$((${interval}*60*60*24))

    if ! [[ "$interval" -gt 0 ]]; then
	echo "check_stamp: variable 'interval' is not > 0, returning 1" 1>&2
	return 1
    fi


    if [ "$delta" -ge "$interval" ]; then
        return 0
    else
	return 1
    fi

}

update_stamp()
{


    if [[ "$#" -ne 1 ]]; then
	echo "update_stamp: number of arguments to functions is not exactly 1, returning 1." 1>&2
	return 1

    fi

    local file="$1"


    if [ ! -f "$file" ]; then
        return 1
    fi

    if touch $file; then
	return 0
    else
	return 1
    fi

}



# we check here if autoclean was enough sizewise
check_size_constraints()
{

    set --

    # min-age in days
    declare -i MaxAge=0
    declare -i MinAge=2
    declare -i MaxSize=0
    local Dir="/"
    local CacheDir="var/cache/apt"
    local CacheArchive="archives/"
    local to_run=""
    local Cache=""
    local tempfile=""
    local tempdir=""
    local filename=""

    if ! to_run=$(apt-config shell MaxAge APT::Archives::MaxAge MinAge APT::Archives::MinAge MaxSize APT::Archives::MaxSize Dir Dir CacheDir Dir::Cache CacheArchive Dir::Cache::archives); then
        echo "check_size_constraints: could not retrieve apt variables with apt-config, returning 1." 1>&2
        return 1
    fi

    if ! eval "$to_run"; then
       	echo "check_size_constraints: could not initialize apt variables, returning  1." 1>&2
       	return 1
    fi


    # sanity check
    if [ -z "$CacheDir" -o -z "$CacheArchive" -o -z "$Dir" ]; then
	echo "check_size_constraints: empty Dir::Cache or Dir::Cache::archives or Dir in apt config, returning 1." 1>&2
	return 1
    fi

    if ! [[ "$MaxAge" -ge 0 && "$MinAge" -ge 0 && "$MaxSize" -ge 0 ]]; then
	echo "check_size_constraints: variable MaxAge or MinAge or MaxSize is not >= 0, returning 1." 1>&2
	return 1
    fi

    if ! [[ "$CacheDir" =~ '^[a-zA-Z0-9/_-]+$' && "$Dir" =~ '^[a-zA-Z0-9/_-]+$' && "$CacheArchive" =~ '^[a-zA-Z0-9/_-]+$' ]]; then
	echo "check_size_constraints: variables CacheDir or Dir or CacheArchive failed syntax check, returning 1." 1>&2
	return 1
    fi


    

    Cache="${Dir%/}/${CacheDir%/}/${CacheArchive%/}"


    if ! [[ -d "$Cache" && -r "$Cache" && -w "$Cache" ]]; then
	echo "check_size_constraints: directory '$Cache' does not exist or is not readable or writable, returning 1." 1>&2
	return 1
    fi



    # check age
    if [[ "$MaxAge" -gt 0 ]]; then

	TMPDIR=""

	if [[ -d "/var/tmp" && -r "/var/tmp" && -w "/var/tmp" ]]; then
		tmpdir="/var/tmp"
	else
		tmpdir="/tmp"
	fi

	
	trap "rm -f $tempfile" 1 2 3 15 
	if tempfile=$(mktemp -p $tmpdir aptcronscript.XXXXXX); then

		#the reason why MaxAge is reduced by 1:
		#in find(1)
		#When find figures out how many 24-hour periods ago the file was last accessed,
		#any fractional part is ignored, so to match -atime +1, a file has to have been modified at least two days ago.	
		#same seems to apply for ctime and mtime

    		if [ ! $MaxAge -eq 0 ] && [ ! $MinAge -eq 0 ]; then
	 		find $Cache -name "*.deb"  \( -mtime +$(($MaxAge - 1)) -and -ctime +$(($MaxAge -1 )) \) -and -not \( -mtime -$MinAge -or -ctime -$MinAge \) > $tempfile
    		elif [ ! $MaxAge -eq 0 ]; then
			find $Cache -name "*.deb"  -ctime +$(($MaxAge - 1)) -and -mtime +$(($MaxAge - 1)) > $tempfile
    		fi


		if [[ -s "$tempfile" ]]; then
			{
				while read filename; do
					if ! rm -f $filename; then
						echo "check_size_constraints: failed to remove file '$filename'" 1>&2
					fi
				done;
			} < ${tempfile}
		fi


	else
		echo "check_size_constraints: creating temp file returned non-zero status, returning 1." 1>&2
		return 1
	fi

	rm -f $tempfile
	trap - 1 2 3 15

    fi



    
    # check size
    if [ ! $MaxSize -eq 0 ]; then
	# maxSize is in MB
	MaxSize=$(($MaxSize*1024))

	#get current time
	now=$(date --date=$(date --iso-8601) +%s)
	MinAge=$(($MinAge*24*60*60))

	# reverse-sort by mtime
	for file in $(ls -rt $Cache/*.deb 2>/dev/null); do 
echo "$file"
	    du=$(du -s $Cache)
	    size=${du%%/*}
	    # check if the cache is small enough
	    if [ $size -lt $MaxSize ]; then
		#break
		continue
	    fi

	    # check for MinAge of the file
	    if [ ! $MinAge -eq 0 ]; then 
		# check both ctime and mtime 
		mtime=$(stat -c %Y $file)
		ctime=$(stat -c %Z $file)
		if [ $mtime -gt $ctime ]; then
		    delta=$(($now-$mtime))
		else
		    delta=$(($now-$ctime))
		fi
		#echo "$file ($delta), $MinAge"
		if [ $delta -le $MinAge ]; then
		    #echo "Skiping $file (delta=$delta)"
		    #break
		    continue
		fi
	    fi

	    # delete oldest file
	    rm -f $file
	done
    fi
}


declare -i UpdateInterval=0
declare -i DownloadUpgradeableInterval=0
declare -i AutocleanInterval=0

to_run=""

if ! to_run=$(apt-config shell UpdateInterval APT::Periodic::Update-Package-Lists DownloadUpgradeableInterval APT::Periodic::Download-Upgradeable-Packages AutocleanInterval APT::Periodic::AutocleanInterval 2>/dev/null); then
	echo "could not retrieve apt variables with apt-config, exiting." 1>&2
	exit 1
fi

if ! eval "$to_run"; then
	echo "could not initialize apt variables, exiting." 1>&2
	exit 1
fi

if ! [[ "$UpdateInterval" -ge 0 && "$DownloadUpgradeableInterval" -ge 0 && "$AutocleanInterval" -ge 0 ]]; then
	echo "variable UpdateInterval or DownloadUpgradeableInterval is not >= 0, exiting." 1>&2
	exit 1
fi


if [[ "$UpdateInterval" -eq 0 && "$DownloadUpgradeableInterval" -gt 0 ]]; then
	echo "note : package index file syncronization has been disabled, yet upgradeable package downloads have been enabled." 1>&2
fi


if [[ "$DownloadUpgradeableInterval" -lt "$UpdateInterval" ]]; then
	echo "note : the package index file synchronization interval is longer then the upgradeable package download interval." 1>&2
fi



declare -i AutocleanInterval=${AutocleanInterval:-DownloadUpgradeableInterval}

if ! [[ "$AutocleanInterval" -ge 0 ]]; then
	echo "variable AutocleanInterval is not >= 0, exiting." 1>&2
	exit 1
fi




# laptop check, on_ac_power returns:
#       0 (true)    System is on mains power
#       1 (false)   System is not on mains power
#       255 (false) Power status could not be determined
# Desktop systems always return 255 it seems
if which on_ac_power >/dev/null; then
    on_ac_power
    if [ $? -eq 1 ]; then
	echo "on_ac_power determined system to not be powered by mains, exiting." 1>&2
	exit 0
    fi
fi


# since we're working with timestamps in the directory, non-root users should not be able to change timestamps of files
# within the directory, if it looks like users can do this, the script exits.
# note: this only accomodates for the standard unix permissions model, ACL's could still allow a non-root user to change timestamps
# of files in the directory.

if ! [[ "$(stat -c %u /var/lib/apt/periodic 2>/dev/null)" == "0" && "$(stat -c %a /var/lib/apt/periodic 2>/dev/null)" == "755" ]]; then
        echo "directory /var/lib/apt/periodic isnt owned by root or doesnt have permissions 755, exiting." 1>&2
	exit 1
fi



UPDATE_STAMP="/var/lib/apt/periodic/update-stamp"
if check_stamp $UPDATE_STAMP $UpdateInterval; then
    echo "--- running apt-get update ---" 1>&2

    #not pipeing stderr to /dev/null since we want to see the errors if the command fails
    #since this script is run by cron, errors of this command will be in the mail cron sends, which is usefull

    apt-get -qq update 
    if [[ "$?" -eq 0 ]]; then
	if which dbus-send >/dev/null; then
	    dbus-send --system / app.apt.dbus.updated boolean:true
	fi

        if ! update_stamp $UPDATE_STAMP; then
		echo "updating timestamp of file '$UPDATE_STAMP' failed." 1>&2
	fi
    else
	echo "" 1>&2
	echo "'apt-get update' returned non-zero status, exiting." 1>&2
	exit 1
    fi
fi




DOWNLOAD_UPGRADEABLE_STAMP="/var/lib/apt/periodic/download-upgradeable-stamp"
if check_stamp $DOWNLOAD_UPGRADEABLE_STAMP $DownloadUpgradeableInterval; then
    echo "---running apt-get -d dist-upgrade ---" 1>&2

    #not pipeing stderr to /dev/null since we want to see the errors if the command fails
    #since this script is run by cron, errors of this command will be in the mail cron sends, which is usefull

    apt-get -qq -d dist-upgrade
    if [[ "$?" -eq 0 ]]; then
    	if ! update_stamp $DOWNLOAD_UPGRADEABLE_STAMP; then
		echo "updating timestamp of file '$DOWNLOAD_UPGRADEABLE_STAMP' failed." 1>&2
	fi
    else
	echo "" 1>&2
	echo "'apt-get -d dist-upgrade' returned non-zero status, exiting." 1>&2
	exit 1
    fi
fi




AUTOCLEAN_STAMP="/var/lib/apt/periodic/autoclean-stamp"
if check_stamp $AUTOCLEAN_STAMP $AutocleanInterval; then
    echo "---running apt-get autoclean ---" 1>&2

    #not pipeing stderr to /dev/null since we want to see the errors if the command fails
    #since this script is run by cron, errors of this command will be in the mail cron sends, which is usefull

    apt-get -qq autoclean
    if [[ "$?" -eq 0 ]]; then
    	if ! update_stamp $AUTOCLEAN_STAMP; then
		echo "updateing timestamp of file '$AUTOCLEAN_STAMP' failed." 1>&2
	fi
    else
	echo "" 1>&2
	echo "'apt-get autoclean' returned non-zero status." 1>&2
    fi
fi



# check cache size 
if ! check_size_constraints; then
	echo "function check_size_constraints returned with a non-zero status!." 1>&2
fi





Reply to: