/* acap.h -- connection level ACAP API * * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* $Id: acap.h,v 1.16 2003/02/13 20:15:17 rjs3 Exp $ */ #ifndef ACAP_H #define ACAP_H #include #include "skip-list.h" /* -------- error codes -------- */ #define ACAP_OK (0) #include /* ------- initialization -------- */ /* be sure to call srand() before acap_init(); we use randomized data structures. (eventually, use our own rand() to avoid clashes?) */ int acap_init(void); /* -------- connections -------- */ struct acap_conn_s; typedef struct acap_conn_s acap_conn_t; /* application should setup callbacks for AUTHNAME and password if required; connect will set a connection callback for the user listed in the URL */ int acap_conn_connect(const char *url, sasl_callback_t *cb, acap_conn_t **conn); int acap_conn_close(acap_conn_t *conn); /* it's only valid to use this socket to select() after acap_process with ACAP_PROCESS_NOBLOCK set returns ACAP_WOULD_BLOCK. otherwise, hands off. */ int acap_conn_get_sock(acap_conn_t *conn); int acap_get_sasl_error(acap_conn_t *conn); /* -------- acap data ---------- */ typedef struct acap_value_s { unsigned len; struct acap_value_s *next; char data[1]; } acap_value_t; typedef struct { char *name; enum { ACAP_VALUE_SINGLE, ACAP_VALUE_LIST, ACAP_VALUE_DEFAULT, ACAP_VALUE_NIL } t; /* value */ acap_value_t *v; /* should have space for metadata here */ } acap_attribute_t; struct acap_entry_s { char *name; /* must be >= 1024 chars */ int refcount; /* contains a list of attributes, ordered by attrname */ skiplist *attrs; }; typedef struct acap_entry_s acap_entry_t; void acap_entry_free(acap_entry_t *e); acap_entry_t *acap_entry_copy(acap_entry_t *e); acap_entry_t *acap_entry_new(char *name); char *acap_entry_getname(acap_entry_t *e); acap_value_t *acap_entry_getattr(acap_entry_t *e, char *attrname); char *acap_entry_getattr_simple(acap_entry_t *e, char *attrname); acap_attribute_t *acap_attribute_new(char *attrname); acap_attribute_t *acap_attribute_new_simple(char *attrname, char *attrvalue); void acap_attribute_free(acap_attribute_t *a); /* ------- command ----------- */ typedef enum { ACAP_RESULT_NOTDONE, ACAP_RESULT_OK, ACAP_RESULT_NO, ACAP_RESULT_BAD } acap_result_t; typedef struct acap_cmd_s acap_cmd_t; typedef void acap_cb_completion_t(acap_result_t res, void *rock); int acap_conn_noop(acap_conn_t *conn, acap_cb_completion_t *cmd_cb, void *rock, acap_cmd_t **ret); /* ------ searching -------- */ struct acap_search_callback { void (*entry_data)(acap_entry_t *entry, void *rock); void (*modtime)(char *modtime, void *rock); }; struct acap_context_callback { void (*addto)(acap_entry_t *entry, unsigned position, void * rock); void (*removefrom)(acap_entry_t *entry, unsigned position, void *rock); void (*change)(acap_entry_t *entry, unsigned old_position, unsigned new_position, void *rock); void (*modtime)(char *time, void *rock); }; typedef struct acap_context_s acap_context_t; /* if search_cb == NULL, no data is returned but a context can be created */ /* if context_ptr != NULL, a context is created if context_cb != NULL, a notification context is created if sort_order != NULL, a enumerated context is created */ struct acap_request { char *attrname; enum { ATTRIBUTE = 0x01, VALUE = 0x02, SIZE = 0x04 } ret; }; struct acap_requested { int n_attrs; struct acap_request attrs[1]; }; struct acap_sort { char *attrname; char *comparator; struct acap_sort *next; }; int acap_search_dataset(acap_conn_t *conn, const char *dataset, char *spec, int depth, const struct acap_requested *ret_attrs, const struct acap_sort *sort_order, const acap_cb_completion_t *cmd_cb, const struct acap_search_callback *search_cb, acap_context_t **context_ptr, const struct acap_context_callback *context_cb, void *rock, acap_cmd_t **ret); int acap_search_context(acap_conn_t *conn, acap_context_t *context, char *spec, struct acap_requested *ret_attrs, struct acap_sort *sort_order, acap_cb_completion_t *cmd_cb, struct acap_search_callback *search_cb, void *rock, acap_cmd_t **ret); int acap_updatecontext(acap_conn_t *conn, acap_context_t *context, acap_cb_completion_t *cmd_cb, void *rock, acap_cmd_t **ret); /* --------- storing ----------- */ #define ACAP_STORE_INITIAL 0x01 #define ACAP_STORE_FORCE 0x02 int acap_store_entry(acap_conn_t *conn, acap_entry_t *entry, acap_cb_completion_t *cmd_cb, void *rock, int flags, acap_cmd_t **ret); int acap_store_attribute(acap_conn_t *conn, const char *entry, acap_attribute_t *attr, char *unchangedsince, acap_cb_completion_t *cmd_cb, void *rock, acap_cmd_t **ret); /* -------- deleting --------- */ int acap_delete_entry_name(acap_conn_t *conn, const char *name, acap_cb_completion_t *cmd_cb, void *rock, acap_cmd_t **ret); int acap_delete_entry(acap_conn_t *conn, acap_entry_t *entry); int acap_delete_attribute(acap_conn_t *conn, char *entryname, char *attrname, acap_cb_completion_t *cmd_cb, void *rock, acap_cmd_t **ret); /* -------- processing -------- */ #define ACAP_PROCESS_NOBLOCK 1 int acap_process_on_command(acap_conn_t *conn, acap_cmd_t *cmd, acap_result_t *res); int acap_process_outstanding(acap_conn_t *conn); int acap_process_line(acap_conn_t *conn, int flag); #endif /* ACAP_H */