diff --git a/tmate-decoder.c b/tmate-decoder.c index ca2d8ccd..1d2e70ad 100644 --- a/tmate-decoder.c +++ b/tmate-decoder.c @@ -110,6 +110,10 @@ static void tmate_header(struct tmate_decoder *decoder, tmate_debug("new master, client version: %s, protocol version: %d", client_version, decoder->protocol); + + if (strcmp(client_version, TMATE_LATEST_VERSION)) + tmate_notify_later(10, "A new version is available, please upgrade :)"); + free(client_version); if (gethostname(hostname, sizeof(hostname)) < 0) diff --git a/tmate-encoder.c b/tmate-encoder.c index 98b83202..70134fbd 100644 --- a/tmate-encoder.c +++ b/tmate-encoder.c @@ -32,6 +32,13 @@ void tmate_encoder_init(struct tmate_encoder *encoder) msgpack_pack_##what(&tmate_encoder->pk, __VA_ARGS__); \ } while(0) +static void __tmate_notify(const char *msg) +{ + pack(array, 2); + pack(int, TMATE_NOTIFY); + pack(string, msg); +} + void printflike1 tmate_notify(const char *fmt, ...) { va_list ap; @@ -41,9 +48,36 @@ void printflike1 tmate_notify(const char *fmt, ...) vsnprintf(msg, sizeof(msg), fmt, ap); va_end(ap); - pack(array, 2); - pack(int, TMATE_NOTIFY); - pack(string, msg); + __tmate_notify(msg); +} + +static void __tmate_notify_later(evutil_socket_t fd, short what, void *arg) +{ + char *msg = arg; + __tmate_notify(msg); +} + +void printflike2 tmate_notify_later(int timeout, const char *fmt, ...) +{ + struct timeval tv; + va_list ap; + char *msg; + + tv.tv_sec = timeout; + tv.tv_usec = 0; + + va_start(ap, fmt); + xvasprintf(&msg, fmt, ap); + va_end(ap); + + /* + * FIXME leaks like crazy when calling tmate_notify_later() + * multiple times. + */ + + evtimer_assign(&tmate_encoder->ev_notify_timer, ev_base, + __tmate_notify_later, msg); + evtimer_add(&tmate_encoder->ev_notify_timer, &tv); } static int num_clients(void) diff --git a/tmate.h b/tmate.h index 8b7d1b6c..82c5edad 100644 --- a/tmate.h +++ b/tmate.h @@ -19,6 +19,7 @@ do { \ /* tmate-encoder.c */ +#define TMATE_LATEST_VERSION "1.8.6" #define TMATE_DOMAIN "tmate.io" enum tmate_client_commands { @@ -31,12 +32,14 @@ enum tmate_client_commands { struct tmate_encoder { struct evbuffer *buffer; struct event ev_readable; + struct event ev_notify_timer; msgpack_packer pk; }; extern void tmate_encoder_init(struct tmate_encoder *encoder); extern void printflike1 tmate_notify(const char *fmt, ...); +extern void printflike2 tmate_notify_later(int timeout, const char *fmt, ...); extern void tmate_notify_client_join(struct client *c); extern void tmate_notify_client_left(struct client *c);