NAME

libslack(msg) - message module


SYNOPSIS

    #include <slack/std.h>
    #include <slack/msg.h>

    typedef struct Msg Msg;
    typedef void msg_out_t(void *data, const void *mesg, size_t mesglen);
    typedef void msg_release_t(void *data);

    Msg *msg_create(int type, msg_out_t *out, void *data, msg_release_t *destroy);
    Msg *msg_create_with_locker(Locker *locker, int type, msg_out_t *out, void *data, msg_release_t *destroy);
    int msg_rdlock(Msg *mesg);
    int msg_wrlock(Msg *mesg);
    int msg_unlock(Msg *mesg);
    void msg_release(Msg *mesg);
    void *msg_destroy(Msg **mesg);
    void msg_out(Msg *dst, const char *format, ...);
    void msg_out_unlocked(Msg *dst, const char *format, ...);
    void vmsg_out(Msg *dst, const char *format, va_list args);
    void vmsg_out_unlocked(Msg *dst, const char *format, va_list args);
    Msg *msg_create_fd(int fd);
    Msg *msg_create_fd_with_locker(Locker *locker, int fd);
    Msg *msg_create_stderr(void);
    Msg *msg_create_stderr_with_locker(Locker *locker);
    Msg *msg_create_stdout(void);
    Msg *msg_create_stdout_with_locker(Locker *locker);
    Msg *msg_create_file(const char *path);
    Msg *msg_create_file_with_locker(Locker *locker, const char *path);
    Msg *msg_create_syslog(const char *ident, int option, int facility, int priority);
    Msg *msg_create_syslog_with_locker(Locker *locker, const char *ident, int option, int facility, int priority);
    Msg *msg_syslog_set_facility(Msg *mesg, int facility);
    Msg *msg_syslog_set_facility_unlocked(Msg *mesg, int facility);
    Msg *msg_syslog_set_priority(Msg *mesg, int priority);
    Msg *msg_syslog_set_priority_unlocked(Msg *mesg, int priority);
    Msg *msg_create_plex(Msg *msg1, Msg *msg2);
    Msg *msg_create_plex_with_locker(Locker *locker, Msg *msg1, Msg *msg2);
    int msg_add_plex(Msg *mesg, Msg *item);
    int msg_add_plex_unlocked(Msg *mesg, Msg *item);
    const char *msg_set_timestamp_format(const char *format);
    int msg_set_timestamp_format_locker(Locker *locker);
    int syslog_lookup_facility(const char *facility);
    int syslog_lookup_priority(const char *priority);
    const char *syslog_facility_str(int spec);
    const char *syslog_priority_str(int spec);
    int syslog_parse(const char *spec, int *facility, int *priority);


DESCRIPTION

This module provides general messaging functions. Message channels can be created that send messages to a file descriptor, a file, syslog or a client defined message handler or that multiplexes messages to any combination of the above. Messages sent to files are timestamped using (by default) the strftime(3) format: "%Y%m%d %H:%M:%S".

It also provides functions for parsing syslog targets, converting between syslog facility names and codes, and converting between syslog priority names and codes.

Msg *msg_create(int type, msg_out_t *out, void *data, msg_release_t *destroy)

Creates a Msg object initialised with type, out, data and destroy. Client defined message handlers must specify a type greater than 4. It is the caller's responsibility to deallocate the new Msg with msg_release(3) or msg_destroy. On success, returns the new Msg object. On error, returns null.

Msg *msg_create_with_locker(Locker *locker, int type, msg_out_t *out, void *data, msg_release_t *destroy)

Equivalent to msg_create(3) except that multiple threads accessing the new Msg will be synchronised by locker.

int msg_rdlock(Msg *mesg)

Claims a read lock on mesg (if mesg was created with a Locker). This is needed when multiple read only msg(3) module functions need to be called atomically. It is the caller's responsibility to call msg_unlock(3) after the atomic operation. The only functions that may be called on mesg between calls to msg_rdlock(3) and msg_unlock(3) are any read only msg(3) module functions whose name ends with _unlocked. On success, returns 0. On error, returns an error code.

int msg_wrlock(Msg *mesg)

Claims a write lock on mesg.

Claims a write lock on mesg (if mesg was created with a Locker). This is needed when multiple read/write msg(3) module functions need to be called atomically. It is the caller's responsibility to call msg_unlock(3) after the atomic operation. The only functions that may be called on mesg between calls to msg_rdlock(3) and msg_unlock(3) are any msg(3) module functions whose name ends with _unlocked. On success, returns 0. On error, returns an error code.

