LIBTTYREC(3)

NAME
libttyrec - a library for handling ttyrec files

SYNOPSIS
#include <ttyrec.h>

Link with -ltty.

DESCRIPTION

  Helper stream function:

int     open_stream(int fd, const char* url, int mode, const char **error);
    This function opens a stream designated by the url. If the given url ends in ".gz", ".xz", ".bz2" or ".zst"), the stream is assumed to be compressed and gets passed through the appropriate [un]packer. If the fd is not -1, it is the descriptor you already opened; if it is -1, the file is opened. The mode can be:

    SM_READ
    SM_WRITE
    SM_REPREAD
    SM_APPEND

    On error, -1 is returned. If you want the message, pass a non-null pointer error, it will be filled in.

  Format encoders:

const char*   ttyrec_w_find_format(const char *format, const char *filename, const char *fallback);
    This function searches for a format that would fit the filename provided -- that is, abc.ttyrec.gz returns "ttyrec". If no known extension is found, the function returns whatever you gave as fallback. You can force a format yourself, in this case, it is only validated and if invalid, 0 is returned regardless of the other two arguments.

recorder        ttyrec_w_open(int fd, const char *format, const char *filename, const struct timeval *ts);
    A recorder is opened, writing to the file fd; if it's not given (=-1), the function calls open_stream(). Recording is done in the given format, if not provided, the format is guessed based on the filename. If you provide a timestamp ts, it becomes date of the recording.

int     ttyrec_w_write(recorder r, const struct timeval *tm, const char *data, int len);
    A chunk of data of length len is written to recorder r, with timestamp tm. Returns 1 if some sort of write error happened.

int     ttyrec_w_close(recorder r);
    All pending data is flushed, recorder closed and its memory freed. Returns 1 if there's some kind of failure.

const char*   ttyrec_w_get_format_name(int i);
    You can use this function to enumerate known write formats by calling it with i being subsequent numbers starting at 0. An invalid i will return a null pointer.

const char*   ttyrec_w_get_format_ext(const char *format);
    If the given write format is associated with a file extension, it is returned.

  Format decoders:

const char*   ttyrec_r_find_format(const char *format, const char *filename, const char *fallback);
    See the _w_ function, except that read formats are searched instead.

const char*   ttyrec_r_get_format_name(int i);
    ditto

const char*   ttyrec_r_get_format_ext(const char *format);
    ditto

int     ttyrec_r_play(int fd, const char *format, const char *filename,    void (*synch_init_wait)(const struct timeval *ts, void *arg),    void (*synch_wait)(const struct timeval *delay, void *arg),    void (*synch_print)(const char *data, int len, void *arg),    void *arg);
    This function decodes the file fd (opening filename if fd=-1). If its contents contain the date of the recording, you'll receive it through the callback synch_init_wait. Between frames, the delay is passed through synch_wait. The actual frame data goes through synch_print. Note that in some formats, two or more consecutive delays or two consecutive frames can happen one after another. If you provide an arbitrary arg, it will be passed to all callbacks.

    The function doesn't return until the end of input data. Returns 1 on success, 0 on failure.

  The following functions deal with in-memory ttyrecs:

ttyrec          ttyrec_init(tty vt);
    An empty one is allocated. If a vt is provided, it becomes the screen that the ttyrec is internally played on; otherwise, a blank 80x25 one is allocated. The vt is consumed.

ttyrec          ttyrec_load(int fd, const char *format, const char *filename, tty vt);
    This function will load a ttyrec from the file designated with fd. If it's not open yet (fd=-1), it will be opened with open_stream. The ttyrec is played on the vt you provide -- or on a new 80x25 one.

void            ttyrec_free(ttyrec tr);
    Destroys the in-memory ttyrec, freeing its memory.

You can read the ttyrec's data while it's being read; all functions are thread-safe with regard to reading. The frames are stored in structures like this:

typedef struct {
    struct timeval t;
    int len;
    char *data; } *ttyrec_frame;

ttyrec_frame    ttyrec_seek(ttyrec tr, const struct timeval *t, tty *vt);
    Finds the frame that should be shown at time *t, or the first frame if t is null. If vt is not-null, it will receive a terminal containing the screen at that frame.

ttyrec_frame    ttyrec_next_frame(ttyrec tr, ttyrec_frame tfv);
    Returns the next frame after frame tfv, or null if tfv was the last.

void            ttyrec_add_frame(ttyrec tr, const struct timeval *delay, const char *data, int len);
    Creates a new frame and appends it to ttyrec tr.

int             ttyrec_save(ttyrec tr, int fd, const char *format, const char *filename, const struct timeval *selstart, const struct timeval *selend);
    Exports the ttyrec to a new file. If selstart and/or selend are given, they designate the part that should be exported -- if not, the whole is.

  struct timeval arithmetics:
A handful of macros for operating on timeval values:

tadd(t, d)
    t+=d;

tsub(t, d)
    t-=d;

tmul1000(t, m)
    t*=m/1000;

tdiv1000(t, m)
    t/=m/1000;

tcmp(t1, t2)
    If t1<t2, -1. If t1>t2, +1. 0 otherwise.

SEE ALSO
libtty(3)