Index: db/zm_create.sql.in
===================================================================
--- db/zm_create.sql.in	(revision 2871)
+++ db/zm_create.sql.in	(working copy)
@@ -311,7 +311,7 @@
   `Host` varchar(64) NOT NULL default '',
   `Port` varchar(8) NOT NULL default '',
   `SubPath` varchar(255) NOT NULL default '',
-  `Path` varchar(64) NOT NULL default '',
+  `Path` varchar(128) NOT NULL default '',
   `Width` smallint(5) unsigned NOT NULL default '0',
   `Height` smallint(5) unsigned NOT NULL default '0',
   `Palette` int(10) unsigned NOT NULL default '0',
@@ -846,4 +846,4 @@
 insert into Config set Id = 179, Name = 'ZM_DYN_NEXT_REMINDER', Value = '', Type = 'string', DefaultValue = '', Hint = 'string', Pattern = '(?-xism:^(.+)$)', Format = ' $1 ', Prompt = 'When the earliest time to remind about versions will be', Help = '', Category = 'dynamic', Readonly = '1', Requires = '';
 insert into Config set Id = 180, Name = 'ZM_DYN_DONATE_REMINDER_TIME', Value = '0', Type = 'integer', DefaultValue = '0', Hint = 'integer', Pattern = '(?-xism:^(\d+)$)', Format = ' $1 ', Prompt = 'When the earliest time to remind about donations will be', Help = '', Category = 'dynamic', Readonly = '1', Requires = '';
 insert into Config set Id = 181, Name = 'ZM_DYN_SHOW_DONATE_REMINDER', Value = '1', Type = 'boolean', DefaultValue = 'yes', Hint = 'yes|no', Pattern = '(?i-xsm:^([yn]))', Format = ' ($1 =~ /^y/) ? \"yes\" : \"no\" ', Prompt = 'Remind about donations or not', Help = '', Category = 'dynamic', Readonly = '1', Requires = '';
-
+insert into Config set Id = 182, Name = 'ZM_RELOAD_CAMBOZOLA', Value = '0', Type = 'integer', DefaultValue = '0', Hint = 'integer', Pattern = '(?-xism:^(\d+)$)', Format = ' $1 ', Prompt = 'After how many seconds should Cambozola be reloaded in live view', Help = 'Cambozola allows for the viewing of streaming MJPEG however it caches the entire stream into cache space on the computer, setting this to a number > 0 will cause it to automatically reload after that many seconds to avoid filling up a hard drive.', Category = 'images', Readonly = '0', Requires = '';
\ No newline at end of file
Index: src/zm_mpeg.cpp
===================================================================
--- src/zm_mpeg.cpp	(revision 2871)
+++ src/zm_mpeg.cpp	(working copy)
@@ -378,7 +378,7 @@
 	}
 	if ( ret != 0 )
 	{
-		Fatal( "Error %d while writing video frame", ret );
+		Fatal( "Error %d while writing video frame: %s", ret, strerror( errno ) );
 	}
 	return( pts );
 }
Index: src/zm_image.cpp
===================================================================
--- src/zm_image.cpp	(revision 2871)
+++ src/zm_image.cpp	(working copy)
@@ -382,7 +382,7 @@
 	{
 		Image temp_image( *this );
 		temp_image.Colourise();
-		return( temp_image.WriteJpeg( filename ) );
+		return( temp_image.WriteJpeg( filename, quality_override, on_blocking_abort ) );
 	}
 
 	int quality = quality_override?quality_override:config.jpeg_file_quality;
Index: src/zm_config_defines.h
===================================================================
--- src/zm_config_defines.h	(revision 2871)
+++ src/zm_config_defines.h	(working copy)
@@ -183,9 +183,10 @@
 #define ZM_DYN_NEXT_REMINDER 179
 #define ZM_DYN_DONATE_REMINDER_TIME 180
 #define ZM_DYN_SHOW_DONATE_REMINDER 181