int msg_unlock(Msg *mesg)

Unlocks a read or write lock on mesg obtained with msg_rdlock(3) or msg_wrlock(3) (if mesg was created with a Locker). On success, returns 0. On error, returns an error code.

void msg_release(Msg *mesg)

Releases (deallocates) mesg and its internal data.

void *msg_destroy(Msg **mesg)

Destroys (deallocates and sets to null) *mesg. Returns null.

void msg_out(Msg *dst, const char *format, ...)

Sends a message to dst. format is a printf(3)-like format string. Any remaining arguments are processed as in printf(3).

Warning: Do not under any circumstances ever pass a non-literal string as the format argument unless you know exactly how many conversions will take place. Being careless with this is a very good way to build potential security holes into your programs. The same is true for all functions that take a printf()-like format string as an argument.

    msg_out(dst, buf);       // EVIL
    msg_out(dst, "%s", buf); // GOOD
void msg_out_unlocked(Msg *dst, const char *format, ...)

Equivalent to msg_out(3) except that dst is not read locked.

void vmsg_out(Msg *dst, const char *format, va_list args)

Sends a message to dst. format is a printf(3)-like format string. args is processed as in vprintf(3).

void vmsg_out_unlocked(Msg *dst, const char *format, va_list args)

Equivalent to vmsg_out(3) except that dst is not read locked.

Msg *msg_create_fd(int fd)

Creates a Msg object that sends messages to file descriptor fd. It is the caller's responsibility to deallocate the new Msg with msg_release(3) or msg_destroy(3). On success, returns the new Msg object. On error, returns null.

Msg *msg_create_fd_with_locker(Locker *locker, int fd)

Equivalent to msg_create_fd(3) except that multiple threads accessing the new Msg will be synchronised by locker.

Msg *msg_create_stderr(void)

Creates a Msg object that sends messages to standard error. It is the caller's responsibility to deallocate the new Msg with msg_release(3) or msg_destroy(3). On success, returns the new Msg object. On error, returns null.

Msg *msg_create_stderr_with_locker(Locker *locker)

Equivalent to msg_create_stderr(3) except that multiple threads accessing the new Msg will be synchronised by locker.

Msg *msg_create_stdout(void)

Creates a Msg object that sends messages to standard output. It is the caller's responsibility to deallocate the new Msg with msg_release(3) or msg_destroy(3). On success, returns the new Msg object. On error, returns null.

Msg *msg_create_stdout_with_locker(Locker *locker)

Equivalent to msg_create_stdout(3) except that multiple threads accessing the new Msg will be synchronised by locker.

Msg *msg_create_file(const char *path)

Creates a Msg object that sends messages to the file specified by path. It is the caller's responsibility to deallocate the new Msg with msg_release(3) or msg_destroy(3). On success, returns the new Msg object. On error, returns null with errno set appropriately.

Msg *msg_create_file_with_locker(Locker *locker, const char *path)

Equivalent to msg_create_file(3) except that multiple threads accessing the new Msg will be synchronised by locker.

Msg *msg_create_syslog(const char *ident, int option, int facility, int priority)

Creates a Msg object that sends messages to syslog initialised with ident, option, facility and priority. It is the caller's responsibility to deallocate the new Msg with msg_release(3) or msg_destroy(3). On success, returns the new Msg object. On error, returns null with errno set appropriately.

Msg *msg_create_syslog_with_locker(Locker *locker, const char *ident, int option, int facility, int priority)

Equivalent to msg_create_syslog(3) except that multiple threads accessing the new Msg will be synchronised by locker.

Msg *msg_syslog_set_facility(Msg *mesg, int facility)

Sets the facility field in mesg's data to facility. On success, returns mesg. On error, returns null with errno set appropriately.

Msg *msg_syslog_set_facility_unlocked(Msg *mesg, int facility)

Equivalent to msg_syslog_set_facility(3) except that mesg is not write locked.

Msg *msg_syslog_set_priority(Msg *mesg, int priority)

Sets the priority field in mesg's data to priority. On success, returns mesg. On error, returns null with errno set appropriately.

Msg *msg_syslog_set_priority_unlocked(Msg *mesg, int priority)

Equivalent to msg_syslog_set_priority(3) except that mesg is not write locked.

Msg *msg_create_plex(Msg *msg1, Msg *msg2)

