=== added file 'includes/archiver.inc'
--- includes/archiver.inc	1970-01-01 00:00:00 +0000
+++ includes/archiver.inc	2009-10-15 03:44:50 +0000
@@ -0,0 +1,150 @@
+<?php
+
+/**
+ * @file
+ * Shared classes and interfaces for the archiver system.
+ */
+
+/**
+ * Common interface for all Archiver classes.
+ *
+ * This interface is deliberately designed to mimic the de facto
+ * interface of Archive_Tar.
+ */
+interface ArchiverInterface {
+
+    /**
+    * This method creates the archive file and add the files / directories
+    * that are listed in $p_filelist.
+    * If a file with the same name exist and is writable, it is replaced
+    * by the new tar.
+    * The method return false and a PEAR error text.
+    * The $p_filelist parameter can be an array of string, each string
+    * representing a filename or a directory name with their path if
+    * needed. It can also be a single string with names separated by a
+    * single blank.
+    * For each directory added in the archive, the files and
+    * sub-directories are also added.
+    * See also createModify() method for more details.
+    *
+    * @param array  $p_filelist An array of filenames and directory names, or a
+    *                           single string with names separated by a single
+    *                           blank space.
+    * @return                   true on success, false on error.
+    * @see createModify()
+    * @access public
+    */
+    public function create($p_filelist);
+
+    /**
+    * This method add the files / directories that are listed in $p_filelist in
+    * the archive. If the archive does not exist it is created.
+    * The method return false and a PEAR error text.
+    * The files and directories listed are only added at the end of the archive,
+    * even if a file with the same name is already archived.
+    * See also createModify() method for more details.
+    *
+    * @param array  $p_filelist An array of filenames and directory names, or a
+    *                           single string with names separated by a single
+    *                           blank space.
+    * @return                   true on success, false on error.
+    * @see createModify()
+    * @access public
+    */
+    public function add($p_filelist);
+
+    /**
+    * This method extract all the content of the archive in the directory
+    * indicated by $p_path. When relevant the memorized path of the
+    * files/dir can be modified by removing the $p_remove_path path at the
+    * beginning of the file/dir path.
+    * While extracting a file, if the directory path does not exists it is
+    * created.
+    * While extracting a file, if the file already exists it is replaced
+    * without looking for last modification date.
+    * While extracting a file, if the file already exists and is write
+    * protected, the extraction is aborted.
+    * While extracting a file, if a directory with the same name already
+    * exists, the extraction is aborted.
+    * While extracting a directory, if a file with the same name already
+    * exists, the extraction is aborted.
+    * While extracting a file/directory if the destination directory exist
+    * and is write protected, or does not exist but can not be created,
+    * the extraction is aborted.
+    * If after extraction an extracted file does not show the correct
+    * stored file size, the extraction is aborted.
+    * When the extraction is aborted, a PEAR error text is set and false
+    * is returned. However the result can be a partial extraction that may
+    * need to be manually cleaned.
+    *
+    * @param string $p_path         The path of the directory where the
+    *                               files/dir need to by extracted.
+    * @param string $p_remove_path  Part of the memorized path that can be
+    *                               removed if present at the beginning of
+    *                               the file/dir path.
+    * @return boolean               true on success, false on error.
+    * @access public
+    * @see extractList()
+    */
+    public function extract($p_path='');
+
+    /**
+     * I have no idea what this does. :-)
+     */
+    public function listContent();
+
+    /**
+    * This method add a single string as a file at the
+    * end of the existing archive. If the archive does not yet exists it
+    * is created.
+    *
+    * @param string     $p_filename     A string which contains the full
+    *                                   filename path that will be associated
+    *                                   with the string.
+    * @param string     $p_string       The content of the file added in
+    *                                   the archive.
+    * @return                           true on success, false on error.
+    * @access public
+    */
+    public function addString($p_filename, $p_string);
+
+   /**
+    * This method extract from the archive one file identified by $p_filename.
+    * The return value is a string with the file content, or NULL on error.
+    * @param string $p_filename     The path of the file to extract in a string.
+    * @return                       a string with the file content or NULL.
+    * @access public
+    */
+    public function extractInString($p_filename);
+
+   /**
+    * This method extract from the archive only the files indicated in the
+    * $p_filelist. These files are extracted in the current directory or
+    * in the directory indicated by the optional $p_path parameter.
+    * If indicated the $p_remove_path can be used in the same way as it is
+    * used in extractModify() method.
+    * @param array  $p_filelist     An array of filenames and directory names,
+    *                               or a single string with names separated
+    *                               by a single blank space.
+    * @param string $p_path         The path of the directory where the
+    *                               files/dir need to by extracted.
+    * @param string $p_remove_path  Part of the memorized path that can be
+    *                               removed if present at the beginning of
+    *                               the file/dir path.
+    * @return                       true on success, false on error.
+    * @access public
+    * @see extractModify()
+    */
+    public function extractList($p_filelist, $p_path='', $p_remove_path='');
+
+    /**
+    * This method set specific attributes of the archive. It uses a variable
+    * list of parameters, in the format attribute code + attribute values :
+    * $arch->setAttribute(ARCHIVE_TAR_ATT_SEPARATOR, ',');
+    * @param mixed $argv            variable list of attributes and values
+    * @return                       true on success, false on error.
+    * @access public
+    */
+    public function setAttribute();
+}
+

