Index: fileshare.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/fileshare/fileshare.install,v
retrieving revision 1.6
diff -u -r1.6 fileshare.install
--- fileshare.install	22 Nov 2006 01:24:47 -0000	1.6
+++ fileshare.install	21 Apr 2007 05:44:55 -0000
@@ -20,6 +20,14 @@
   db_add_column($ret, 'node_fileshare', '_whitelist', 'varchar(255)', array('default' => "'jpg jpeg gif png txt html htm doc xls pdf ppt pps ai psd'"));
   return $ret;
 }
+
+/**
+ * Add the column to hold the maximum size (K bytes) for this collection
+ */
+function fileshare_update_3() {
+  $ret = array();
+  db_add_column($ret, 'node_fileshare', '_maxsizeKb', 'int(4)', array('default' => 0, 'not null' => TRUE));
+}
 
 /**
  * Implementation of hook_install()
@@ -39,7 +47,8 @@
         _method tinyint(1) NOT NULL default '0',
         _thumbs tinyint(1) NOT NULL default '0',
         _modify tinyint(1) NOT NULL default '0',
-        _private tinyint(1) NOT NULL default '0',
+        _private tinyint(1) NOT NULL default '0',
+	    _maxsizeKb int(4) unsigned NOT NULL default '0',
         PRIMARY KEY (vid, nid)
       ) TYPE = MYISAM /*!40100 DEFAULT CHARACTER SET utf8 */;"
     );
@@ -58,6 +67,7 @@
         _thumbs smallint NOT NULL default '0',
         _modify smallint NOT NULL default '0',
         _private smallint NOT NULL default '0',
+        _maxsizeKb int4 NOT NULL DEFAULT 0,
       CONSTRAINT fileshare_nid PRIMARY KEY (vid, nid)
       );"
     );
Index: fileshare.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/fileshare/fileshare.module,v
retrieving revision 1.20
diff -u -r1.20 fileshare.module
--- fileshare.module	16 Jan 2007 23:06:06 -0000	1.20
+++ fileshare.module	21 Apr 2007 05:44:55 -0000
@@ -251,7 +251,16 @@
     '#maxlength' => 255,
     '#description' => t("File extensions that are allowed to be uploaded. Separate extensions with a space and do not include the leading dot. 
       If left blank the default 'jpg jpeg gif png txt html htm doc xls pdf ppt pps ai psd' will be applied.")
-  );
+  );
+  
+  $form['file_filter']['_maxsizeKb'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Maximum file collection size (Kb)'),
+    '#default_value' => ($new) ? 0 : $node->_maxsizeKb,
+    '#maxlength' => 5,
+    '#description' => t("Maximum total file size for this fileshare collection, in kilobytes.  A value of 0 means unlimited")
+  );
+  
   $form['file_filter']['_private'] = array(
     '#type' => 'checkbox',
     '#title' => '<strong>'.t('Set the node private').'</strong>',
@@ -297,8 +306,8 @@
       }
     }
   }