Creates a Msg object that multiplexes messages to msg1 and msg2. Further Msg objects may be added to its list using msg_add_plex(3). It is the caller's responsibility to deallocate the new Msg with msg_release(3) or msg_destroy(3). On success, returns the new Msg object. On error, returns null with errno set appropriately.

Msg *msg_create_plex_with_locker(Locker *locker, Msg *msg1, Msg *msg2)

Equivalent to msg_create_plex(3) except that multiple threads accessing the new Msg will be synchronised by locker.

int msg_add_plex(Msg *mesg, Msg *item)

Adds item to the list of Msg objects multiplexed by mesg. On success, returns 0. On error, returns -1 with errno set appropriately.

int msg_add_plex_unlocked(Msg *mesg, Msg *item)

Equivalent to msg_add_plex(3) except that mesg is not write locked.

const char *msg_set_timestamp_format(const char *format)

Sets the strftime(3) format string used when sending messages to a file. By default, it is "%Y%m%d %H:%M:%S ". On success, returns the previous format string. On error, returns null with errno set appropriately.

int msg_set_timestamp_format_locker(Locker *locker)

Sets the locking strategy for changing the timestamp format used when sending messages to a file. This is only needed if the timestamp format will be modified in multiple threads. On success, returns 0. On error, returns -1 with errno set appropriately.

int syslog_lookup_facility(const char *facility)

Returns the code corresponding to facility. If not found, returns -1.

int syslog_lookup_priority(const char *priority)

Returns the code corresponding to priority. If not found, returns -1.

const char *syslog_facility_str(int spec)

Returns the name corresponding to the facility part of spec. If not found, returns null.

const char *syslog_priority_str(int spec)

Returns the name corresponding to the priority part of spec. If not found, returns null.

int syslog_parse(const char *spec, int *facility, int *priority)

Parses spec as a facility.priority string. If facility is non-null, the parsed facility is stored in the location pointed to by facility. If priority is non-null the parsed priority is stored in the location pointed to by priority. On success, returns 0. On error, returns -1 with errno set appropriately.

    syslog facilities          syslog priorities
    ----------------------     -----------------------
    "kern"      LOG_KERN       "emerg"       LOG_EMERG
    "user"      LOG_USER       "alert"       LOG_ALERT
    "mail"      LOG_MAIL       "crit"        LOG_CRIT
    "daemon"    LOG_DAEMON     "err"         LOG_ERR
    "auth"      LOG_AUTH       "warning"     LOG_WARNING
    "syslog"    LOG_SYSLOG     "info"        LOG_INFO
    "lpr"       LOG_LPR        "debug"       LOG_DEBUG
    "news"      LOG_NEWS
    "uucp"      LOG_UUCP
    "cron"      LOG_CRON
    "local0"    LOG_LOCAL0
    "local1"    LOG_LOCAL1
    "local2"    LOG_LOCAL2
    "local3"    LOG_LOCAL3
    "local4"    LOG_LOCAL4
    "local5"    LOG_LOCAL5
    "local6"    LOG_LOCAL6
    "local7"    LOG_LOCAL7


ERRORS

On error, errno is set by underlying functions or as follows:

EINVAL

An argument was null or could not be parsed.


MT-Level

MT-Disciplined - msg functions - See locker(3) for details.

MT-Safe - syslog functions


EXAMPLE

Parse syslog facility priority pair:

    #include <slack/std.h>
    #include <slack/msg.h>

    int main(int ac, char **av)
    {
        int facility, priority;

        if (syslog_parse(av[1], &facility, &priority) != -1)
            syslog(facility | priority, "syslog(%s)", av[1]);

        return EXIT_SUCCESS;
    }

Multiplex a message to several locations:

    #include <slack/std.h>
    #include <slack/msg.h>

    int main(int ac, char **av)
    {
        Msg *stdout_msg = msg_create_stdout();
        Msg *stderr_msg = msg_create_stderr();
        Msg *file_msg = msg_create_file("/tmp/junk");
        Msg *syslog_msg = msg_create_syslog("ident", 0, LOG_DAEMON, LOG_ERR);
        Msg *plex_msg = msg_create_plex(stdout_msg, stderr_msg);

        msg_add_plex(plex_msg, file_msg);
        msg_add_plex(plex_msg, syslog_msg);

        msg_out(plex_msg, "Multiplex message\n");
        unlink("/tmp/junk");

        return EXIT_SUCCESS;
    }


SEE ALSO

libslack(3), err(3), prog(3), openlog(3), syslog(3), locker(3)


AUTHOR

20100612 raf <raf@raf.org>