=== modified file 'includes/common.inc'
--- includes/common.inc	2009-10-13 21:16:42 +0000
+++ includes/common.inc	2009-10-15 03:24:12 +0000
@@ -5797,3 +5797,47 @@ function xmlrpc($url) {
   return call_user_func_array('_xmlrpc', $args);
 }
 
+/**
+ * Retrieve a list of all available archivers.
+ */
+function archiver_get_info() {
+  $archiver_info = &drupal_static(__FUNCTION__, array());
+
+  if (empty($archiver_info)) {
+    $cache = cache_get('archiver_info');
+    if ($cache === FALSE) {
+      // Rebuild the cache and save it.
+      $archiver_info = module_invoke_all('archiver_info');
+      drupal_alter('archiver_info', $archiver_info);
+      uasort($archiver_info, 'drupal_sort_weight');
+      cache_set('archiver_info', $archiver_info);
+    }
+    else {
+      $archiver_info = $cache->data;
+    }
+  }
+
+  return $archiver_info;
+}
+
+/**
+ * Create the appropriate archiver for the specified file.
+ *
+ * @param $file
+ *   The full path of the archive file.  Note that stream wrapper
+ *   paths are supported.
+ * @return
+ *   A newly created instance of the archiver class appropriate
+ *   for the specified file, already bound to that file.
+ */
+function archiver_get_archiver($file) {
+  $archiver_info = archiver_get_info();
+
+  $extension = pathinfo($file, PATHINFO_EXTENSION);
+
+  foreach ($archiver_info as $implementation) {
+    if (in_array($extension, $implementation['extensions'])) {
+      return new $implementation['class']($file);
+    }
+  }
+}