+#define ZM_RELOAD_CAMBOZOLA 182
 
 
-#define ZM_MAX_CFG_ID 181
+#define ZM_MAX_CFG_ID 182
 
 #define ZM_CFG_DECLARE_LIST \
 	const char *lang_default;\
@@ -370,6 +371,7 @@
 	const char *dyn_next_reminder;\
 	int dyn_donate_reminder_time;\
 	bool dyn_show_donate_reminder;\
+	int reload_cambozola;\
 
 
 #define ZM_CFG_ASSIGN_LIST \
@@ -555,5 +557,5 @@
 	dyn_next_reminder = (const char *)config.Item( ZM_DYN_NEXT_REMINDER );\
 	dyn_donate_reminder_time = (int)config.Item( ZM_DYN_DONATE_REMINDER_TIME );\
 	dyn_show_donate_reminder = (bool)config.Item( ZM_DYN_SHOW_DONATE_REMINDER );\
+	reload_cambozola = (int)config.Item( ZM_RELOAD_CAMBOZOLA );\
 
-
Index: src/zm_zone.cpp
===================================================================
--- src/zm_zone.cpp	(revision 2871)
+++ src/zm_zone.cpp	(working copy)
@@ -85,7 +85,7 @@
 					ranges[py].lo_x = x;
 					ranges[py].off_x = px;
 				}
-				else if ( ranges[py].hi_x < x )
+				if ( ranges[py].hi_x < x )
 				{
 					ranges[py].hi_x = x;
 				}
Index: src/zms.cpp
===================================================================
--- src/zms.cpp	(revision 2871)
+++ src/zms.cpp	(working copy)
@@ -75,8 +75,12 @@
 
 	bool nph = false;
 	const char *basename = strrchr( argv[0], '/' );
+	if (basename) //if we found a / lets skip past it
+		basename++;
+	else //argv[0] will not always contain the full path, but rather just the script name
+		basename = argv[0];
 	const char *nph_prefix = "nph-";
-	if ( basename && !strncmp( basename+1, nph_prefix, strlen(nph_prefix) ) )
+	if ( basename && !strncmp( basename, nph_prefix, strlen(nph_prefix) ) )
 	{
 		nph = true;
 	}
Index: src/zm_ffmpeg_camera.cpp
===================================================================
--- src/zm_ffmpeg_camera.cpp	(revision 2871)
+++ src/zm_ffmpeg_camera.cpp	(working copy)
@@ -81,11 +81,11 @@
 
     // Open the input, not necessarily a file
     if ( av_open_input_file( &mFormatContext, mPath.c_str(), NULL, 0, NULL ) !=0 )
-        Fatal( "Unable to open input %s", mPath.c_str() );
+        Fatal( "Unable to open input %s due to: %s", mPath.c_str(), strerror(errno) );
 
     // Locate stream info from input
     if ( av_find_stream_info( mFormatContext ) < 0 )
-        Fatal( "Unable to find stream info from %s", mPath.c_str() );
+        Fatal( "Unable to find stream info from %s due to: %s", mPath.c_str(), strerror(errno) );
     
     // Find first video stream present
     mVideoStreamId = -1;
Index: web/skins/classic/views/watch.php
===================================================================
--- web/skins/classic/views/watch.php	(revision 2871)
+++ web/skins/classic/views/watch.php	(working copy)
@@ -197,7 +197,7 @@
           classid="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95"
           codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,0,02,902">
           <param name="FileName" value="<?= $soundSrc ?>"/>
-          <param name="autoStart" value="1"/>
+          <param name="autoStart" value="0"/>
           <param name="loop" value="1"/>
           <param name=hidden value="1"/>
           <param name="showControls" value="0"/>
