From 32779ee15ff4cc87b08074ffa3200458646e09ed Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 15 Mar 2016 17:24:25 -0700 Subject: [PATCH] GUAC-236: Provide -f option for overriding locking behavior. --- src/guacenc/encode.c | 8 +++++--- src/guacenc/encode.h | 13 +++++++++++-- src/guacenc/guacenc.c | 12 ++++++++++-- src/guacenc/man/guacenc.1 | 20 +++++++++++++++++++- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/guacenc/encode.c b/src/guacenc/encode.c index 6e5fd022..115becba 100644 --- a/src/guacenc/encode.c +++ b/src/guacenc/encode.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -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 width, int height, int bitrate) { + int width, int height, int bitrate, bool force) { /* Open input file */ 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 */ - if (fcntl(fd, F_SETLK, &file_lock) == -1) { + if (!force && fcntl(fd, F_SETLK, &file_lock) == -1) { /* Warn if lock cannot be acquired */ if (errno == EACCES || errno == EAGAIN) 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 */ else diff --git a/src/guacenc/encode.h b/src/guacenc/encode.h index ee6be9ab..b80eeb00 100644 --- a/src/guacenc/encode.h +++ b/src/guacenc/encode.h @@ -25,8 +25,13 @@ #include "config.h" +#include + /** - * 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 * 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 * second. * + * @param force + * Perform the encoding, even if the input file appears to be an + * in-progress recording (has an associated lock). + * * @return * Zero on success, non-zero if an error prevented successful encoding of * the video. */ 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 diff --git a/src/guacenc/guacenc.c b/src/guacenc/guacenc.c index c5525056..f67b2084 100644 --- a/src/guacenc/guacenc.c +++ b/src/guacenc/guacenc.c @@ -30,6 +30,7 @@ #include #include +#include #include int main(int argc, char* argv[]) { @@ -37,13 +38,14 @@ int main(int argc, char* argv[]) { int i; /* Load defaults */ + bool force = false; int width = GUACENC_DEFAULT_WIDTH; int height = GUACENC_DEFAULT_HEIGHT; int bitrate = GUACENC_DEFAULT_BITRATE; /* Parse arguments */ int opt; - while ((opt = getopt(argc, argv, "s:r:")) != -1) { + while ((opt = getopt(argc, argv, "s:r:f")) != -1) { /* -s: Dimensions (WIDTHxHEIGHT) */ if (opt == 's') { @@ -61,6 +63,10 @@ int main(int argc, char* argv[]) { } } + /* -f: Force */ + else if (opt == 'f') + force = true; + /* Invalid option */ else { goto invalid_options; @@ -108,7 +114,8 @@ int main(int argc, char* argv[]) { } /* 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++; guacenc_log(GUAC_LOG_DEBUG, "%s was NOT successfully encoded.", path); @@ -136,6 +143,7 @@ invalid_options: fprintf(stderr, "USAGE: %s" " [-s WIDTHxHEIGHT]" " [-r BITRATE]" + " [-f]" " [FILE]...\n", argv[0]); return 1; diff --git a/src/guacenc/man/guacenc.1 b/src/guacenc/man/guacenc.1 index 3f6f1799..bbef7189 100644 --- a/src/guacenc/man/guacenc.1 +++ b/src/guacenc/man/guacenc.1 @@ -7,6 +7,7 @@ guacenc \- Guacamole video encoder .B guacenc [\fB-s\fR \fIWIDTH\fRx\fIHEIGHT\fR] [\fB-r\fR \fIBITRATE\fR] +[\fB-f\fR] [\fIFILE\fR]... . .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 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 -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 .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 higher-quality video files. Lower values will result in smaller but 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 Written by Michael Jumper