/* Copyright 2010 Nathan Phillip Brink, Ethan Zonca This file is a part of DistRen. DistRen is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. DistRen is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with DistRen. If not, see . */ #ifndef _DISTREN_REMOTEIO_H #define _DISTREN_REMOTEIO_H #include /** * @file RemoteIO provides an abstraction to the method of talking to a remote distrend. It is a layer on top of execio that should provide an equivalent interface. * * RemoteIO works on top of multiio, so for it to work you write your * program in an event-oriented fashion and call multiio_poll(). */ struct remoteio_opts; struct remoteio; /** * asynchronous read handler signature. * * This is the signature of the callback that is called when data is * available for reading. The handler may process as much of the * available data as it wants. When it has processed a chunk of data, * it must return the length of the data that it processed. If the * handler returns 0, the handler is essentially signalling ``I can't * figure out what this means until I see more''. * * If you need to close a socket after reading certain data from it, * you may call remoteio_close() from inside of this function. * * @param rem the associated remoteio handle * @param generic_data a pointer that is stored in remoteio's struct remoteio_opts which isn't client-specific * @param buf a pointer to the buffer containing data waiting to be processed * @param len the size of buf that may be accessed * @param data the pointer passed to remoteio_open(). _NOT_ the data just received on the socket. * @return the number of bytes that the function accepted and thus should be removed from the rem handle. */ typedef size_t(*remoteio_read_handle_func_t)(struct remoteio *rem, void *generic_data, void *buf, size_t len, void *data); /** * asynchronous close handler which is called whenever remoteio_close() is called. * * As reading is now event-oriented and as libremoteio may itself call * remoteio_close(), you need a way to be informed that a socket is * being closed. This is particularly important if you have to clean * up your read_handler_data. * * @param generic_data a pointer set by a call to remoteio_generic_data_set(). * @param data the same pointer passed to remoteio_open(). */ typedef void (*remoteio_close_handle_func_t)(void *generic_data, void *data); /** * Determines the value of generic_data which is passed to * remoteio_read_handle_func_t * * @param opts the remoteio runtime options */ int remoteio_generic_data_set(struct remoteio_opts *opts, void *generic_data); /** Opens connection with to a remote distrend. Returns 1 on error. @todo should this be asynchronous? YES! but optionally, perhaps @param opts the configuration settings for remoteio gotten from options_init(). @param read_handler the function to call when data has been read from the server. @param read_handler_data the data to pass to the read_handler function. @param servername the name of the configuration file entry for the server. From this, information about how to make the outgoing connection is derived. */ int remoteio_open_server(struct remoteio **rem, struct remoteio_opts *opts, remoteio_read_handle_func_t read_handler, void *read_handler_data, remoteio_close_handle_func_t close_handler, const char *servername); /** * Initializes a remoteio instance for a socket that's already been floating * around for a while. I.e., this socket probably came from accept(). * * @param rem a pointer to where the poiner to the newly allocated struct remoteio should be stored. * @param opts remoteio's options * @param read_handler the function to call when data has been read from the server. * @param read_handler_data the data to pass to the read_handler function. * @param opts self explanatory. */ int remoteio_open_socket(struct remoteio **rem, struct remoteio_opts *opts, remoteio_read_handle_func_t read_handler, void *read_handler_data, remoteio_close_handle_func_t close_handler, int fd); /** * Queue bytes to be written to the remote host. * * @param rem the remoteio handle * @param buf a buffer to be queued for writing. We will copy this, so the caller has to handle its memory (and free() it if necessary). * @param len number of bytes to grab from buf * @return 0 on success, 1 on failure */ int remoteio_write(struct remoteio *rem, const void *buf, size_t len); /** * \brief Retrieves authentication information associated with a * server's configuration entry. * * Possibly, the whole idea of remoteio handling server names with the * remoteio_open() function should be moved somewhere else and * remoteio should be more general-purpose I/O? * * \param rem_opts A remoteio options handle. * \param servername The name of the server whose information should be retrieved. * \param username Where to store a pointer to the username. Do not free this. * \param pass Where to store a pointer to the password. Do not free this. */ int remoteio_authinfo_get(struct remoteio_opts *rem_opts, const char *servername, const char **username, const char **pass); /** * Closes a remoteio session. * * It is safe to call this function from within * remoteio_read_handle_func_t. * * @return nonzero on error */ int remoteio_close(struct remoteio *rem); /** * Returns the number of unfulfilled remoteio_write() calls pending on * a remoteio handle. */ size_t remoteio_sendq_len(const struct remoteio *rem); #endif