GUAC-236: Provide -f option for overriding locking behavior.

This commit is contained in:
Michael Jumper 2016-03-15 17:24:25 -07:00
parent 9d43e22592
commit 32779ee15f
4 changed files with 45 additions and 8 deletions

View File

@ -34,6 +34,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdbool.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -84,7 +85,7 @@ static int guacenc_read_instructions(guacenc_display* display,
} }
int guacenc_encode(const char* path, const char* out_path, const char* codec, int guacenc_encode(const char* path, const char* out_path, const char* codec,
int width, int height, int bitrate) { int width, int height, int bitrate, bool force) {
/* Open input file */ /* Open input file */
int fd = open(path, O_RDONLY); int fd = open(path, O_RDONLY);
@ -103,12 +104,13 @@ int guacenc_encode(const char* path, const char* out_path, const char* codec,
}; };
/* Abort if file cannot be locked for reading */ /* Abort if file cannot be locked for reading */
if (fcntl(fd, F_SETLK, &file_lock) == -1) { if (!force && fcntl(fd, F_SETLK, &file_lock) == -1) {
/* Warn if lock cannot be acquired */ /* Warn if lock cannot be acquired */
if (errno == EACCES || errno == EAGAIN) if (errno == EACCES || errno == EAGAIN)
guacenc_log(GUAC_LOG_WARNING, "Refusing to encode in-progress " guacenc_log(GUAC_LOG_WARNING, "Refusing to encode in-progress "
"recording \"%s\".", path); "recording \"%s\" (specify the -f option to override "
"this behavior).", path);
/* Log an error if locking fails in an unexpected way */ /* Log an error if locking fails in an unexpected way */
else else

View File

@ -25,8 +25,13 @@
#include "config.h" #include "config.h"
#include <stdbool.h>
/** /**
* Encodes the given Guacamole protocol dump as video. * Encodes the given Guacamole protocol dump as video. A read lock will be
* acquired on the input file to ensure that in-progress recordings are not
* encoded. This behavior can be overridden by specifying true for the force
* parameter.
* *
* @param path * @param path
* The path to the file containing the raw Guacamole protocol dump. * The path to the file containing the raw Guacamole protocol dump.
@ -48,12 +53,16 @@
* The desired overall bitrate of the resulting encoded video, in bits per * The desired overall bitrate of the resulting encoded video, in bits per
* second. * second.
* *
* @param force
* Perform the encoding, even if the input file appears to be an
* in-progress recording (has an associated lock).
*
* @return * @return
* Zero on success, non-zero if an error prevented successful encoding of * Zero on success, non-zero if an error prevented successful encoding of
* the video. * the video.
*/ */
int guacenc_encode(const char* path, const char* out_path, const char* codec, int guacenc_encode(const char* path, const char* out_path, const char* codec,
int width, int height, int bitrate); int width, int height, int bitrate, bool force);
#endif #endif

View File

@ -30,6 +30,7 @@
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <getopt.h> #include <getopt.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
@ -37,13 +38,14 @@ int main(int argc, char* argv[]) {
int i; int i;
/* Load defaults */ /* Load defaults */
bool force = false;
int width = GUACENC_DEFAULT_WIDTH; int width = GUACENC_DEFAULT_WIDTH;
int height = GUACENC_DEFAULT_HEIGHT; int height = GUACENC_DEFAULT_HEIGHT;
int bitrate = GUACENC_DEFAULT_BITRATE; int bitrate = GUACENC_DEFAULT_BITRATE;
/* Parse arguments */ /* Parse arguments */
int opt; int opt;
while ((opt = getopt(argc, argv, "s:r:")) != -1) { while ((opt = getopt(argc, argv, "s:r:f")) != -1) {
/* -s: Dimensions (WIDTHxHEIGHT) */ /* -s: Dimensions (WIDTHxHEIGHT) */
if (opt == 's') { if (opt == 's') {
@ -61,6 +63,10 @@ int main(int argc, char* argv[]) {
} }
} }
/* -f: Force */
else if (opt == 'f')
force = true;
/* Invalid option */ /* Invalid option */
else { else {
goto invalid_options; goto invalid_options;
@ -108,7 +114,8 @@ int main(int argc, char* argv[]) {
} }
/* Attempt encoding, log granular success/failure at debug level */ /* Attempt encoding, log granular success/failure at debug level */
if (guacenc_encode(path, out_path, "mpeg4", width, height, bitrate)) { if (guacenc_encode(path, out_path, "mpeg4",
width, height, bitrate, force)) {
failures++; failures++;
guacenc_log(GUAC_LOG_DEBUG, guacenc_log(GUAC_LOG_DEBUG,
"%s was NOT successfully encoded.", path); "%s was NOT successfully encoded.", path);
@ -136,6 +143,7 @@ invalid_options:
fprintf(stderr, "USAGE: %s" fprintf(stderr, "USAGE: %s"
" [-s WIDTHxHEIGHT]" " [-s WIDTHxHEIGHT]"
" [-r BITRATE]" " [-r BITRATE]"
" [-f]"
" [FILE]...\n", argv[0]); " [FILE]...\n", argv[0]);
return 1; return 1;

View File

@ -7,6 +7,7 @@ guacenc \- Guacamole video encoder
.B guacenc .B guacenc
[\fB-s\fR \fIWIDTH\fRx\fIHEIGHT\fR] [\fB-s\fR \fIWIDTH\fRx\fIHEIGHT\fR]
[\fB-r\fR \fIBITRATE\fR] [\fB-r\fR \fIBITRATE\fR]
[\fB-f\fR]
[\fIFILE\fR]... [\fIFILE\fR]...
. .
.SH DESCRIPTION .SH DESCRIPTION
@ -23,7 +24,18 @@ Each \fIFILE\fR specified will be encoded as a raw MPEG-4 video stream to a new
file named \fIFILE\fR.m4v, encoded according to the other options specified. By file named \fIFILE\fR.m4v, encoded according to the other options specified. By
default, the output video will be \fI640\fRx\fI480\fR pixels, and will be saved default, the output video will be \fI640\fRx\fI480\fR pixels, and will be saved
with a bitrate of \fI2000000\fR bits per second (2 Mbps). These defaults can be with a bitrate of \fI2000000\fR bits per second (2 Mbps). These defaults can be
overridden with the \fB-s\fR and \fB-r\fR options respectively. overridden with the \fB-s\fR and \fB-r\fR options respectively. Existing files
will not be overwritten; the encoding process for any input file will be
aborted if it would result in overwriting an existing file.
.P
Guacamole acquires a write lock on recordings as they are being written. By
default,
.B guacenc
will check whether the each input file is locked and will refuse to read and
encode an input file if it appears to be an in-progress recording. This
behavior can be overridden by specifying the \fB-f\fR option. Encoding an
in-progress recording will still result in a valid video; the video will simply
cover the user's session only up to the current point in time.
. .
.SH OPTIONS .SH OPTIONS
.TP .TP
@ -39,6 +51,12 @@ will use for the saved video. This is specified in bits per second. By default,
this will be \fI2000000\fR (2 Mbps). Higher values will result in larger but this will be \fI2000000\fR (2 Mbps). Higher values will result in larger but
higher-quality video files. Lower values will result in smaller but higher-quality video files. Lower values will result in smaller but
lower-quality video files. lower-quality video files.
.TP
\fB-f\fR
Overrides the default behavior of
.B guacenc
such that input files will be encoded even if they appear to be recordings of
in-progress Guacamole sessions.
. .
.SH AUTHOR .SH AUTHOR
Written by Michael Jumper <mike.jumper@guac-dev.org> Written by Michael Jumper <mike.jumper@guac-dev.org>