Index: web/skins/classic/views/js/video.js
===================================================================
--- web/skins/classic/views/js/video.js	(revision 2871)
+++ web/skins/classic/views/js/video.js	(working copy)
@@ -12,7 +12,7 @@
 
 function generateVideoProgress()
 {
-    var tickerText = $('videoProgressTicker').getText();
+    var tickerText = $('videoProgressTicker').innerHTML;
     if ( tickerText.length < 1 || tickerText.length > 4 )
         $('videoProgressTicker').set( 'text', '.' );
     else
Index: web/skins/classic/views/js/watch.js
===================================================================
--- web/skins/classic/views/js/watch.js	(revision 2871)
+++ web/skins/classic/views/js/watch.js	(working copy)
@@ -72,7 +72,10 @@
         if ( SOUND_ON_ALARM )
         {
             // Enable the alarm sound
-            $('alarmSound').removeClass( 'hidden' );
+			if (! canPlayPauseAudio )
+				$('alarmSound').removeClass( 'hidden' );
+			else
+				$('MediaPlayer').Play();
         }
         if ( POPUP_ON_ALARM )
         {
@@ -84,9 +87,15 @@
         if ( oldAlarm )
         {
             // Disable alarm sound
-            $('alarmSound').addClass( 'hidden' );
+			if (! canPlayPauseAudio )
+				$('alarmSound').addClass( 'hidden' );
+			else
+				$('MediaPlayer').Stop();
         }
     }
+	if ( oldAlarm) //done with an event do a refresh
+		eventCmdQuery();
+
     lastAlarmState = alarmState;
 }
 
@@ -98,6 +107,7 @@
 
 function getStreamCmdResponse( respObj, respText )
 {
+	watchdog_ok("stream");
     if ( streamCmdTimer )
         streamCmdTimer = $clear( streamCmdTimer );
 
@@ -199,6 +209,8 @@
             $('enableDisableAlarms').addClass( 'hidden' );
         }
     }
+	else
+		checkStreamForErrors("getStreamCmdResponse",respObj);//log them
 
     var streamCmdTimeout = statusRefreshTimeout;
     if ( alarmState == STATE_ALARM || alarmState == STATE_ALERT )
@@ -345,6 +357,7 @@
 
 function getStatusCmdResponse( respObj, respText )
 {
+	watchdog_ok("status");
     if ( statusCmdTimer )
         statusCmdTimer = $clear( statusCmdTimer );
 
@@ -353,6 +366,8 @@
         $('fpsValue').set( 'text', respObj.monitor.FrameRate );
         setAlarmState( respObj.monitor.Status );
     }
+	else
+		checkStreamForErrors("getStatusCmdResponse",respObj);
 
     var statusCmdTimeout = statusRefreshTimeout;
     if ( alarmState == STATE_ALARM || alarmState == STATE_ALERT )
@@ -371,6 +386,7 @@
 
 function getAlarmCmdResponse( respObj, respText )
 {
+	checkStreamForErrors("getAlarmCmdResponse",respObj);
 }
 
 function cmdDisableAlarms()
@@ -425,6 +441,7 @@
 
 function getEventCmdResponse( respObj, respText )
 {
+	watchdog_ok("event");
     if ( eventCmdTimer )
         eventCmdTimer = $clear( eventCmdTimer );
 
@@ -514,6 +531,8 @@
             rows.length--;
         }
     }
+	else
+		checkStreamForErrors("getEventCmdResponse",respObj);
 
     var eventCmdTimeout = eventsRefreshTimeout;
     if ( alarmState == STATE_ALARM || alarmState == STATE_ALERT )
@@ -524,6 +543,8 @@
 
 function eventCmdQuery()
 {
+	if ( eventCmdTimer ) //avoid firing another if we are firing one
+        eventCmdTimer = $clear( eventCmdTimer );
     eventCmdReq.send();
 }
 
@@ -618,15 +639,39 @@
         controlCmdImage( x, y );
     }
 }