=== modified file 'modules/system/system.api.php'
--- modules/system/system.api.php	2009-10-14 10:56:35 +0000
+++ modules/system/system.api.php	2009-10-15 03:21:07 +0000
@@ -2288,7 +2288,7 @@ function hook_drupal_goto_alter(array $a
  *   the Drupal installation process that occurs after the installation profile
  *   is selected.
  * @param $install_state
- *   An array of information about the current installation state. 
+ *   An array of information about the current installation state.
  */
 function hook_install_tasks_alter(&$tasks, $install_state) {
   // Replace the "Choose language" installation task provided by Drupal core
@@ -2403,6 +2403,34 @@ function hook_action_info_alter(&$action
 }
 
 /**
+ * Declare archivers to the system.
+ *
+ * An archiver is a class that is able to package and unpackage one or more files
+ * into a single possibly compressed file.  Common examples of such files are
+ * zip files and tar.gz files.  All archiver classes must implement
+ * ArchiverInterface.
+ *
+ * When mapping a
+ *
+ * Each entry should be keyed on a unique value, and specify three
+ * additional keys:
+ *   - class: The name of the PHP class for this archiver.
+ *   - extensions: An array of file extensions that this archiver supports.
+ *   - weight: This optional key specifies the weight of this archiver.
+ *     When mapping file extensions to archivers, the first archiver by
+ *     weight found that supports the requested extension will be used.
+ */
+function system_archiver_info() {
+  return array(
+    'tar' => array(
+      'class' => 'ArchiverTar',
+      'extensions' => array('tar'),
+    ),
+  );
+}
+
+
+/**
  * Defines additional date types.
  *
  * Next to the 'long', 'medium' and 'short' date types defined in core, any
@@ -2435,7 +2463,7 @@ function hook_date_format_types() {
  * module can define additional types that can be used when displaying dates. A
  * date type is a key which can be passed to format_date() to return a date in
  * the configured displayed format. A date format is a string defining the date
- * and time elements to use. For example, a date type could be 
+ * and time elements to use. For example, a date type could be
  * 'mymodule_extra_long', while a date format is like 'Y-m-d'.
  *
  * New date types must first be declared using hook_date_format_types(). It is

=== added file 'modules/system/system.archiver.inc'
--- modules/system/system.archiver.inc	1970-01-01 00:00:00 +0000
+++ modules/system/system.archiver.inc	2009-10-15 03:38:26 +0000
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Archiver implementations provided by the system module.
+ *
+ * These classes all extend Archive_Tar, so we keep them in a separate
+ * file.  That way we do not need to load them or Archive_Tar or
+ * ArchiverInterface until requested. Even though they are small,
+ * defining them in system.module would force Archive_Tar and
+ * ArchiverInterface to get loaded on every page request.
+ */
+
+/**
+ * Archiver for .tar files.
+ */
+class ArchiverTar extends Archive_Tar implements ArchiverInterface {
+  public function __construct($filename) {
+    parent::__construct($filename);
+  }
+}
+
+/**
+ * Archiver for .tar.gz files.
+ */
+class ArchiverTarGz extends Archive_Tar implements ArchiverInterface {
+  public function __construct($filename) {
+    parent::__construct($filename, 'gz');
+  }
+}
+
+/**
+ * Archiver for .tar.bz2 files.
+ */
+class ArchiverTarBz2 extends Archive_Tar implements ArchiverInterface {
+  public function __construct($filename) {
+    parent::__construct($filename, 'bz2');
+  }
+}

=== modified file 'modules/system/system.info'
--- modules/system/system.info	2009-08-31 18:30:26 +0000
+++ modules/system/system.info	2009-10-15 03:42:15 +0000
@@ -6,6 +6,7 @@ version = VERSION
 core = 7.x
 files[] = system.module
 files[] = system.admin.inc
+files[] = system.archiver.inc
 files[] = system.queue.inc
 files[] = image.gd.inc
 files[] = system.install

=== modified file 'modules/system/system.module'
--- modules/system/system.module	2009-10-14 20:42:47 +0000
+++ modules/system/system.module	2009-10-15 03:36:36 +0000
@@ -3364,3 +3364,22 @@ function system_date_format_delete($dfid
     ->execute();
 }
 
+/**
+ * Implement hook_archiver_info().
+ */
+function system_archiver_info() {
+  return array(
+    'tar' => array(
+      'class' => 'ArchiverTar',
+      'extensions' => array('tar'),
+    ),
+    'targz' => array(
+      'class' => 'ArchiverTarGz',
+      'extensions' => array('tar.gz'),
+    ),
+    'tarbz2' => array(
+      'class' => 'ArchiverTarBz2',
+      'extensions' => array('tar.bz2'),
+    ),
+  );
+}

