Linux and UNIX Man Pages

Linux & Unix Commands - Search Man Pages

auparse_feed(3) [debian man page]

AUPARSE_FEED(3) 						  Linux Audit API						   AUPARSE_FEED(3)

NAME
auparse_feed - feed data into parser SYNOPSIS
#include <auparse.h> int auparse_feed(auparse_state_t *au, const char *data, size_t data_len); au The audit parse state data a buffer of data to feed into the parser, it is data_len bytes long. The data is copied in the parser, upon return the caller may free or reuse the data buffer. data_len number of bytes in data DESCRIPTION
auparse_feed supplies new data for the parser to consume. auparse_init() must have been called with a source type of AUSOURCE_FEED and a NULL pointer. The parser consumes as much data as it can invoking a user supplied callback specified with auparse_add_callback with a cb_event_type of AUPARSE_CB_EVENT_READY each time the parser recognizes a complete event in the data stream. Data not fully parsed will persist and be prepended to the next feed data. After all data has been feed to the parser auparse_flush_feed should be called to signal the end of input data and flush any pending parse data through the parsing system. EXAMPLE
void auparse_callback(auparse_state_t *au, auparse_cb_event_t cb_event_type, void *user_data) { int *event_cnt = (int *)user_data; if (cb_event_type == AUPARSE_CB_EVENT_READY) { if (auparse_first_record(au) <= 0) return; printf("event: %d ", *event_cnt); printf("records:%d ", auparse_get_num_records(au)); do { printf("fields:%d ", auparse_get_num_fields(au)); printf("type=%d ", auparse_get_type(au)); const au_event_t *e = auparse_get_timestamp(au); if (e == NULL) return; printf("event time: %u.%u:%lu ", (unsigned)e->sec, e->milli, e->serial); auparse_first_field(au); do { printf("%s=%s (%s) ", auparse_get_field_name(au), auparse_get_field_str(au), auparse_interpret_field(au)); } while (auparse_next_field(au) > 0); printf(" "); } while(auparse_next_record(au) > 0); (*event_cnt)++; } } main(int argc, char **argv) { char *filename = argv[1]; FILE *fp; char buf[256]; size_t len; int *event_cnt = malloc(sizeof(int)); au = auparse_init(AUSOURCE_FEED, 0); *event_cnt = 1; auparse_add_callback(au, auparse_callback, event_cnt, free); if ((fp = fopen(filename, "r")) == NULL) { fprintf(stderr, "could not open '%s', %s0, filename, strerror(errno)); return 1; } while ((len = fread(buf, 1, sizeof(buf), fp))) { auparse_feed(au, buf, len); } auparse_flush_feed(au); } RETURN VALUE
Returns -1 if an error occurs; otherwise, 0 for success. SEE ALSO
auparse_add_callback(3), auparse_flush_feed(3) AUTHOR
John Dennis Red Hat May 2007 AUPARSE_FEED(3)

Check Out this Related Man Page

ivykis(3)						    ivykis programmer's manual							 ivykis(3)

NAME
iv_examples - ivykis examples EXAMPLE
ivykis is initialised by calling iv_init(3). This function is the first function to call when dealing with ivykis -- it has to be called before registering file descriptors or timers. The ivykis main event loop is started by calling iv_main(3). This function generally does not return, except when iv_quit(3) is called somewhere during execution of the program. An application asks ivykis to monitor a certain file descriptor by filling out a structure of type 'struct iv_fd' with a file descriptor number and a callback function, and calling the function iv_fd_register. The first example program waits for data from standard input, and writes a message to standard out whenever something is received: #include <stdio.h> #include <stdlib.h> #include <iv.h> struct iv_fd fd_stdin; static void callback(void *dummy) { char buf[1024]; int len; len = read(fd_stdin.fd, buf, sizeof(buf)); if (len <= 0) { if (len < 0) { if (errno == EAGAIN) return; perror("read"); } exit(1); } printf("read %d bytes of data from stdin ", len); } int main() { iv_init(); IV_FD_INIT(&fd_stdin); fd_stdin.fd = 0; fd_stdin.handler_in = callback; iv_fd_register(&fd_stdin); iv_main(); iv_deinit(); return 0; } The application is responsible for memory management of 'struct iv_fd's passed to ivykis. For example, it should not free memory that con- tains such structures that are still registered with ivykis (i.e. haven't had iv_fd_unregister called on them). iv_fd_register transparently sets the passed file descriptor to nonblocking mode, in anticipation of its future usage. File descriptor callbacks are called in a level-triggered fashion. Therefore, the way of dealing with fd_stdin in the example callback function is safe. In case there arrives data between read and detecting EAGAIN, ivykis will re-call the callback function after it returns. Also, if there are more than 1024 bytes waiting in the input buffer, ivykis will re-call the callback function until all data from stdin have been drained. EXAMPLE 2 The second example accepts connections on TCP port 6667, and waits on each of the connections for data. When data is received on any con- nection, a message is printed to standard out. #include <stdio.h> #include <stdlib.h> #include <iv.h> #include <netinet/in.h> struct connection { struct iv_fd fd; /* other per-connection data goes here */ }; struct listening_socket { struct iv_fd fd; /* other per-listening socket data goes here */ }; static void connection_handler(void *_conn) { struct connection *conn = (struct connection *)_conn; char buf[1024]; int len; len = read(conn->fd.fd, buf, sizeof(buf)); if (len <= 0) { if (len < 0 && errno == EAGAIN) return; iv_fd_unregister(&conn->fd); close(conn->fd.fd); free(conn); return; } printf("got %d bytes of data from %p ", len, conn); } static void listening_socket_handler(void *_sock) { struct listening_socket *sock = (struct listening_socket *)_sock; struct sockaddr_in addr; socklen_t addrlen; struct connection *conn; int fd; addrlen = sizeof(addr); fd = accept(sock->fd.fd, (struct sockaddr *)&addr, &addrlen); if (fd < 0) { if (errno == EAGAIN) return; perror("accept"); exit(1); } conn = malloc(sizeof(*conn)); if (conn == NULL) { fprintf(stderr, "listening_socket_handler: memory allocation error, dropping connection"); close(fd); return; } IV_FD_INIT(&conn->fd); conn->fd.fd = fd; conn->fd.cookie = (void *)conn; conn->fd.handler_in = connection_handler; iv_fd_register(&conn->fd); } int main() { struct listening_socket s; struct sockaddr_in addr; int fd; fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { perror("socket"); exit(1); } addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(6667); if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); exit(1); } if (listen(fd, 4) < 0) { perror("listen"); exit(1); } iv_init(); IV_FD_INIT(&s.fd); s.fd.fd = fd; s.fd.cookie = (void *)&s; s.fd.handler_in = listening_socket_handler; iv_fd_register(&s.fd); iv_main(); iv_deinit(); return 0; } As illustrated, it is possible to pass cookies into callback functions. This is useful for conveying information on which higher-level entity (such as 'connection' or 'listening socket') generated the event for which the callback was called. Note how it is possible to unregister and even free a 'struct iv_fd' in its own callback function. There is logic in ivykis to deal with this case. EXAMPLE 3 This example extends the previous example by a per-connection timer that disconnects the client after too long a period of inactivity. Lines not present in example 2 or different than in example 2 are indicated by '//XXXX' in the right-hand margin. #include <stdio.h> #include <stdlib.h> #include <iv.h> #include <netinet/in.h> #define CONNECTION_TIMEOUT(10) struct connection { struct iv_fd fd; struct iv_timer disconnect_timeout; //XXXX /* other per-connection data goes here */ }; struct listening_socket { struct iv_fd fd; /* other per-listening socket data goes here */ }; static void connection_handler(void *_conn) { struct connection *conn = (struct connection *)_conn; char buf[1024]; int len; len = read(conn->fd.fd, buf, sizeof(buf)); if (len <= 0) { if (len < 0 && errno == EAGAIN) return; iv_timer_unregister(&conn->disconnect_timeout); //XXXX iv_fd_unregister(&conn->fd); close(conn->fd.fd); free(conn); return; } printf("got %d bytes of data from %p ", len, conn); iv_timer_unregister(&conn->disconnect_timeout); //XXXX iv_validate_now(); //XXXX conn->disconnect_timeout.expires = iv_now; //XXXX conn->disconnect_timeout.expires.tv_sec += CONNECTION_TIMEOUT;//XXXX iv_timer_register(&conn->disconnect_timeout); //XXXX } static void disconnect_timeout_expired(void *_conn) //XXXX { //XXXX struct connection *conn = (struct connection *)_conn; //XXXX iv_fd_unregister(&conn->fd); //XXXX close(conn->fd.fd); //XXXX free(conn); //XXXX } //XXXX static void listening_socket_handler(void *_sock) { struct listening_socket *sock = (struct listening_socket *)_sock; struct sockaddr_in addr; socklen_t addrlen; struct connection *conn; int fd; addrlen = sizeof(addr); fd = accept(sock->fd.fd, (struct sockaddr *)&addr, &addrlen); if (fd < 0) { if (errno == EAGAIN) return; perror("accept"); exit(1); } conn = malloc(sizeof(*conn)); if (conn == NULL) { fprintf(stderr, "listening_socket_handler: memory allocation error, dropping connection"); close(fd); return; } IV_FD_INIT(&conn->fd); conn->fd.fd = fd; conn->fd.cookie = (void *)conn; conn->fd.handler_in = connection_handler; iv_fd_register(&conn->fd); IV_TIMER_INIT(&conn->disconnect_timeout); //XXXX iv_validate_now(); //XXXX conn->disconnect_timeout.cookie = (void *)conn; //XXXX conn->disconnect_timeout.handler = disconnect_timeout_expired;//XXXX conn->disconnect_timeout.expires = iv_now; //XXXX conn->disconnect_timeout.expires.tv_sec += CONNECTION_TIMEOUT;//XXXX iv_timer_register(&conn->disconnect_timeout); //XXXX } int main() { struct listening_socket s; struct sockaddr_in addr; int fd; fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { perror("socket"); exit(1); } addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(6667); if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); exit(1); } if (listen(fd, 4) < 0) { perror("listen"); exit(1); } iv_init(); IV_FD_INIT(&s.fd); s.fd.fd = fd; s.fd.cookie = (void *)&s; s.fd.handler_in = listening_socket_handler; iv_fd_register(&s.fd); iv_main(); iv_deinit(); return 0; } The global variable 'iv_now' contains the current time-of-day. However, it is updated lazily, and its contents might be stale at any given time. Before using it, iv_validate_now(3) must be called. EXAMPLE 4 The fourth example demonstrates how to use a custom fatal error handler that does not write the message to syslog. #include <stdio.h> #include <iv.h> static void fatal_error(const char *msg) { fprintf(stderr, "ivykis: FATAL ERROR: %s ", msg); } int main() { iv_init(); iv_set_fatal_msg_handler(fatal_error); iv_fatal("Programmatically triggered fatal error %d.", 42); printf("This code is never reached. "); iv_deinit(); return 0; } This program will abort immediately, with the error message printed to the standard error stream. SEE ALSO
ivykis(3), iv_fatal(3), iv_fd(3), iv_timer(3), iv_task(3), iv_init(3), iv_time(3) ivykis 2003-03-29 ivykis(3)
Man Page