+var watchdog_inactive = {stream: false,status:false,event:false};
+var watchdog_functions = {stream:streamCmdQuery,status:statusCmdQuery,event:eventCmdQuery};
+//Make sure the various refreshes are still taking effect
+function watchdog_check(type)
+{
+	if (watchdog_inactive[type])
+{
+		console.log("Detected streamWatch of type: " + type + " stopped, restarting");
+		watchdog_functions[type]();
+		watchdog_inactive[type] = false;
+	}
+	else
+		watchdog_inactive[type] = true;
+}
+function watchdog_ok(type){
+	watchdog_inactive[type] = false;
+}
 
 function initPage()
 {
     if ( streamMode == "single" )
+	{
         statusCmdTimer = statusCmdQuery.delay( (Math.random()+0.1)*statusRefreshTimeout );
+		watchdog_check.pass('status').periodical(statusRefreshTimeout*2);
+	}
     else
+	{
         streamCmdTimer = streamCmdQuery.delay( (Math.random()+0.1)*statusRefreshTimeout );
+		watchdog_check.pass('stream').periodical(statusRefreshTimeout*2);
+	}
  
     eventCmdTimer = eventCmdQuery.delay( (Math.random()+0.1)*statusRefreshTimeout );
+	watchdog_check.pass('event').periodical(eventsRefreshTimeout*2);
 
     if ( canStreamNative || streamMode == "single" )
     {
@@ -638,6 +683,8 @@
             fetchImage.pass( streamImg ).periodical( imageRefreshTimeout );
     }
 
+	if (window.java_refresh && javaRefreshTime)
+		java_refresh.delay(javaRefreshTime*1000);
 }
 
 // Kick everything off
Index: web/skins/classic/views/js/export.js
===================================================================
--- web/skins/classic/views/js/export.js	(revision 2871)
+++ web/skins/classic/views/js/export.js	(working copy)
@@ -21,7 +21,7 @@
 
 function exportProgress()
 {
-    var tickerText = $('exportProgressTicker').getText();
+    var tickerText = $('exportProgressTicker').innerHTML;
     if ( tickerText.length < 1 || tickerText.length > 4 )
         $('exportProgressTicker').set( 'text', '.' );
     else
Index: web/skins/classic/views/js/event.js
===================================================================
--- web/skins/classic/views/js/event.js	(revision 2871)
+++ web/skins/classic/views/js/event.js	(working copy)
@@ -684,7 +684,7 @@
 
 function showFrameStats()
 {
-    var fid = $('eventImageNo').getText();
+    var fid = $('eventImageNo').innerHTML;
     createPopup( '?view=stats&eid='+event.Id+'&fid='+fid, 'zmStats', 'stats', event.Width, event.Height );
 }
 
Index: web/skins/classic/views/js/watch.js.php
===================================================================
--- web/skins/classic/views/js/watch.js.php	(revision 2871)
+++ web/skins/classic/views/js/watch.js.php	(working copy)
@@ -58,7 +58,7 @@
 
 var canEditMonitors = <?= canEdit( 'Monitors' )?'true':'false' ?>;
 var canStreamNative = <?= canStreamNative()?'true':'false' ?>;
-
+var canPlayPauseAudio = <?=  isInternetExplorer()?'true':'false' ?>;
 <?php if ( $monitor['CanMoveMap'] ) { ?>
 var imageControlMode = "moveMap";
 <?php } elseif ( $monitor['CanMoveRel'] ) { ?>
@@ -68,3 +68,23 @@
 <?php } else { ?>
 var imageControlMode = null;
 <?php } ?>
+
+
+<?php if ( canStreamApplet() && $streamMode == "jpeg" ) { ?>
+var javaRefreshTime = <?= ZM_RELOAD_CAMBOZOLA ?>;
+function java_refresh(){
+	if (streamStatus && (! streamStatus.paused && ! streamStatus.delayed) )
+	{
+		var streamImg = document.getElementById('liveStream');
+		var parent = streamImg.parentNode;
+		parent.removeChild(streamImg);
+		parent.appendChild(streamImg);
+		if (javaRefreshTime)
+			java_refresh.delay(javaRefreshTime*1000);
+	}
+	else
+		java_refresh.delay(15);//if we are paused or delayed check every 15 seconds if we are live yet...
+	
+}
+<?php } ?>
\ No newline at end of file
