When a browser closes a streaming connection, fwrite to stdout raises
SIGPIPE. Without a handler the default action terminates the process
immediately, skipping exit_zm() and leaving the DB handle and log
unclosed.
Add zm_pipe_handler that sets zm_terminate so zms falls out of its
streaming loop and exits through the normal shutdown path. Clarify
the sendFrame comment to match.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add user= parameter to get_auth_relay() so zms can use the indexed
Username column instead of iterating all users to validate the hash
- Apply the same fix to Event.php getStreamSrc() and getThumbnailSrc()
- Tighten Monitor.php from isset() to !empty() for consistency
- In MonitorStream.js start(), check if the auth hash in the img src
matches the current auth_hash before resuming via CMD_PLAY. If stale,
fall through to rebuild the URL with fresh auth_relay. This prevents
long-running montage pages from spawning zms with expired credentials.
- Downgrade zms auth failure from Error to Warning
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
FFmpeg is an integral component of ZM. Promote the appropriate libraries to required dependencies.
This reduces the possible build configurations greatly and thus maintenance burden.
gmtime uses an internal static storage to which a pointer is given as return value.
Due to this it is not safe to call gmtime from multiple threads since the same static storage is used.
Use gmtime_r instead which allows to pass in a tm struct.
Fixes:
https://github.com/ZoneMinder/zoneminder/security/code-scanning/32
Remove calls to zmDBConnect from various places to avoid possible side-effects/double initialization.
The function should be called once from the main thread of the daemon.
Also split config loading into 2 steps: static and DB config loading. Load the static config before zmDBConnect is called so it has a chance to succeed.
With this commit a unified structure for includes is introduced.
The general rules:
* Only include what you need
* Include wherever possible in the cpp and forward-declare in the header
The includes are sorted in a local to global fashion. This means for the include order:
0. If cpp file: The corresponding h file and an empty line
1. Includes from the project sorted alphabetically
2. System/library includes sorted alphabetically
3. Conditional includes