-  db_query("INSERT INTO {node_fileshare} (vid, nid, _filepath, _basepath, _whitelist, _method, _modify, _thumbs, _private) VALUES (%d, %d, '%s', '%s', '%s', %b, %b, %b, %b)", 
-    $node->vid, $node->nid, $node->_filepath, $node->_basepath, $node->_whitelist, $node->_method, $node->_modify, $node->_thumbs, $node->_private);
+  db_query("INSERT INTO {node_fileshare} (vid, nid, _filepath, _basepath, _whitelist, _method, _modify, _thumbs, _private, _maxsizeKb) VALUES (%d, %d, '%s', '%s', '%s', %b, %b, %b, %b, %d)", 
+    $node->vid, $node->nid, $node->_filepath, $node->_basepath, $node->_whitelist, $node->_method, $node->_modify, $node->_thumbs, $node->_private, $node->_maxsizeKb);
 }
 
 /**
@@ -323,8 +332,8 @@
       }
     }
   $node->_filepath = $rename;
-  db_query("UPDATE {node_fileshare} SET _filepath = '%s',  _basepath = '%s', _whitelist = '%s', _method = %b, _modify = %b, _thumbs = %b, _private = %b WHERE vid = %d", 
-    $node->_filepath, $node->_basepath, $node->_whitelist, $node->_method, $node->_modify, $node->_thumbs, $node->_private, $node->vid);
+  db_query("UPDATE {node_fileshare} SET _filepath = '%s',  _basepath = '%s', _whitelist = '%s', _method = %b, _modify = %b, _thumbs = %b, _private = %b, _maxsizeKb = %d WHERE vid = %d", 
+    $node->_filepath, $node->_basepath, $node->_whitelist, $node->_method, $node->_modify, $node->_thumbs, $node->_private, $node->_maxsizeKb, $node->vid);
   }
 }
 
@@ -353,7 +362,7 @@
   // Notice that we're matching all revision, by using the node's nid.
   db_query('DELETE FROM {node_fileshare} WHERE nid = %d', $node->nid);
   if (_recursive_rmdir($node->_basepath.$node->_filepath)) {
-    drupal_set_message('The directory: <strong>"'.$node->_basepath.$node->_filepath.'"</strong> has been deleted.');
+    drupal_set_message('The directory: <strong>"'.$node->_basepath.$node->_filepath.'"</strong> has been deleted.');
     watchdog('fileshare', $node->title." and the contents of ".$node->_basepath.$node->_filepath." were deleted", WATCHDOG_NOTICE, l(t('view'), 'node/'.$node->nid));
   } else {
     drupal_set_message('ERROR: "'.$node->_basepath.$node->_filepath.'" could not be deleted.','error');
@@ -368,7 +377,7 @@
  * every time a node is loaded, and allows us to do some loading of our own.
  */
 function fileshare_load($node) {
-  $additions = db_fetch_object(db_query('SELECT _filepath, _basepath, _whitelist, _method, _modify, _thumbs, _private FROM 
+  $additions = db_fetch_object(db_query('SELECT _filepath, _basepath, _whitelist, _method, _modify, _thumbs, _private, _maxsizeKb FROM 
     {node_fileshare} WHERE vid = %d', $node->vid));
   return $additions;
 }
@@ -486,10 +495,26 @@
         if ($node->_whitelist == '') $node->_whitelist = 'jpg jpeg gif png txt html htm doc xls pdf ppt pps ai psd';
         $regex = '/\.('. ereg_replace(' +', '|', preg_quote($node->_whitelist)) .')$/i';
         if (!preg_match($regex, $upload)) {
-          form_set_error('upload', t('The selected file <em>%name</em> can not be attached to this post, because it is only possible to attach files with the following extensions: %files-allowed.', 
+          form_set_error('filename', t('The selected file <em>%name</em> can not be attached to this post, because it is only possible to attach files with the following extensions: %files-allowed.', 
             array('%name' => $upload, '%files-allowed' => $node->_whitelist)));
-        }
-      }
+        }
+        
+        // Validate file against collection file size limits
+        $collection_size = _fileshare_collection_size($node);
+        $file = file_check_upload('filename');
+        $file_size = filesize($file->filepath);
+        $space_left = ($node->_maxsizeKb*1024)-$collection_size;
+        if($space_left < 0) {
+			$space_left_txt = t('The collection is full.');
+        } else {
+			$space_left_txt = t('Upload a file that is smaller than %size.', array('%size' => _resize_bytes($space_left)));
+        }
+        
+        if(($file_size + $collection_size) > ($node->_maxsizeKb*1024)) {
+			form_set_error('filename', t('The selected file cannot be attached to this post because it would exceed %collection_size, the maximum upload space for files.  %collection_left', 
+			                           array('%collection_size' => _resize_bytes($node->_maxsizeKb*1024), '%collection_left' => $space_left_txt)));
+        }
+      }
       break;
     case t('New folder'):
       if ($form_values['dirname']=='') {
@@ -516,6 +541,16 @@
         drupal_set_message('The file: <strong>"'.$file->filename.'"</strong> uploaded successfully!');
         $node = node_load($form_values['nid']);
         watchdog('fileshare', $file->filename.' uploaded from '.$node->title, WATCHDOG_NOTICE, l(t('view'), 'node/'.$node->nid));
+        if($node->_maxsizeKb > 0) {
+          $collection_size = _fileshare_collection_size($node);
+          $space_left = ($node->_maxsizeKb*1024)-$collection_size;
+          if($space_left < 0) {
+			$space_left_txt = t('The file collection is full, you must delete files before you can upload any more.');
+          } else {
+			$space_left_txt = t('You have %size left for uploads in this file collection.', array('%size' => _resize_bytes($space_left)));
+          }
+		  drupal_set_message($space_left_txt);
+        }
       } else {
         drupal_set_message('Upload failed. Please check your filename.','error');
       }
@@ -570,7 +605,19 @@
         drupal_set_message('The file: <strong>"'.$deletefile.'"</strong> could not be deleted.','error'); 
         return FALSE;
       }
-    }
+    }
+    
+    if($node->_maxsizeKb > 0) {
+       $collection_size = _fileshare_collection_size($node);
+       $space_left = ($node->_maxsizeKb*1024)-$collection_size;
+       if($space_left < 0) {
+		 $space_left_txt = t('The file collection is still full, you must delete more files before you can upload any more.');
+       } else {
+		 $space_left_txt = t('You now have %size left for uploads in this file collection.', array('%size' => _resize_bytes($space_left)));
+       }
+	   drupal_set_message($space_left_txt);
+    }
+    
   } else {
     drupal_set_message('You are not authorized to remove: <strong>"'.$deletefile.'"</strong>.','error');
   }
@@ -813,4 +860,41 @@
     if ($mime) return $mime;
     return "application/octet-stream";
   }
-}
\ No newline at end of file
+}
+
+/**
+ * Returns the size of all files in the fileshare collection
+ * 
+ */
+function _fileshare_collection_size($node) {
+	return _fileshare_collection_size_recursive($node->_basepath.$node->_filepath);
+}
+
+/**
+ * Calculates the size of all files in the fileshare.  This is an internal helper
+ * function to do a recursive descent into the directory.  Call
+ * _fileshare_collection_size with a fileshare node as the main entry point to this
+ * function.
+ * 
+ * @param $filepath the top level directory at which to start
+ * 
+ * @return The number of bytes consumed on disk (based on filesize()) by the files uploaded to this
+ * 		   fileshare.
+ */
+function _fileshare_collection_size_recursive($filepath) {
+  $size = 0;
+  
+  // Read directory to calculate file sizes
+  $handle = opendir($filepath);
+  while (false !== ($file = readdir($handle))) {
+    if ($file != "." && $file != "..") {
+      if (is_dir($filepath.'/'.$file)) {
+        $size += _fileshare_collection_size_recursive($filepath.'/'.$file); //recursive size calculation
+      } else {
+        $size += filesize($filepath.'/'.$file);
+      }
+    }
+  }
+  closedir($handle);
+  return $size;
+}
