diff options
| author | Alexandra Ellwood <lxs@mit.edu> | 2007-05-31 21:06:54 +0000 |
|---|---|---|
| committer | Alexandra Ellwood <lxs@mit.edu> | 2007-05-31 21:06:54 +0000 |
| commit | d45eeb7f708d5be2e9fbdbc54a04655776074f6c (patch) | |
| tree | 5ab3d7e31f285ac4d6900d3abc647cbb53a05f8d /src/ccapi/server | |
| parent | 66bd29f512b9bdd5e808d645118862112973d2d6 (diff) | |
| download | krb5-d45eeb7f708d5be2e9fbdbc54a04655776074f6c.tar.gz krb5-d45eeb7f708d5be2e9fbdbc54a04655776074f6c.tar.xz krb5-d45eeb7f708d5be2e9fbdbc54a04655776074f6c.zip | |
Move CCAPI sources to krb5 repository
ticket: new
status: open
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19564 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/ccapi/server')
32 files changed, 6155 insertions, 0 deletions
diff --git a/src/ccapi/server/ccs_array.c b/src/ccapi/server/ccs_array.c new file mode 100644 index 000000000..c798c7a3a --- /dev/null +++ b/src/ccapi/server/ccs_array.c @@ -0,0 +1,145 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" +#include "cci_array_internal.h" + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_pipe_object_release (void *io_pipe) +{ + return cci_check_error (ccs_pipe_release ((ccs_pipe_t) io_pipe)); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_pipe_array_new (ccs_pipe_array_t *out_array) +{ + return cci_array_new (out_array, ccs_pipe_object_release); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_pipe_array_release (ccs_pipe_array_t io_array) +{ + return cci_array_release (io_array); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_uint64 ccs_pipe_array_count (ccs_pipe_array_t in_array) +{ + return cci_array_count (in_array); +} + +/* ------------------------------------------------------------------------ */ + +inline ccs_pipe_t ccs_pipe_array_object_at_index (ccs_pipe_array_t io_array, + cc_uint64 in_position) +{ + return cci_array_object_at_index (io_array, in_position); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_pipe_array_insert (ccs_pipe_array_t io_array, + ccs_pipe_t in_pipe, + cc_uint64 in_position) +{ + return cci_array_insert (io_array, in_pipe, in_position); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_pipe_array_remove (ccs_pipe_array_t io_array, + cc_uint64 in_position) +{ + return cci_array_remove (io_array, in_position); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_lock_object_release (void *io_lock) +{ + return cci_check_error (ccs_lock_release ((ccs_lock_t) io_lock)); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_lock_array_new (ccs_lock_array_t *out_array) +{ + return cci_array_new (out_array, ccs_lock_object_release); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_lock_array_release (ccs_lock_array_t io_array) +{ + return cci_array_release (io_array); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_uint64 ccs_lock_array_count (ccs_lock_array_t in_array) +{ + return cci_array_count (in_array); +} + +/* ------------------------------------------------------------------------ */ + +inline ccs_lock_t ccs_lock_array_object_at_index (ccs_lock_array_t io_array, + cc_uint64 in_position) +{ + return cci_array_object_at_index (io_array, in_position); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_lock_array_insert (ccs_lock_array_t io_array, + ccs_lock_t in_lock, + cc_uint64 in_position) +{ + return cci_array_insert (io_array, in_lock, in_position); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_lock_array_remove (ccs_lock_array_t io_array, + cc_uint64 in_position) +{ + return cci_array_remove (io_array, in_position); +} + +/* ------------------------------------------------------------------------ */ +inline cc_int32 ccs_lock_array_move (ccs_lock_array_t io_array, + cc_uint64 in_position, + cc_uint64 in_new_position, + cc_uint64 *out_real_new_position) +{ + return cci_array_move (io_array, in_position, in_new_position, out_real_new_position); +} diff --git a/src/ccapi/server/ccs_array.h b/src/ccapi/server/ccs_array.h new file mode 100644 index 000000000..865647c1c --- /dev/null +++ b/src/ccapi/server/ccs_array.h @@ -0,0 +1,71 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_ARRAY_H +#define CCS_ARRAY_H + +#include "ccs_types.h" + +inline cc_int32 ccs_pipe_array_new (ccs_pipe_array_t *out_array); + +inline cc_int32 ccs_pipe_array_release (ccs_pipe_array_t io_array); + +inline cc_uint64 ccs_pipe_array_count (ccs_pipe_array_t in_array); + +inline ccs_pipe_t ccs_pipe_array_object_at_index (ccs_pipe_array_t io_array, + cc_uint64 in_position); + +inline cc_int32 ccs_pipe_array_insert (ccs_pipe_array_t io_array, + ccs_pipe_t in_pipe, + cc_uint64 in_position); + +inline cc_int32 ccs_pipe_array_remove (ccs_pipe_array_t io_array, + cc_uint64 in_position); + +#pragma mark - + +inline cc_int32 ccs_lock_array_new (ccs_lock_array_t *out_array); + +inline cc_int32 ccs_lock_array_release (ccs_lock_array_t io_array); + +inline cc_uint64 ccs_lock_array_count (ccs_lock_array_t in_array); + +inline ccs_lock_t ccs_lock_array_object_at_index (ccs_lock_array_t io_array, + cc_uint64 in_position); + +inline cc_int32 ccs_lock_array_insert (ccs_lock_array_t io_array, + ccs_lock_t in_lock, + cc_uint64 in_position); + +inline cc_int32 ccs_lock_array_remove (ccs_lock_array_t io_array, + cc_uint64 in_position); + +inline cc_int32 ccs_lock_array_move (ccs_lock_array_t io_array, + cc_uint64 in_position, + cc_uint64 in_new_position, + cc_uint64 *out_real_new_position); + +#endif /* CCS_ARRAY_H */ diff --git a/src/ccapi/server/ccs_cache_collection.c b/src/ccapi/server/ccs_cache_collection.c new file mode 100644 index 000000000..4927aaacb --- /dev/null +++ b/src/ccapi/server/ccs_cache_collection.c @@ -0,0 +1,949 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +struct ccs_cache_collection_d { + cc_time_t last_changed_time; + cc_uint64 next_unique_name; + cci_identifier_t identifier; + ccs_lock_state_t lock_state; + ccs_ccache_list_t ccaches; +}; + +struct ccs_cache_collection_d ccs_cache_collection_initializer = { 0, 0, NULL, NULL, NULL }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_new (ccs_cache_collection_t *out_cache_collection) +{ + cc_int32 err = ccNoError; + ccs_cache_collection_t cache_collection = NULL; + + if (!out_cache_collection) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cache_collection = malloc (sizeof (*cache_collection)); + if (cache_collection) { + *cache_collection = ccs_cache_collection_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_server_new_identifier (&cache_collection->identifier); + } + + if (!err) { + err = ccs_lock_state_new (&cache_collection->lock_state, + ccErrInvalidContext, + ccErrContextLocked, + ccErrContextUnlocked); + } + + if (!err) { + err = ccs_ccache_list_new (&cache_collection->ccaches); + } + + if (!err) { + err = ccs_cache_collection_changed (cache_collection); + } + + if (!err) { + *out_cache_collection = cache_collection; + cache_collection = NULL; + } + + ccs_cache_collection_release (cache_collection); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_release (ccs_cache_collection_t io_cache_collection) +{ + cc_int32 err = ccNoError; + + if (!io_cache_collection) { err = ccErrBadParam; } + + if (!err) { + cci_identifier_release (io_cache_collection->identifier); + ccs_lock_state_release (io_cache_collection->lock_state); + ccs_ccache_list_release (io_cache_collection->ccaches); + free (io_cache_collection); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_compare_identifier (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_equal ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_compare (in_cache_collection->identifier, + in_identifier, + out_equal); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collection) +{ + cc_int32 err = ccNoError; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_time_t now = time (NULL); + + if (io_cache_collection->last_changed_time < now) { + io_cache_collection->last_changed_time = now; + } else { + io_cache_collection->last_changed_time++; + } + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_find_ccache_by_name (ccs_cache_collection_t in_cache_collection, + const char *in_name, + ccs_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + ccs_ccache_list_iterator_t iterator = NULL; + + if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_name ) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, &iterator); + } + + while (!err) { + ccs_ccache_t ccache = NULL; + + err = ccs_ccache_list_iterator_next (iterator, &ccache); + + if (!err) { + cc_uint32 equal = 0; + + err = ccs_ccache_compare_name (ccache, in_name, &equal); + + if (!err && equal) { + *out_ccache = ccache; + break; + } + } + } + if (err == ccIteratorEnd) { err = ccErrCCacheNotFound; } + + if (iterator) { ccs_ccache_list_iterator_release (iterator); } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_find_ccache (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + ccs_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + + if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_find (in_cache_collection->ccaches, + in_identifier, out_ccache); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_collection_move_ccache (ccs_cache_collection_t io_cache_collection, + cci_identifier_t in_source_identifier, + ccs_ccache_t io_destination_ccache) +{ + cc_int32 err = ccNoError; + ccs_ccache_t source_ccache = NULL; + + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_source_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_find_ccache (io_cache_collection, + in_source_identifier, + &source_ccache); + } + + if (!err) { + err = ccs_ccache_swap_contents (source_ccache, io_destination_ccache); + } + + if (!err) { + err = ccs_cache_collection_destroy_ccache (io_cache_collection, + in_source_identifier); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_destroy_ccache (ccs_cache_collection_t io_cache_collection, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_remove (io_cache_collection->ccaches, + in_identifier); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_find_ccache_iterator (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + ccs_ccache_iterator_t *out_ccache_iterator) +{ + cc_int32 err = ccNoError; + + if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_find_iterator (in_cache_collection->ccaches, + in_identifier, + out_ccache_iterator); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_find_credentials_iterator (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + ccs_ccache_t *out_ccache, + ccs_credentials_iterator_t *out_credentials_iterator) +{ + cc_int32 err = ccNoError; + ccs_ccache_list_iterator_t iterator = NULL; + + if (!in_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, &iterator); + } + + while (!err) { + ccs_ccache_t ccache = NULL; + + err = ccs_ccache_list_iterator_next (iterator, &ccache); + + if (!err) { + cc_int32 terr = ccs_ccache_find_credentials_iterator (ccache, + in_identifier, + out_credentials_iterator); + if (!terr) { + *out_ccache = ccache; + break; + } + } + } + if (err == ccIteratorEnd) { err = cci_check_error (ccErrInvalidCredentialsIterator); } + + if (iterator) { ccs_ccache_list_iterator_release (iterator); } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_get_next_unique_ccache_name (ccs_cache_collection_t io_cache_collection, + char **out_name) +{ + cc_int32 err = ccNoError; + cc_uint64 count = 0; + char *name = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!out_name ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_list_count (io_cache_collection->ccaches, &count); + } + + if (!err) { + if (count > 0) { + while (!err) { + int ret = asprintf (&name, "%lld", io_cache_collection->next_unique_name++); + if (ret < 0 || !name) { err = cci_check_error (ccErrNoMem); } + + if (!err) { + ccs_ccache_t ccache = NULL; /* temporary to hold ccache pointer */ + err = ccs_cache_collection_find_ccache_by_name (io_cache_collection, + name, &ccache); + } + + if (err == ccErrCCacheNotFound) { + err = ccNoError; + break; /* found a unique one */ + } + } + } else { + name = strdup (k_cci_context_initial_ccache_name); + if (!name) { err = cci_check_error (ccErrNoMem); } + } + } + + if (!err) { + *out_name = name; + name = NULL; + } + + free (name); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_get_default_ccache (ccs_cache_collection_t in_cache_collection, + ccs_ccache_t *out_ccache) +{ + cc_int32 err = ccNoError; + cc_uint64 count = 0; + + if (!in_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_count (in_cache_collection->ccaches, &count); + } + + if (!err) { + if (count > 0) { + /* First ccache is the default */ + ccs_ccache_list_iterator_t iterator = NULL; + + err = ccs_ccache_list_new_iterator (in_cache_collection->ccaches, + &iterator); + + if (!err) { + err = ccs_ccache_list_iterator_next (iterator, out_ccache); + } + + ccs_ccache_list_iterator_release (iterator); + + } else { + err = cci_check_error (ccErrCCacheNotFound); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_cache_collection_set_default_ccache (ccs_cache_collection_t io_cache_collection, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + ccs_ccache_t old_default = NULL; + ccs_ccache_t new_default = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_get_default_ccache (io_cache_collection, + &old_default); + } + + if (!err) { + err = ccs_ccache_list_push_front (io_cache_collection->ccaches, + in_identifier); + } + + if (!err) { + err = ccs_ccache_notify_default_state_changed (old_default, + io_cache_collection, + FALSE /* no longer default */); + } + + if (!err) { + err = ccs_cache_collection_get_default_ccache (io_cache_collection, + &new_default); + } + + if (!err) { + err = ccs_ccache_notify_default_state_changed (new_default, + io_cache_collection, + TRUE /* now default */); + } + + if (!err) { + err = ccs_cache_collection_changed (io_cache_collection); + } + + return cci_check_error (err); +} + +#pragma mark - +#pragma mark -- IPC Messages -- + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_context_release (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* Currently does nothing */ + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_sync (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_write (io_cache_collection->identifier, io_reply_data); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_get_change_time (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_time (io_reply_data, io_cache_collection->last_changed_time); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_get_default_ccache_name (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint64 count = 0; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_list_count (io_cache_collection->ccaches, &count); + } + + if (!err) { + if (count > 0) { + ccs_ccache_t ccache = NULL; + + err = ccs_cache_collection_get_default_ccache (io_cache_collection, &ccache); + + if (!err) { + err = ccs_ccache_write_name (ccache, io_reply_data); + } + } else { + err = cci_stream_write_string (io_reply_data, + k_cci_context_initial_ccache_name); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_open_ccache (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + char *name = NULL; + ccs_ccache_t ccache = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_string (in_request_data, &name); + } + + if (!err) { + err = ccs_cache_collection_find_ccache_by_name (io_cache_collection, + name, &ccache); + } + + if (!err) { + err = ccs_ccache_write (ccache, io_reply_data); + } + + free (name); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_open_default_ccache (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_ccache_t ccache = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_get_default_ccache (io_cache_collection, + &ccache); + } + + if (!err) { + err = ccs_ccache_write (ccache, io_reply_data); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_create_ccache (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + char *name = NULL; + cc_uint32 cred_vers; + char *principal = NULL; + ccs_ccache_t ccache = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_string (in_request_data, &name); + } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &cred_vers); + } + + if (!err) { + err = cci_stream_read_string (in_request_data, &principal); + } + + if (!err) { + cc_int32 terr = ccs_cache_collection_find_ccache_by_name (io_cache_collection, + name, + &ccache); + + if (!terr) { + err = ccs_ccache_reset (ccache, cred_vers, principal); + + } else { + err = ccs_ccache_new (&ccache, cred_vers, name, principal, + io_cache_collection->ccaches); + } + } + + if (!err) { + err = ccs_ccache_write (ccache, io_reply_data); + } + + if (!err) { + err = ccs_cache_collection_changed (io_cache_collection); + } + + free (name); + free (principal); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_create_default_ccache (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 cred_vers; + char *principal = NULL; + ccs_ccache_t ccache = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &cred_vers); + } + + if (!err) { + err = cci_stream_read_string (in_request_data, &principal); + } + + if (!err) { + err = ccs_cache_collection_get_default_ccache (io_cache_collection, + &ccache); + + if (!err) { + err = ccs_ccache_reset (ccache, cred_vers, principal); + + } else if (err == ccErrCCacheNotFound) { + char *name = NULL; + + err = ccs_cache_collection_get_next_unique_ccache_name (io_cache_collection, + &name); + + if (!err) { + err = ccs_ccache_new (&ccache, cred_vers, name, principal, + io_cache_collection->ccaches); + } + + free (name); + } + } + + if (!err) { + err = ccs_ccache_write (ccache, io_reply_data); + } + + if (!err) { + err = ccs_cache_collection_changed (io_cache_collection); + } + + free (principal); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_create_new_ccache (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 cred_vers; + char *principal = NULL; + char *name = NULL; + ccs_ccache_t ccache = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &cred_vers); + } + + if (!err) { + err = cci_stream_read_string (in_request_data, &principal); + } + + if (!err) { + err = ccs_cache_collection_get_next_unique_ccache_name (io_cache_collection, + &name); + } + + if (!err) { + err = ccs_ccache_new (&ccache, cred_vers, name, principal, + io_cache_collection->ccaches); + } + + if (!err) { + err = ccs_ccache_write (ccache, io_reply_data); + } + + if (!err) { + err = ccs_cache_collection_changed (io_cache_collection); + } + + free (name); + free (principal); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_new_ccache_iterator (ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_ccache_iterator_t ccache_iterator = NULL; + + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_new_iterator (io_cache_collection->ccaches, + &ccache_iterator); + } + + if (!err) { + err = ccs_ccache_list_iterator_write (ccache_iterator, io_reply_data); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_lock (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cc_uint32 *out_will_block, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 lock_type; + cc_uint32 block; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &lock_type); + } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &block); + } + + if (!err) { + err = ccs_lock_state_add (io_cache_collection->lock_state, + in_client_pipe, in_reply_pipe, + lock_type, block, out_will_block); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_unlock (ccs_pipe_t in_client_pipe, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_lock_state_remove (io_cache_collection->lock_state, + in_client_pipe); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + + cc_int32 ccs_cache_collection_handle_message (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_cache_collection_t io_cache_collection, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cc_uint32 *out_will_block, + cci_stream_t *out_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 will_block = 0; + cci_stream_t reply_data = NULL; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&reply_data); + } + + if (!err) { + if (in_request_name == cci_context_release_msg_id) { + err = ccs_cache_collection_context_release (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_sync_msg_id) { + err = ccs_cache_collection_sync (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_get_change_time_msg_id) { + err = ccs_cache_collection_get_change_time (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_get_default_ccache_name_msg_id) { + err = ccs_cache_collection_get_default_ccache_name (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_open_ccache_msg_id) { + err = ccs_cache_collection_open_ccache (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_open_default_ccache_msg_id) { + err = ccs_cache_collection_open_default_ccache (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_create_ccache_msg_id) { + err = ccs_cache_collection_create_ccache (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_create_default_ccache_msg_id) { + err = ccs_cache_collection_create_default_ccache (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_create_new_ccache_msg_id) { + err = ccs_cache_collection_create_new_ccache (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_new_ccache_iterator_msg_id) { + err = ccs_cache_collection_new_ccache_iterator (io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_context_lock_msg_id) { + err = ccs_cache_collection_lock (in_client_pipe, in_reply_pipe, + io_cache_collection, + in_request_data, + &will_block, reply_data); + + } else if (in_request_name == cci_context_unlock_msg_id) { + err = ccs_cache_collection_unlock (in_client_pipe, io_cache_collection, + in_request_data, reply_data); + + } else { + err = ccErrBadInternalMessage; + } + } + + if (!err) { + *out_will_block = will_block; + *out_reply_data = reply_data; + reply_data = NULL; /* take ownership */ + } + + cci_stream_release (reply_data); + + return cci_check_error (err); +} diff --git a/src/ccapi/server/ccs_cache_collection.h b/src/ccapi/server/ccs_cache_collection.h new file mode 100644 index 000000000..4d663f992 --- /dev/null +++ b/src/ccapi/server/ccs_cache_collection.h @@ -0,0 +1,73 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_CACHE_COLLECTION_H +#define CCS_CACHE_COLLECTION_H + +#include "ccs_types.h" + +cc_int32 ccs_cache_collection_new (ccs_cache_collection_t *out_cache_collection); + +inline cc_int32 ccs_cache_collection_release (ccs_cache_collection_t io_cache_collection); + +inline cc_int32 ccs_cache_collection_compare_identifier (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + cc_uint32 *out_equal); + +cc_int32 ccs_cache_collection_changed (ccs_cache_collection_t io_cache_collection); + +cc_int32 ccs_cache_collection_set_default_ccache (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier); + +cc_int32 ccs_cache_collection_find_ccache (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + ccs_ccache_t *out_ccache); + +cc_int32 ccs_ccache_collection_move_ccache (ccs_cache_collection_t io_cache_collection, + cci_identifier_t in_source_identifier, + ccs_ccache_t io_destination_ccache); + +cc_int32 ccs_cache_collection_destroy_ccache (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier); + +cc_int32 ccs_cache_collection_find_ccache_iterator (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + ccs_ccache_iterator_t *out_ccache_iterator); + +cc_int32 ccs_cache_collection_find_credentials_iterator (ccs_cache_collection_t in_cache_collection, + cci_identifier_t in_identifier, + ccs_ccache_t *out_ccache, + ccs_credentials_iterator_t *out_credentials_iterator); + +cc_int32 ccs_cache_collection_handle_message (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_cache_collection_t io_cache_collection, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cc_uint32 *out_will_block, + cci_stream_t *out_reply_data); + +#endif /* CCS_CACHE_COLLECTION_H */ diff --git a/src/ccapi/server/ccs_ccache.c b/src/ccapi/server/ccs_ccache.c new file mode 100644 index 000000000..aaeed9796 --- /dev/null +++ b/src/ccapi/server/ccs_ccache.c @@ -0,0 +1,1002 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +struct ccs_ccache_d { + cci_identifier_t identifier; + ccs_lock_state_t lock_state; + cc_uint32 cred_vers; + char *name; + char *principal; + cc_time_t last_default_time; + cc_time_t last_changed_time; + cc_uint32 kdc_time_offset_v4_valid; + cc_time_t kdc_time_offset_v4; + cc_uint32 kdc_time_offset_v5_valid; + cc_time_t kdc_time_offset_v5; + ccs_credentials_list_t credentials; +}; + +struct ccs_ccache_d ccs_ccache_initializer = { NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_new (ccs_ccache_t *out_ccache, + cc_uint32 in_cred_vers, + const char *in_name, + const char *in_principal, + ccs_ccache_list_t io_ccache_list) +{ + cc_int32 err = ccNoError; + ccs_ccache_t ccache = NULL; + + if (!out_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_name ) { err = cci_check_error (ccErrBadParam); } + if (!in_principal) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + ccache = malloc (sizeof (*ccache)); + if (ccache) { + *ccache = ccs_ccache_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_server_new_identifier (&ccache->identifier); + } + + if (!err) { + err = ccs_lock_state_new (&ccache->lock_state, + ccErrInvalidCCache, + ccErrCCacheLocked, + ccErrCCacheUnlocked); + } + + if (!err) { + ccache->cred_vers = in_cred_vers; + + if (in_cred_vers != cc_credentials_v4 && + in_cred_vers != cc_credentials_v5) { + err = cci_check_error (ccErrBadCredentialsVersion); + } + } + + if (!err) { + ccache->name = strdup (in_name); + if (!ccache->name) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + ccache->principal = strdup (in_principal); + if (!ccache->principal) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + err = ccs_credentials_list_new (&ccache->credentials); + } + + if (!err) { + cc_uint64 now = time (NULL); + cc_uint64 count = 0; + + err = ccs_ccache_list_count (io_ccache_list, &count); + + if (!err) { + /* first cache is default */ + ccache->last_default_time = (count == 0) ? now : 0; + ccache->last_changed_time = now; + } + } + + if (!err) { + /* Add self to the list of ccaches */ + err = ccs_ccache_list_add (io_ccache_list, ccache); + } + + if (!err) { + *out_ccache = ccache; + ccache = NULL; + } + + ccs_ccache_release (ccache); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache, + cc_uint32 in_cred_vers, + const char *in_principal) +{ + cc_int32 err = ccNoError; + char *principal = NULL; + ccs_credentials_list_t credentials = NULL; + + if (!io_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (in_cred_vers != cc_credentials_v4 && + in_cred_vers != cc_credentials_v5) { + err = cci_check_error (ccErrBadCredentialsVersion); + } + } + + if (!err) { + principal = strdup (in_principal); + if (!io_ccache->principal) { err = cci_check_error (ccErrNoMem); } + } + + if (!err) { + err = ccs_credentials_list_new (&credentials); + } + + if (!err) { + io_ccache->cred_vers = in_cred_vers; + + free (io_ccache->principal); + io_ccache->principal = principal; + principal = NULL; /* take ownership */ + + ccs_credentials_list_release (io_ccache->credentials); + io_ccache->credentials = credentials; + credentials = NULL; /* take ownership */ + + } + + free (principal); + ccs_credentials_list_release (credentials); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache, + ccs_ccache_t io_destination_ccache) +{ + cc_int32 err = ccNoError; + + if (!io_source_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_destination_ccache) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + struct ccs_ccache_d temp_ccache = *io_destination_ccache; + + /* swap everything */ + *io_destination_ccache = *io_source_ccache; + *io_source_ccache = temp_ccache; + + /* swap back the name and identifier */ + io_source_ccache->identifier = io_destination_ccache->identifier; + io_destination_ccache->identifier = temp_ccache.identifier; + + io_source_ccache->name = io_destination_ccache->name; + io_destination_ccache->name = temp_ccache.name; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_release (ccs_ccache_t io_ccache) +{ + cc_int32 err = ccNoError; + + if (!io_ccache) { err = ccErrBadParam; } + + if (!err) { + cci_identifier_release (io_ccache->identifier); + ccs_lock_state_release (io_ccache->lock_state); + free (io_ccache->name); + free (io_ccache->principal); + ccs_credentials_list_release (io_ccache->credentials); + free (io_ccache); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_compare_identifier (ccs_ccache_t in_ccache, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier) { err = cci_check_error (ccErrBadParam); } + if (!out_equal ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_compare (in_ccache->identifier, + in_identifier, + out_equal); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_compare_name (ccs_ccache_t in_ccache, + const char *in_name, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (!in_ccache) { err = cci_check_error (ccErrBadParam); } + if (!in_name ) { err = cci_check_error (ccErrBadParam); } + if (!out_equal) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_equal = (strcmp (in_ccache->name, in_name) == 0); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_changed (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_time_t now = time (NULL); + + if (io_ccache->last_changed_time < now) { + io_ccache->last_changed_time = now; + } else { + io_ccache->last_changed_time++; + } + } + + if (!err) { + err = ccs_cache_collection_changed (io_cache_collection); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_notify_default_state_changed (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cc_uint32 in_new_default_state) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + + if (!err && in_new_default_state) { + cc_time_t now = time (NULL); + + if (io_ccache->last_default_time < now) { + io_ccache->last_default_time = now; + } else { + io_ccache->last_default_time++; + } + } + + if (!err) { + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_find_credentials_iterator (ccs_ccache_t in_ccache, + cci_identifier_t in_identifier, + ccs_credentials_iterator_t *out_credentials_iterator) +{ + cc_int32 err = ccNoError; + + if (!in_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_credentials_list_find_iterator (in_ccache->credentials, + in_identifier, + out_credentials_iterator); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_write (ccs_ccache_t in_ccache, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + + if (!in_ccache) { err = cci_check_error (ccErrBadParam); } + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_write (in_ccache->identifier, io_stream); + } + + return cci_check_error (err); +} + + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_write_name (ccs_ccache_t in_ccache, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + + if (!in_ccache) { err = cci_check_error (ccErrBadParam); } + if (!io_stream) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_string (io_stream, in_ccache->name); + } + + return cci_check_error (err); +} + +#pragma mark - +#pragma mark -- IPC Messages -- + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_destroy (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_destroy_ccache (io_cache_collection, + io_ccache->identifier); + } + + if (!err) { + /* ccache has been destroyed so just mark the cache collection */ + err = ccs_cache_collection_changed (io_cache_collection); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_set_default (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_cache_collection_set_default_ccache (io_cache_collection, + io_ccache->identifier); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_get_credentials_version (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_uint32 (io_reply_data, io_ccache->cred_vers); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_get_name (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_string (io_reply_data, io_ccache->name); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_get_principal (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_string (io_reply_data, io_ccache->principal); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_set_principal (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + char *principal = NULL; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_string (io_reply_data, &principal); + } + + if (!err) { + free (io_ccache->principal); + io_ccache->principal = principal; + principal = NULL; + + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_store_credentials (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_credentials_t credentials = NULL; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_credentials_new (&credentials, in_request_data, + io_ccache->credentials); + } + + if (!err) { + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_remove_credentials (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cci_identifier_t credentials_identifier = NULL; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_read (&credentials_identifier, in_request_data); + } + + if (!err) { + err = ccs_credentials_list_remove (io_ccache->credentials, credentials_identifier); + } + + if (!err) { + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + cci_identifier_release (credentials_identifier); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_new_credentials_iterator (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_credentials_iterator_t credentials_iterator = NULL; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_credentials_list_new_iterator (io_ccache->credentials, + &credentials_iterator); + } + + if (!err) { + err = ccs_credentials_list_iterator_write (credentials_iterator, io_reply_data); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_move (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cci_identifier_t source_identifier = NULL; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* Note: message is sent as the destination ccache to avoid */ + /* extra work on the server when deleting it the source ccache. */ + err = cci_identifier_read (&source_identifier, in_request_data); + } + + if (!err) { + err = ccs_ccache_collection_move_ccache (io_cache_collection, + source_identifier, + io_ccache); + } + + if (!err) { + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + cci_identifier_release (source_identifier); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_lock (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cc_uint32 *out_will_block, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 lock_type; + cc_uint32 block; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &lock_type); + } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &block); + } + + if (!err) { + err = ccs_lock_state_add (io_ccache->lock_state, + in_client_pipe, in_reply_pipe, + lock_type, block, out_will_block); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_unlock (ccs_pipe_t in_client_pipe, + ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_lock_state_remove (io_ccache->lock_state, in_client_pipe); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_get_last_default_time (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err && io_ccache->last_default_time == 0) { + err = cci_check_error (ccErrNeverDefault); + } + + if (!err) { + err = cci_stream_write_time (io_reply_data, io_ccache->last_default_time); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_get_change_time (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_write_time (io_reply_data, io_ccache->last_changed_time); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_get_kdc_time_offset (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 cred_vers = 0; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &cred_vers); + } + + if (!err) { + if (cred_vers == cc_credentials_v4) { + if (io_ccache->kdc_time_offset_v4_valid) { + err = cci_stream_write_time (io_reply_data, io_ccache->kdc_time_offset_v4); + } else { + err = cci_check_error (ccErrTimeOffsetNotSet); + } + + } else if (cred_vers == cc_credentials_v5) { + if (io_ccache->kdc_time_offset_v5_valid) { + err = cci_stream_write_time (io_reply_data, io_ccache->kdc_time_offset_v5); + } else { + err = cci_check_error (ccErrTimeOffsetNotSet); + } + + } else { + err = cci_check_error (ccErrBadCredentialsVersion); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_set_kdc_time_offset (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 cred_vers = 0; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &cred_vers); + } + + if (!err) { + if (cred_vers == cc_credentials_v4) { + err = cci_stream_read_time (in_request_data, &io_ccache->kdc_time_offset_v4); + + if (!err) { + io_ccache->kdc_time_offset_v4_valid = 1; + } + } else if (cred_vers == cc_credentials_v5) { + err = cci_stream_read_time (in_request_data, &io_ccache->kdc_time_offset_v5); + + if (!err) { + io_ccache->kdc_time_offset_v5_valid = 1; + } + } else { + err = cci_check_error (ccErrBadCredentialsVersion); + } + } + + if (!err) { + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_clear_kdc_time_offset (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 cred_vers = 0; + + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_read_uint32 (in_request_data, &cred_vers); + } + + if (!err) { + if (cred_vers == cc_credentials_v4) { + io_ccache->kdc_time_offset_v4 = 0; + io_ccache->kdc_time_offset_v4_valid = 0; + + } else if (cred_vers == cc_credentials_v5) { + io_ccache->kdc_time_offset_v5 = 0; + io_ccache->kdc_time_offset_v5_valid = 0; + + } else { + err = cci_check_error (ccErrBadCredentialsVersion); + } + } + + if (!err) { + err = ccs_ccache_changed (io_ccache, io_cache_collection); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_ccache_handle_message (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cc_uint32 *out_will_block, + cci_stream_t *out_reply_data) +{ + cc_int32 err = ccNoError; + cc_uint32 will_block = 0; + cci_stream_t reply_data = NULL; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&reply_data); + } + + if (!err) { + if (in_request_name == cci_ccache_destroy_msg_id) { + err = ccs_ccache_destroy (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_set_default_msg_id) { + err = ccs_ccache_set_default (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_get_credentials_version_msg_id) { + err = ccs_ccache_get_credentials_version (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_get_name_msg_id) { + err = ccs_ccache_get_name (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_get_principal_msg_id) { + err = ccs_ccache_get_principal (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_set_principal_msg_id) { + err = ccs_ccache_set_principal (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_store_credentials_msg_id) { + err = ccs_ccache_store_credentials (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_remove_credentials_msg_id) { + err = ccs_ccache_remove_credentials (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_new_credentials_iterator_msg_id) { + err = ccs_ccache_new_credentials_iterator (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_move_msg_id) { + err = ccs_ccache_move (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_lock_msg_id) { + err = ccs_ccache_lock (in_client_pipe, in_reply_pipe, + io_ccache, io_cache_collection, + in_request_data, + &will_block, reply_data); + + } else if (in_request_name == cci_ccache_unlock_msg_id) { + err = ccs_ccache_unlock (in_client_pipe, + io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_get_last_default_time_msg_id) { + err = ccs_ccache_get_last_default_time (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_get_change_time_msg_id) { + err = ccs_ccache_get_change_time (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_get_kdc_time_offset_msg_id) { + err = ccs_ccache_get_kdc_time_offset (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_set_kdc_time_offset_msg_id) { + err = ccs_ccache_set_kdc_time_offset (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else if (in_request_name == cci_ccache_clear_kdc_time_offset_msg_id) { + err = ccs_ccache_clear_kdc_time_offset (io_ccache, io_cache_collection, + in_request_data, reply_data); + + } else { + err = ccErrBadInternalMessage; + } + } + + if (!err) { + *out_will_block = will_block; + *out_reply_data = reply_data; + reply_data = NULL; /* take ownership */ + } + + cci_stream_release (reply_data); + + return cci_check_error (err); +} + diff --git a/src/ccapi/server/ccs_ccache.h b/src/ccapi/server/ccs_ccache.h new file mode 100644 index 000000000..837c6b457 --- /dev/null +++ b/src/ccapi/server/ccs_ccache.h @@ -0,0 +1,78 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_CCACHE_H +#define CCS_CCACHE_H + +#include "ccs_types.h" + +cc_int32 ccs_ccache_new (ccs_ccache_t *out_ccache, + cc_uint32 in_cred_vers, + const char *in_name, + const char *in_principal, + ccs_ccache_list_t io_ccache_list); + +cc_int32 ccs_ccache_reset (ccs_ccache_t io_ccache, + cc_uint32 in_cred_vers, + const char *in_principal); + +cc_int32 ccs_ccache_swap_contents (ccs_ccache_t io_source_ccache, + ccs_ccache_t io_destination_ccache); + +inline cc_int32 ccs_ccache_release (ccs_ccache_t io_ccache); + +inline cc_int32 ccs_ccache_compare_identifier (ccs_ccache_t in_ccache, + cci_identifier_t in_identifier, + cc_uint32 *out_equal); + +cc_int32 ccs_ccache_compare_name (ccs_ccache_t in_ccache, + const char *in_name, + cc_uint32 *out_equal); + +cc_int32 ccs_ccache_notify_default_state_changed (ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + cc_uint32 in_new_default_state); + +cc_int32 ccs_ccache_find_credentials_iterator (ccs_ccache_t in_ccache, + cci_identifier_t in_identifier, + ccs_credentials_iterator_t *out_credentials_iterator); + +cc_int32 ccs_ccache_write (ccs_ccache_t in_ccache, + cci_stream_t io_stream); + +cc_int32 ccs_ccache_write_name (ccs_ccache_t in_ccache, + cci_stream_t io_stream); + +cc_int32 ccs_ccache_handle_message (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_ccache_t io_ccache, + ccs_cache_collection_t io_cache_collection, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cc_uint32 *out_will_block, + cci_stream_t *out_reply_data); + +#endif /* CCS_CCACHE_H */ diff --git a/src/ccapi/server/ccs_ccache_iterator.c b/src/ccapi/server/ccs_ccache_iterator.c new file mode 100644 index 000000000..77d83f1b0 --- /dev/null +++ b/src/ccapi/server/ccs_ccache_iterator.c @@ -0,0 +1,156 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_iterator_release (ccs_ccache_iterator_t io_ccache_iterator, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_ccache_iterator ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_iterator_release (io_ccache_iterator); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_iterator_next (ccs_ccache_iterator_t io_ccache_iterator, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_ccache_t ccache = NULL; + + if (!io_ccache_iterator ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_iterator_next (io_ccache_iterator, &ccache); + } + + if (!err) { + err = ccs_ccache_write (ccache, io_reply_data); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_iterator_clone (ccs_ccache_iterator_t io_ccache_iterator, + ccs_cache_collection_t io_cache_collection, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_ccache_iterator_t ccache_iterator = NULL; + + if (!io_ccache_iterator ) { err = cci_check_error (ccErrBadParam); } + if (!io_cache_collection) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_ccache_list_iterator_clone (io_ccache_iterator, + &ccache_iterator); + } + + if (!err) { + err = ccs_ccache_list_iterator_write (ccache_iterator, io_reply_data); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + + cc_int32 ccs_ccache_iterator_handle_message (ccs_ccache_iterator_t io_ccache_iterator, + ccs_cache_collection_t io_cache_collection, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cci_stream_t *out_reply_data) +{ + cc_int32 err = ccNoError; + cci_stream_t reply_data = NULL; + + if (!in_request_data) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&reply_data); + } + + if (!err) { + if (in_request_name == cci_ccache_iterator_release_msg_id) { + err = ccs_ccache_iterator_release (io_ccache_iterator, + io_cache_collection, + in_request_data, + reply_data); + + } else if (in_request_name == cci_ccache_iterator_next_msg_id) { + err = ccs_ccache_iterator_next (io_ccache_iterator, + io_cache_collection, + in_request_data, + reply_data); + + } else if (in_request_name == cci_ccache_iterator_clone_msg_id) { + err = ccs_ccache_iterator_clone (io_ccache_iterator, + io_cache_collection, + in_request_data, + reply_data); + + } else { + err = ccErrBadInternalMessage; + } + } + + if (!err) { + *out_reply_data = reply_data; + reply_data = NULL; /* take ownership */ + } + + cci_stream_release (reply_data); + + return cci_check_error (err); +} + diff --git a/src/ccapi/server/ccs_ccache_iterator.h b/src/ccapi/server/ccs_ccache_iterator.h new file mode 100644 index 000000000..8ec361a67 --- /dev/null +++ b/src/ccapi/server/ccs_ccache_iterator.h @@ -0,0 +1,38 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_CCACHE_ITERATOR_H +#define CCS_CCACHE_ITERATOR_H + +#include "ccs_types.h" + + cc_int32 ccs_ccache_iterator_handle_message (ccs_ccache_iterator_t io_ccache_iterator, + ccs_cache_collection_t io_cache_collection, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cci_stream_t *out_reply_data); + +#endif /* CCS_CCACHE_ITERATOR_H */ diff --git a/src/ccapi/server/ccs_common.h b/src/ccapi/server/ccs_common.h new file mode 100644 index 000000000..f035780da --- /dev/null +++ b/src/ccapi/server/ccs_common.h @@ -0,0 +1,44 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_COMMON_H +#define CCS_COMMON_H + +#include "cci_common.h" + +#include "ccs_array.h" +#include "ccs_list.h" +#include "ccs_cache_collection.h" +#include "ccs_ccache_iterator.h" +#include "ccs_ccache.h" +#include "ccs_credentials_iterator.h" +#include "ccs_credentials.h" +#include "ccs_lock.h" +#include "ccs_lock_state.h" +#include "ccs_pipe.h" +#include "ccs_server.h" + +#endif /* CCS_COMMON_H */ diff --git a/src/ccapi/server/ccs_credentials.c b/src/ccapi/server/ccs_credentials.c new file mode 100644 index 000000000..7cb6483f0 --- /dev/null +++ b/src/ccapi/server/ccs_credentials.c @@ -0,0 +1,136 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +struct ccs_credentials_d { + cc_credentials_union *cred_union; + cci_identifier_t identifier; +}; + +struct ccs_credentials_d ccs_credentials_initializer = { NULL, NULL }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_credentials_new (ccs_credentials_t *out_credentials, + cci_stream_t in_stream, + ccs_credentials_list_t io_credentials_list) +{ + cc_int32 err = ccNoError; + ccs_credentials_t credentials = NULL; + + if (!out_credentials) { err = cci_check_error (ccErrBadParam); } + if (!in_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + credentials = malloc (sizeof (*credentials)); + if (credentials) { + *credentials = ccs_credentials_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = cci_cred_union_read (&credentials->cred_union, in_stream); + } + + if (!err) { + err = ccs_server_new_identifier (&credentials->identifier); + } + + if (!err) { + err = ccs_credentials_list_add (io_credentials_list, credentials); + } + + if (!err) { + *out_credentials = credentials; + credentials = NULL; + } + + ccs_credentials_release (credentials); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_release (ccs_credentials_t io_credentials) +{ + cc_int32 err = ccNoError; + + if (!io_credentials) { err = ccErrBadParam; } + + if (!err) { + cci_cred_union_release (io_credentials->cred_union); + cci_identifier_release (io_credentials->identifier); + free (io_credentials); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_credentials_write (ccs_credentials_t in_credentials, + cci_stream_t io_stream) +{ + cc_int32 err = ccNoError; + + if (!in_credentials) { err = cci_check_error (ccErrBadParam); } + if (!io_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_write (in_credentials->identifier, io_stream); + } + + if (!err) { + err = cci_cred_union_write (in_credentials->cred_union, io_stream); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_compare_identifier (ccs_credentials_t in_credentials, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (!in_credentials) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_equal ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_compare (in_credentials->identifier, + in_identifier, + out_equal); + } + + return cci_check_error (err); +} diff --git a/src/ccapi/server/ccs_credentials.h b/src/ccapi/server/ccs_credentials.h new file mode 100644 index 000000000..e4dbb69f5 --- /dev/null +++ b/src/ccapi/server/ccs_credentials.h @@ -0,0 +1,46 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_CREDENTIALS_H +#define CCS_CREDENTIALS_H + +#include "ccs_types.h" + + +cc_int32 ccs_credentials_new (ccs_credentials_t *out_credentials, + cci_stream_t in_stream, + ccs_credentials_list_t io_credentials_list); + +inline cc_int32 ccs_credentials_release (ccs_credentials_t io_credentials); + +cc_int32 ccs_credentials_write (ccs_credentials_t in_credentials, + cci_stream_t io_stream); + +inline cc_int32 ccs_credentials_compare_identifier (ccs_credentials_t in_credentials, + cci_identifier_t in_identifier, + cc_uint32 *out_equal); + +#endif /* CCS_CREDENTIALS_H */ diff --git a/src/ccapi/server/ccs_credentials_iterator.c b/src/ccapi/server/ccs_credentials_iterator.c new file mode 100644 index 000000000..f95dc4842 --- /dev/null +++ b/src/ccapi/server/ccs_credentials_iterator.c @@ -0,0 +1,158 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_credentials_iterator_release (ccs_credentials_iterator_t io_credentials_iterator, + ccs_ccache_t io_ccache, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + + if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_credentials_list_iterator_release (io_credentials_iterator); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_credentials_iterator_next (ccs_credentials_iterator_t io_credentials_iterator, + ccs_ccache_t io_ccache, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_credentials_t credentials = NULL; + + if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_credentials_list_iterator_next (io_credentials_iterator, + &credentials); + } + + if (!err) { + err = ccs_credentials_write (credentials, io_reply_data); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_credentials_iterator_clone (ccs_credentials_iterator_t io_credentials_iterator, + ccs_ccache_t io_ccache, + cci_stream_t in_request_data, + cci_stream_t io_reply_data) +{ + cc_int32 err = ccNoError; + ccs_credentials_iterator_t credentials_iterator = NULL; + + if (!io_credentials_iterator) { err = cci_check_error (ccErrBadParam); } + if (!io_ccache ) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!io_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_credentials_list_iterator_clone (io_credentials_iterator, + &credentials_iterator); + } + + if (!err) { + err = ccs_credentials_list_iterator_write (credentials_iterator, + io_reply_data); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + + cc_int32 ccs_credentials_iterator_handle_message (ccs_credentials_iterator_t io_credentials_iterator, + ccs_ccache_t io_ccache, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cci_stream_t *out_reply_data) +{ + cc_int32 err = ccNoError; + cci_stream_t reply_data = NULL; + + if (!in_request_data) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_stream_new (&reply_data); + } + + if (!err) { + if (in_request_name == cci_credentials_iterator_release_msg_id) { + err = ccs_credentials_iterator_release (io_credentials_iterator, + io_ccache, + in_request_data, + reply_data); + + } else if (in_request_name == cci_credentials_iterator_next_msg_id) { + err = ccs_credentials_iterator_next (io_credentials_iterator, + io_ccache, + in_request_data, + reply_data); + + } else if (in_request_name == cci_credentials_iterator_clone_msg_id) { + err = ccs_credentials_iterator_clone (io_credentials_iterator, + io_ccache, + in_request_data, + reply_data); + + } else { + err = ccErrBadInternalMessage; + } + } + + if (!err) { + *out_reply_data = reply_data; + reply_data = NULL; /* take ownership */ + } + + cci_stream_release (reply_data); + + return cci_check_error (err); +} + diff --git a/src/ccapi/server/ccs_credentials_iterator.h b/src/ccapi/server/ccs_credentials_iterator.h new file mode 100644 index 000000000..af3cf1a18 --- /dev/null +++ b/src/ccapi/server/ccs_credentials_iterator.h @@ -0,0 +1,38 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_CREDENTIALS_ITERATOR_H +#define CCS_CREDENTIALS_ITERATOR_H + +#include "ccs_types.h" + + cc_int32 ccs_credentials_iterator_handle_message (ccs_credentials_iterator_t io_credentials_iterator, + ccs_ccache_t io_ccache, + enum cci_msg_id_t in_request_name, + cci_stream_t in_request_data, + cci_stream_t *out_reply_data); + +#endif /* CCS_CREDENTIALS_ITERATOR_H */ diff --git a/src/ccapi/server/ccs_list.c b/src/ccapi/server/ccs_list.c new file mode 100644 index 000000000..17355c08f --- /dev/null +++ b/src/ccapi/server/ccs_list.c @@ -0,0 +1,345 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" +#include "ccs_list_internal.h" + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_list_object_release (void *io_object) +{ + return cci_check_error (ccs_cache_collection_release ((ccs_cache_collection_t) io_object)); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_cache_collection_list_object_compare_identifier (void *in_cache_collection, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) +{ + return ccs_cache_collection_compare_identifier ((ccs_cache_collection_t) in_cache_collection, + in_identifier, + out_equal); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_list_new (ccs_cache_collection_list_t *out_list) +{ + return ccs_list_new (out_list, + ccErrInvalidContext, + ccErrInvalidContext, + ccs_cache_collection_list_object_compare_identifier, + ccs_cache_collection_list_object_release); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_list_count (ccs_cache_collection_list_t in_list, + cc_uint64 *out_count) +{ + return ccs_list_count (in_list, out_count); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_list_find (ccs_cache_collection_list_t in_list, + cci_identifier_t in_identifier, + ccs_cache_collection_t *out_cache_collection) +{ + return ccs_list_find (in_list, in_identifier, (ccs_object_t *) out_cache_collection); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_list_add (ccs_cache_collection_list_t io_list, + ccs_cache_collection_t in_cache_collection) +{ + return ccs_list_add (io_list, in_cache_collection); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_list_remove (ccs_cache_collection_list_t io_list, + cci_identifier_t in_identifier) +{ + return ccs_list_remove (io_list, in_identifier); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_cache_collection_list_release (ccs_cache_collection_list_t io_list) +{ + return ccs_list_release (io_list); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_list_object_release (void *io_ccache) +{ + return cci_check_error (ccs_ccache_release ((ccs_ccache_t) io_ccache)); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_ccache_list_object_compare_identifier (void *in_ccache, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) +{ + return ccs_ccache_compare_identifier ((ccs_ccache_t) in_ccache, + in_identifier, + out_equal); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_new (ccs_ccache_list_t *out_list) +{ + return ccs_list_new (out_list, + ccErrInvalidCCache, + ccErrInvalidCCacheIterator, + ccs_ccache_list_object_compare_identifier, + ccs_ccache_list_object_release); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_new_iterator (ccs_ccache_list_t in_list, + ccs_ccache_list_iterator_t *out_list_iterator) +{ + return ccs_list_new_iterator (in_list, out_list_iterator); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_count (ccs_ccache_list_t in_list, + cc_uint64 *out_count) +{ + return ccs_list_count (in_list, out_count); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_find (ccs_ccache_list_t in_list, + cci_identifier_t in_identifier, + ccs_ccache_t *out_ccache) +{ + return ccs_list_find (in_list, in_identifier, (ccs_object_t *) out_ccache); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_find_iterator (ccs_ccache_list_t in_list, + cci_identifier_t in_identifier, + ccs_ccache_list_iterator_t *out_list_iterator) +{ + return ccs_list_find_iterator (in_list, in_identifier, + (ccs_list_iterator_t *) out_list_iterator); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_add (ccs_ccache_list_t io_list, + ccs_ccache_t in_ccache) +{ + return ccs_list_add (io_list, in_ccache); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_remove (ccs_ccache_list_t io_list, + cci_identifier_t in_identifier) +{ + return ccs_list_remove (io_list, in_identifier); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_push_front (ccs_ccache_list_t io_list, + cci_identifier_t in_identifier) +{ + return ccs_list_push_front (io_list, in_identifier); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_release (ccs_ccache_list_t io_list) +{ + return ccs_list_release (io_list); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_iterator_write (ccs_ccache_list_iterator_t in_list_iterator, + cci_stream_t in_stream) +{ + return ccs_list_iterator_write (in_list_iterator, in_stream); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_iterator_clone (ccs_ccache_list_iterator_t in_list_iterator, + ccs_ccache_list_iterator_t *out_list_iterator) +{ + return ccs_list_iterator_clone (in_list_iterator, out_list_iterator); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_iterator_next (ccs_ccache_list_iterator_t io_list_iterator, + ccs_ccache_t *out_ccache) +{ + return ccs_list_iterator_next (io_list_iterator, (ccs_object_t *) out_ccache); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_ccache_list_iterator_release (ccs_ccache_list_iterator_t io_list_iterator) +{ + return ccs_list_iterator_release (io_list_iterator); +} + +#pragma mark- + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_credentials_list_object_release (void *io_object) +{ + return cci_check_error (ccs_credentials_release ((ccs_credentials_t) io_object)); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_credentials_list_object_compare_identifier (void *in_credentials, + cci_identifier_t in_identifier, + cc_uint32 *out_equal) +{ + return ccs_credentials_compare_identifier ((ccs_credentials_t) in_credentials, + in_identifier, + out_equal); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_new (ccs_credentials_list_t *out_list) +{ + return ccs_list_new (out_list, + ccErrInvalidCredentials, + ccErrInvalidCredentialsIterator, + ccs_credentials_list_object_compare_identifier, + ccs_credentials_list_object_release); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_new_iterator (ccs_credentials_list_t in_list, + ccs_credentials_list_iterator_t *out_list_iterator) +{ + return ccs_list_new_iterator (in_list, out_list_iterator); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_count (ccs_credentials_list_t in_list, + cc_uint64 *out_count) +{ + return ccs_list_count (in_list, out_count); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_find (ccs_credentials_list_t in_list, + cci_identifier_t in_identifier, + ccs_credentials_t *out_credentials) +{ + return ccs_list_find (in_list, in_identifier, (ccs_object_t *) out_credentials); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_find_iterator (ccs_credentials_list_t in_list, + cci_identifier_t in_identifier, + ccs_credentials_list_iterator_t *out_list_iterator) +{ + return ccs_list_find_iterator (in_list, in_identifier, + (ccs_list_iterator_t *) out_list_iterator); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_add (ccs_credentials_list_t io_list, + ccs_credentials_t in_credential) +{ + return ccs_list_add (io_list, in_credential); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_remove (ccs_credentials_list_t io_list, + cci_identifier_t in_identifier) +{ + return ccs_list_remove (io_list, in_identifier); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_release (ccs_credentials_list_t io_list) +{ + return ccs_list_release (io_list); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_iterator_write (ccs_credentials_list_iterator_t in_list_iterator, + cci_stream_t in_stream) +{ + return ccs_list_iterator_write (in_list_iterator, in_stream); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_iterator_clone (ccs_credentials_list_iterator_t in_list_iterator, + ccs_credentials_list_iterator_t *out_list_iterator) +{ + return ccs_list_iterator_clone (in_list_iterator, out_list_iterator); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_iterator_next (ccs_credentials_list_iterator_t io_list_iterator, + ccs_credentials_t *out_credential) +{ + return ccs_list_iterator_next (io_list_iterator, (ccs_object_t *) out_credential); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_credentials_list_iterator_release (ccs_credentials_list_iterator_t io_list_iterator) +{ + return ccs_list_iterator_release (io_list_iterator); +} diff --git a/src/ccapi/server/ccs_list.h b/src/ccapi/server/ccs_list.h new file mode 100644 index 000000000..435821a5b --- /dev/null +++ b/src/ccapi/server/ccs_list.h @@ -0,0 +1,129 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_LIST_H +#define CCS_LIST_H + + +#include "ccs_types.h" + +cc_int32 ccs_cache_collection_list_new (ccs_cache_collection_list_t *out_list); + +cc_int32 ccs_cache_collection_list_count (ccs_cache_collection_list_t in_list, + cc_uint64 *out_count); + +cc_int32 ccs_cache_collection_list_find (ccs_cache_collection_list_t in_list, + cci_identifier_t in_identifier, + ccs_cache_collection_t *out_cache_collection); + +cc_int32 ccs_cache_collection_list_add (ccs_cache_collection_list_t io_list, + ccs_cache_collection_t in_cache_collection); + +cc_int32 ccs_cache_collection_list_remove (ccs_cache_collection_list_t io_list, + cci_identifier_t in_identifier); + +cc_int32 ccs_cache_collection_list_release (ccs_cache_collection_list_t io_list); + +#pragma mark - + +cc_int32 ccs_ccache_list_new (ccs_ccache_list_t *out_list); + +cc_int32 ccs_ccache_list_new_iterator (ccs_ccache_list_t in_list, + ccs_ccache_list_iterator_t *out_list_iterator); + +cc_int32 ccs_ccache_list_count (ccs_ccache_list_t in_list, + cc_uint64 *out_count); + +cc_int32 ccs_ccache_list_find (ccs_ccache_list_t in_list, + cci_identifier_t in_identifier, + ccs_ccache_t *out_ccache); + +cc_int32 ccs_ccache_list_find_iterator (ccs_ccache_list_t in_list, + cci_identifier_t in_identifier, + ccs_ccache_list_iterator_t *out_list_iterator); + +cc_int32 ccs_ccache_list_add (ccs_ccache_list_t io_list, + ccs_ccache_t in_ccache); + +cc_int32 ccs_ccache_list_remove (ccs_ccache_list_t io_list, + cci_identifier_t in_identifier); + +cc_int32 ccs_ccache_list_push_front (ccs_ccache_list_t io_list, + cci_identifier_t in_identifier); + +cc_int32 ccs_ccache_list_release (ccs_ccache_list_t io_list); + + +cc_int32 ccs_ccache_list_iterator_write (ccs_ccache_list_iterator_t in_list_iterator, + cci_stream_t in_stream); + +cc_int32 ccs_ccache_list_iterator_clone (ccs_ccache_list_iterator_t in_list_iterator, + ccs_ccache_list_iterator_t *out_list_iterator); + +cc_int32 ccs_ccache_list_iterator_next (ccs_ccache_list_iterator_t io_list_iterator, + ccs_ccache_t *out_ccache); + +cc_int32 ccs_ccache_list_iterator_release (ccs_ccache_list_iterator_t io_list_iterator); + +#pragma mark - + +cc_int32 ccs_credentials_list_new (ccs_credentials_list_t *out_list); + +cc_int32 ccs_credentials_list_new_iterator (ccs_credentials_list_t in_list, + ccs_credentials_list_iterator_t *out_list_iterator); + +cc_int32 ccs_credentials_list_count (ccs_credentials_list_t in_list, + cc_uint64 *out_count); + +cc_int32 ccs_credentials_list_find (ccs_credentials_list_t in_list, + cci_identifier_t in_identifier, + ccs_credentials_t *out_credentials); + +cc_int32 ccs_credentials_list_find_iterator (ccs_credentials_list_t in_list, + cci_identifier_t in_identifier, + ccs_credentials_list_iterator_t *out_list_iterator); + +cc_int32 ccs_credentials_list_add (ccs_credentials_list_t io_list, + ccs_credentials_t in_credential); + +cc_int32 ccs_credentials_list_remove (ccs_credentials_list_t io_list, + cci_identifier_t in_identifier); + +cc_int32 ccs_credentials_list_release (ccs_credentials_list_t io_list); + + +cc_int32 ccs_credentials_list_iterator_write (ccs_credentials_list_iterator_t in_list_iterator, + cci_stream_t in_stream); + +cc_int32 ccs_credentials_list_iterator_clone (ccs_credentials_list_iterator_t in_list_iterator, + ccs_credentials_list_iterator_t *out_list_iterator); + +cc_int32 ccs_credentials_list_iterator_next (ccs_credentials_list_iterator_t io_list_iterator, + ccs_credentials_t *out_credential); + +cc_int32 ccs_credentials_list_iterator_release (ccs_credentials_list_iterator_t io_list_iterator); + +#endif /* CCS_LIST_H */ diff --git a/src/ccapi/server/ccs_list_internal.c b/src/ccapi/server/ccs_list_internal.c new file mode 100644 index 000000000..a930fba33 --- /dev/null +++ b/src/ccapi/server/ccs_list_internal.c @@ -0,0 +1,612 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_list_internal.h" +#include "cci_array_internal.h" +#include "cci_identifier.h" +#include "ccs_server.h" + +typedef enum { + ccs_list_action_insert, + ccs_list_action_remove, + ccs_list_action_push_front +} ccs_list_action_enum; + +/* ------------------------------------------------------------------------ */ + +struct ccs_list_d { + cci_array_t objects; + cci_array_t iterators; + + cc_int32 object_not_found_err; + cc_int32 iterator_not_found_err; + + ccs_object_compare_identifier_t object_compare_identifier; +}; + +struct ccs_list_d ccs_list_initializer = { NULL, NULL, -1, -1, NULL }; + +/* ------------------------------------------------------------------------ */ + +struct ccs_list_iterator_d { + cci_identifier_t identifier; + ccs_list_t list; + cc_uint64 current; +}; + +struct ccs_list_iterator_d ccs_list_iterator_initializer = { NULL, NULL, 0 }; + +static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator, + ccs_list_t in_list); + +static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_iterator); + +static cc_int32 ccs_list_iterator_update (ccs_list_iterator_t io_list_iterator, + ccs_list_action_enum in_action, + cc_uint64 in_object_index); +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_new (ccs_list_t *out_list, + cc_int32 in_object_not_found_err, + cc_int32 in_iterator_not_found_err, + ccs_object_compare_identifier_t in_object_compare_identifier, + ccs_object_release_t in_object_release) +{ + cc_int32 err = ccNoError; + ccs_list_t list = NULL; + + if (!out_list) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + list = malloc (sizeof (*list)); + if (list) { + *list = ccs_list_initializer; + list->object_not_found_err = in_object_not_found_err; + list->iterator_not_found_err = in_iterator_not_found_err; + list->object_compare_identifier = in_object_compare_identifier; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = cci_array_new (&list->objects, in_object_release); + } + + if (!err) { + err = cci_array_new (&list->iterators, ccs_list_iterator_object_release); + } + + if (!err) { + *out_list = list; + list = NULL; + } + + ccs_list_release (list); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_release (ccs_list_t io_list) +{ + cc_int32 err = ccNoError; + + if (!io_list) { err = ccErrBadParam; } + + if (!err) { + cc_uint64 i; + + for (i = 0; i < cci_array_count (io_list->iterators); i++) { + ccs_list_iterator_release (cci_array_object_at_index (io_list->iterators, i)); + } + free (io_list->iterators); + cci_array_release (io_list->objects); + free (io_list); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_new_iterator (ccs_list_t io_list, + ccs_list_iterator_t *out_list_iterator) +{ + return cci_check_error (ccs_list_iterator_new (out_list_iterator, io_list)); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_release_iterator (ccs_list_t io_list, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + ccs_list_iterator_t iterator = NULL; + + if (!io_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_list_find_iterator (io_list, in_identifier, &iterator); + } + + if (!err) { + err = ccs_list_iterator_release (iterator); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_count (ccs_list_t in_list, + cc_uint64 *out_count) +{ + cc_int32 err = ccNoError; + + if (!in_list ) { err = cci_check_error (ccErrBadParam); } + if (!out_count) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_count = cci_array_count (in_list->objects); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_list_find_index (ccs_list_t in_list, + cci_identifier_t in_identifier, + cc_uint64 *out_object_index) +{ + cc_int32 err = ccNoError; + cc_int32 found = 0; + + if (!in_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_object_index) { err = cci_check_error (ccErrBadParam); } + + if (!err && !found) { + cc_uint64 i; + + for (i = 0; !err && i < cci_array_count (in_list->objects); i++) { + cc_uint32 equal = 0; + cci_array_object_t object = cci_array_object_at_index (in_list->objects, i); + + err = in_list->object_compare_identifier (object, in_identifier, &equal); + + if (!err && equal) { + found = 1; + *out_object_index = i; + } + } + } + + if (!err && !found) { + err = cci_check_error (in_list->object_not_found_err); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ +cc_int32 ccs_list_find (ccs_list_t in_list, + cci_identifier_t in_identifier, + ccs_object_t *out_object) +{ + cc_int32 err = ccNoError; + cc_uint64 i; + + if (!in_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier) { err = cci_check_error (ccErrBadParam); } + if (!out_object ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_list_find_index (in_list, in_identifier, &i); + } + + if (!err) { + *out_object = cci_array_object_at_index (in_list->objects, i); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_list_find_iterator_index (ccs_list_t in_list, + cci_identifier_t in_identifier, + cc_uint64 *out_object_index) +{ + cc_int32 err = ccNoError; + cc_int32 found = 0; + + if (!in_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_object_index) { err = cci_check_error (ccErrBadParam); } + + if (!err && !found) { + cc_uint64 i; + + for (i = 0; !err && i < cci_array_count (in_list->iterators); i++) { + cc_uint32 equal = 0; + ccs_list_iterator_t iterator = cci_array_object_at_index (in_list->iterators, i); + + err = cci_identifier_compare (iterator->identifier, in_identifier, &equal); + + if (!err && equal) { + found = 1; + *out_object_index = i; + } + } + } + + if (!err && !found) { + err = cci_check_error (in_list->object_not_found_err); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_find_iterator (ccs_list_t in_list, + cci_identifier_t in_identifier, + ccs_list_iterator_t *out_list_iterator) +{ + cc_int32 err = ccNoError; + cc_uint64 i; + + if (!in_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } + if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_list_find_iterator_index (in_list, in_identifier, &i); + } + + if (!err) { + *out_list_iterator = cci_array_object_at_index (in_list->iterators, i); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_add (ccs_list_t io_list, + ccs_object_t in_object) +{ + cc_int32 err = ccNoError; + cc_uint64 add_index; + + if (!io_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_object) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + add_index = cci_array_count (io_list->objects); + + err = cci_array_insert (io_list->objects, in_object, add_index); + } + + if (!err) { + /* Fixup iterator indexes */ + cc_uint64 i; + + for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) { + ccs_list_iterator_t iterator = cci_array_object_at_index (io_list->iterators, i); + + err = ccs_list_iterator_update (iterator, ccs_list_action_insert, add_index); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_remove (ccs_list_t io_list, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + cc_uint64 remove_index; + + if (!io_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_list_find_index (io_list, in_identifier, &remove_index); + } + + if (!err) { + err = cci_array_remove (io_list->objects, remove_index); + } + + if (!err) { + /* Fixup iterator indexes */ + cc_uint64 i; + + for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) { + ccs_list_iterator_t iterator = cci_array_object_at_index (io_list->iterators, i); + + err = ccs_list_iterator_update (iterator, ccs_list_action_remove, remove_index); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_push_front (ccs_list_t io_list, + cci_identifier_t in_identifier) +{ + cc_int32 err = ccNoError; + cc_uint64 push_front_index; + + if (!io_list ) { err = cci_check_error (ccErrBadParam); } + if (!in_identifier) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_list_find_index (io_list, in_identifier, &push_front_index); + } + + if (!err) { + err = cci_array_push_front (io_list->objects, push_front_index); + } + + if (!err) { + /* Fixup iterator indexes */ + cc_uint64 i; + + for (i = 0; !err && i < cci_array_count (io_list->iterators); i++) { + ccs_list_iterator_t iterator = cci_array_object_at_index (io_list->iterators, i); + + err = ccs_list_iterator_update (iterator, + ccs_list_action_push_front, + push_front_index); + } + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_list_iterator_new (ccs_list_iterator_t *out_list_iterator, + ccs_list_t io_list) +{ + cc_int32 err = ccNoError; + ccs_list_iterator_t list_iterator = NULL; + + if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); } + if (!io_list ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + list_iterator = malloc (sizeof (*list_iterator)); + if (list_iterator) { + *list_iterator = ccs_list_iterator_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_server_new_identifier (&list_iterator->identifier); + } + + if (!err) { + list_iterator->list = io_list; + list_iterator->current = 0; + + err = cci_array_insert (io_list->iterators, + list_iterator, cci_array_count (io_list->iterators)); + } + + if (!err) { + *out_list_iterator = list_iterator; + list_iterator = NULL; + } + + ccs_list_iterator_release (list_iterator); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_iterator_write (ccs_list_iterator_t in_list_iterator, + cci_stream_t in_stream) +{ + cc_int32 err = ccNoError; + + if (!in_list_iterator) { err = cci_check_error (ccErrBadParam); } + if (!in_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_identifier_write (in_list_iterator->identifier, + in_stream); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_iterator_clone (ccs_list_iterator_t in_list_iterator, + ccs_list_iterator_t *out_list_iterator) +{ + cc_int32 err = ccNoError; + ccs_list_iterator_t list_iterator = NULL; + + if (!in_list_iterator ) { err = cci_check_error (ccErrBadParam); } + if (!out_list_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_list_iterator_new (&list_iterator, in_list_iterator->list); + } + + if (!err) { + list_iterator->current = in_list_iterator->current; + + *out_list_iterator = list_iterator; + list_iterator = NULL; + } + + ccs_list_iterator_release (list_iterator); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_list_iterator_object_release (cci_array_object_t io_list_iterator) +{ + cc_int32 err = ccNoError; + ccs_list_iterator_t list_iterator = (ccs_list_iterator_t) io_list_iterator; + + if (!io_list_iterator) { err = ccErrBadParam; } + + if (!err) { + cci_identifier_release (list_iterator->identifier); + free (io_list_iterator); + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator) +{ + cc_int32 err = ccNoError; + + if (!io_list_iterator) { err = ccErrBadParam; } + + if (!err) { + cc_uint64 i = 0; + + if (ccs_list_find_iterator_index (io_list_iterator->list, + io_list_iterator->identifier, + &i) == ccNoError) { + /* cci_array_remove will call ccs_list_iterator_object_release */ + cci_array_remove (io_list_iterator->list->iterators, i); + } else { + cci_debug_printf ("Warning: iterator not in iterator list!"); + } + } + + return err; +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_iterator_current (ccs_list_iterator_t io_list_iterator, + ccs_object_t *out_object) +{ + cc_int32 err = ccNoError; + + if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); } + if (!out_object ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (io_list_iterator->current < cci_array_count (io_list_iterator->list->objects)) { + *out_object = cci_array_object_at_index (io_list_iterator->list->objects, + io_list_iterator->current); + } else { + err = ccIteratorEnd; + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_list_iterator_next (ccs_list_iterator_t io_list_iterator, + ccs_object_t *out_object) +{ + cc_int32 err = ccNoError; + + if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); } + if (!out_object ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (io_list_iterator->current < cci_array_count (io_list_iterator->list->objects)) { + *out_object = cci_array_object_at_index (io_list_iterator->list->objects, + io_list_iterator->current); + io_list_iterator->current++; + } else { + err = ccIteratorEnd; + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_list_iterator_update (ccs_list_iterator_t io_list_iterator, + ccs_list_action_enum in_action, + cc_uint64 in_object_index) +{ + cc_int32 err = ccNoError; + + if (!io_list_iterator) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* When the list changes adjust the current index so that */ + /* we don't unnecessarily skip or double count items */ + if (in_action == ccs_list_action_insert) { + if (io_list_iterator->current > in_object_index) { + io_list_iterator->current++; + } + + } else if (in_action == ccs_list_action_remove) { + if (io_list_iterator->current >= in_object_index) { + io_list_iterator->current--; + } + + } else if (in_action == ccs_list_action_push_front) { + if (io_list_iterator->current < in_object_index) { + io_list_iterator->current++; + } + + } else { + err = cci_check_error (ccErrBadParam); + } + } + + return cci_check_error (err); +} + diff --git a/src/ccapi/server/ccs_list_internal.h b/src/ccapi/server/ccs_list_internal.h new file mode 100644 index 000000000..83320a5eb --- /dev/null +++ b/src/ccapi/server/ccs_list_internal.h @@ -0,0 +1,92 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_LIST_INTERNAL_H +#define CCS_LIST_INTERNAL_H + +#include "cci_common.h" + +struct ccs_list_d; +typedef struct ccs_list_d *ccs_list_t; + +struct ccs_list_iterator_d; +typedef struct ccs_list_iterator_d *ccs_list_iterator_t; + +typedef void *ccs_object_t; +typedef cc_int32 (*ccs_object_release_t) (ccs_object_t); +typedef cc_int32 (*ccs_object_compare_identifier_t) (ccs_object_t, cci_identifier_t, cc_uint32 *); + +cc_int32 ccs_list_new (ccs_list_t *out_list, + cc_int32 in_object_not_found_err, + cc_int32 in_iterator_not_found_err, + ccs_object_compare_identifier_t in_object_compare_identifier, + ccs_object_release_t in_object_release); + +cc_int32 ccs_list_release (ccs_list_t io_list); + +cc_int32 ccs_list_new_iterator (ccs_list_t io_list, + ccs_list_iterator_t *out_list_iterator); + +cc_int32 ccs_list_release_iterator (ccs_list_t io_list, + cci_identifier_t in_identifier); + +cc_int32 ccs_list_count (ccs_list_t in_list, + cc_uint64 *out_count); + +cc_int32 ccs_list_find (ccs_list_t in_list, + cci_identifier_t in_identifier, + ccs_object_t *out_object); + +cc_int32 ccs_list_find_iterator (ccs_list_t in_list, + cci_identifier_t in_identifier, + ccs_list_iterator_t *out_list_iterator); + +cc_int32 ccs_list_add (ccs_list_t io_list, + ccs_object_t in_object); + +cc_int32 ccs_list_remove (ccs_list_t io_list, + cci_identifier_t in_identifier); + +cc_int32 ccs_list_push_front (ccs_list_t io_list, + cci_identifier_t in_identifier); + + +cc_int32 ccs_list_iterator_write (ccs_list_iterator_t in_list_iterator, + cci_stream_t in_stream); + +cc_int32 ccs_list_iterator_clone (ccs_list_iterator_t in_list_iterator, + ccs_list_iterator_t *out_list_iterator); + +cc_int32 ccs_list_iterator_current (ccs_list_iterator_t io_list_iterator, + ccs_object_t *out_object); + +cc_int32 ccs_list_iterator_next (ccs_list_iterator_t io_list_iterator, + ccs_object_t *out_object); + +cc_int32 ccs_list_iterator_release (ccs_list_iterator_t io_list_iterator); + + +#endif /* CCS_LIST_INTERNAL_H */ diff --git a/src/ccapi/server/ccs_lock.c b/src/ccapi/server/ccs_lock.c new file mode 100644 index 000000000..939da5e12 --- /dev/null +++ b/src/ccapi/server/ccs_lock.c @@ -0,0 +1,245 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +struct ccs_lock_d { + cc_uint32 type; + cc_uint32 pending; + cc_int32 invalid_object_err; + ccs_pipe_t client_pipe; + ccs_pipe_t reply_pipe; +}; + +struct ccs_lock_d ccs_lock_initializer = { 0, 1, 1, NULL, NULL }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_new (ccs_lock_t *out_lock, + cc_uint32 in_type, + cc_int32 in_invalid_object_err, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe) +{ + cc_int32 err = ccNoError; + ccs_lock_t lock = NULL; + + if (!out_lock ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + + if (in_type != cc_lock_read && + in_type != cc_lock_write && + in_type != cc_lock_upgrade && + in_type != cc_lock_downgrade) { + err = cci_check_error (ccErrBadLockType); + } + + if (!err) { + lock = malloc (sizeof (*lock)); + if (lock) { + *lock = ccs_lock_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_pipe_copy (&lock->client_pipe, in_client_pipe); + } + + if (!err) { + err = ccs_pipe_copy (&lock->reply_pipe, in_reply_pipe); + } + + if (!err) { + lock->type = in_type; + lock->invalid_object_err = in_invalid_object_err; + + *out_lock = lock; + lock = NULL; + } + + ccs_lock_release (lock); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_release (ccs_lock_t io_lock) +{ + cc_int32 err = ccNoError; + + if (!io_lock) { err = cci_check_error (ccErrBadParam); } + + if (!err && io_lock->pending) { + err = ccs_server_send_reply (io_lock->reply_pipe, + io_lock->invalid_object_err, NULL); + } + + if (!err) { + ccs_pipe_release (io_lock->client_pipe); + ccs_pipe_release (io_lock->reply_pipe); + free (io_lock); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock) +{ + cc_int32 err = ccNoError; + + if (!io_lock) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (io_lock->pending) { + err = ccs_server_send_reply (io_lock->reply_pipe, err, NULL); + + if (!err) { + ccs_pipe_release (io_lock->reply_pipe); + io_lock->pending = 0; + io_lock->reply_pipe = NULL; + } + } else { + cci_debug_printf ("WARNING %s() called on non-pending lock!", + __FUNCTION__); + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_uint32 ccs_lock_is_pending (ccs_lock_t in_lock, + cc_uint32 *out_pending) +{ + cc_int32 err = ccNoError; + + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + if (!out_pending) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_pending = in_lock->pending; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_type (ccs_lock_t in_lock, + cc_uint32 *out_lock_type) +{ + cc_int32 err = ccNoError; + + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + if (!out_lock_type) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_lock_type = in_lock->type; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_is_read_lock (ccs_lock_t in_lock, + cc_uint32 *out_is_read_lock) +{ + cc_int32 err = ccNoError; + + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + if (!out_is_read_lock) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_is_read_lock = (in_lock->type == cc_lock_read || + in_lock->type == cc_lock_downgrade); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_is_write_lock (ccs_lock_t in_lock, + cc_uint32 *out_is_write_lock) +{ + cc_int32 err = ccNoError; + + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + if (!out_is_write_lock) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_is_write_lock = (in_lock->type == cc_lock_write || + in_lock->type == cc_lock_upgrade); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_is_for_client (ccs_lock_t in_lock, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_is_for_client) +{ + cc_int32 err = ccNoError; + + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + if (!out_is_for_client ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_pipe_compare (in_lock->client_pipe, in_client_pipe, + out_is_for_client); + } + + return cci_check_error (err); +} + + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_client (ccs_lock_t in_lock, + ccs_pipe_t *out_client_pipe) +{ + cc_int32 err = ccNoError; + + if (!in_lock ) { err = cci_check_error (ccErrBadParam); } + if (!out_client_pipe) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_client_pipe = in_lock->client_pipe; + } + + return cci_check_error (err); +} diff --git a/src/ccapi/server/ccs_lock.h b/src/ccapi/server/ccs_lock.h new file mode 100644 index 000000000..197f5d50d --- /dev/null +++ b/src/ccapi/server/ccs_lock.h @@ -0,0 +1,61 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_LOCK_H +#define CCS_LOCK_H + +#include "ccs_types.h" + +cc_int32 ccs_lock_new (ccs_lock_t *out_lock, + cc_uint32 in_type, + cc_int32 in_invalid_object_err, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe); + +cc_int32 ccs_lock_release (ccs_lock_t io_lock); + +cc_int32 ccs_lock_grant_lock (ccs_lock_t io_lock); + +cc_uint32 ccs_lock_is_pending (ccs_lock_t in_lock, + cc_uint32 *out_pending); + +cc_int32 ccs_lock_type (ccs_lock_t in_lock, + cc_uint32 *out_lock_type); + +cc_int32 ccs_lock_is_read_lock (ccs_lock_t in_lock, + cc_uint32 *out_is_read_lock); + +cc_int32 ccs_lock_is_write_lock (ccs_lock_t in_lock, + cc_uint32 *out_is_write_lock); + +cc_int32 ccs_lock_is_for_client (ccs_lock_t in_lock, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_is_for_client); + +cc_int32 ccs_lock_client (ccs_lock_t in_lock, + ccs_pipe_t *out_client_pipe); + +#endif /* CCS_LOCK_H */ diff --git a/src/ccapi/server/ccs_lock_state.c b/src/ccapi/server/ccs_lock_state.c new file mode 100644 index 000000000..f9bb614c2 --- /dev/null +++ b/src/ccapi/server/ccs_lock_state.c @@ -0,0 +1,543 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +struct ccs_lock_state_d { + cc_int32 invalid_object_err; + cc_int32 pending_lock_err; + cc_int32 no_lock_err; + ccs_lock_array_t locks; + cc_uint64 first_pending_lock_index; +}; + +struct ccs_lock_state_d ccs_lock_state_initializer = { 1, 1, 1, NULL, 0 }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_state_new (ccs_lock_state_t *out_lock_state, + cc_int32 in_invalid_object_err, + cc_int32 in_pending_lock_err, + cc_int32 in_no_lock_err) +{ + cc_int32 err = ccNoError; + ccs_lock_state_t lock_state = NULL; + + if (!out_lock_state) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + lock_state = malloc (sizeof (*lock_state)); + if (lock_state) { + *lock_state = ccs_lock_state_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_lock_array_new (&lock_state->locks); + } + + if (!err) { + lock_state->invalid_object_err = in_invalid_object_err; + lock_state->pending_lock_err = in_pending_lock_err; + lock_state->no_lock_err = in_no_lock_err; + + *out_lock_state = lock_state; + lock_state = NULL; + } + + ccs_lock_state_release (lock_state); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_state_release (ccs_lock_state_t io_lock_state) +{ + cc_int32 err = ccNoError; + + if (!io_lock_state) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + ccs_lock_array_release (io_lock_state->locks); + free (io_lock_state); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_state_allow_read (ccs_lock_state_t in_lock_state, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_allow_read) +{ + cc_int32 err = ccNoError; + cc_uint32 allow_read = 0; + + if (!in_lock_state ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!out_allow_read ) { err = cci_check_error (ccErrBadParam); } + + /* A client may read if no other clients have write locks */ + + if (!err) { + cc_uint64 lock_count = in_lock_state->first_pending_lock_index; + if (lock_count == 0) { + allow_read = 1; + } else { + ccs_lock_t lock = ccs_lock_array_object_at_index (in_lock_state->locks, 0); + cc_uint32 is_read_lock; + cc_uint32 is_for_client; + + err = ccs_lock_is_read_lock (lock, &is_read_lock); + + if (!err) { + err = ccs_lock_is_for_client (lock, in_client_pipe, &is_for_client); + } + + if (!err) { + /* read locks or write lock we own */ + allow_read = (is_read_lock || is_for_client); + } + } + } + + if (!err) { + *out_allow_read = allow_read; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_state_allow_write (ccs_lock_state_t in_lock_state, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_allow_write) +{ + cc_int32 err = ccNoError; + cc_uint32 allow_write = 0; + + if (!in_lock_state ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!out_allow_write ) { err = cci_check_error (ccErrBadParam); } + + /* A client may write if there are no locks or if it has a write lock */ + + if (!err) { + cc_uint64 lock_count = in_lock_state->first_pending_lock_index; + if (lock_count == 0) { + allow_write = 1; + } else { + ccs_lock_t lock = ccs_lock_array_object_at_index (in_lock_state->locks, 0); + cc_uint32 is_write_lock = 0; + cc_uint32 is_for_client = 0; + + err = ccs_lock_is_write_lock (lock, &is_write_lock); + + if (!err) { + err = ccs_lock_is_for_client (lock, in_client_pipe, &is_for_client); + } + + if (!err) { + allow_write = (is_write_lock && is_for_client); + } + } + } + + if (!err) { + *out_allow_write = allow_write; + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_lock_status_add_pending_lock (ccs_lock_state_t io_lock_state, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + cc_uint32 in_lock_type, + cc_uint64 *out_lock_index) +{ + cc_int32 err = ccNoError; + ccs_lock_t lock = NULL; + + if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_lock_new (&lock, in_lock_type, + io_lock_state->invalid_object_err, + in_client_pipe, in_reply_pipe); + } + + if (!err) { + err = ccs_lock_array_insert (io_lock_state->locks, lock, + ccs_lock_array_count (io_lock_state->locks)); + if (!err) { lock = NULL; /* take ownership */ } + } + + if (!err) { + *out_lock_index = ccs_lock_array_count (io_lock_state->locks) - 1; + } + + ccs_lock_release (lock); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_lock_status_remove_lock (ccs_lock_state_t io_lock_state, + cc_uint64 in_lock_index) +{ + cc_int32 err = ccNoError; + + if (!io_lock_state) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_lock_array_remove (io_lock_state->locks, in_lock_index); + + if (!err && in_lock_index < io_lock_state->first_pending_lock_index) { + io_lock_state->first_pending_lock_index--; + } + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_lock_status_grant_lock (ccs_lock_state_t io_lock_state, + cc_uint64 in_pending_lock_index) +{ + cc_int32 err = ccNoError; + cc_uint64 new_lock_index = 0; + + if (!io_lock_state) { err = cci_check_error (ccErrBadParam); } + + if (!err && in_pending_lock_index < io_lock_state->first_pending_lock_index) { + err = cci_check_error (ccErrBadParam); + } + + if (!err) { + err = ccs_lock_array_move (io_lock_state->locks, + in_pending_lock_index, + io_lock_state->first_pending_lock_index, + &new_lock_index); + if (!err) { io_lock_state->first_pending_lock_index++; } + } + + if (!err) { + ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, + new_lock_index); + err = ccs_lock_grant_lock (lock); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_lock_state_check_pending_lock (ccs_lock_state_t io_lock_state, + ccs_pipe_t in_pending_lock_client_pipe, + cc_uint32 in_pending_lock_type, + cc_uint32 *out_grant_lock) +{ + cc_int32 err = ccNoError; + cc_uint32 is_write_locked = 0; + cc_uint32 client_has_lock = 0; + cc_uint32 client_lock_type = 0; + cc_uint32 grant_lock = 0; + + if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_pending_lock_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!out_grant_lock ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_uint64 i; + cc_uint64 lock_count = io_lock_state->first_pending_lock_index; + + for (i = 0; !err && i < lock_count; i++) { + ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); + cc_uint32 lock_type = 0; + cc_uint32 lock_is_for_client = 0; + + err = ccs_lock_type (lock, &lock_type); + + if (!err) { + err = ccs_lock_is_for_client (lock, in_pending_lock_client_pipe, + &lock_is_for_client); + } + + if (!err) { + if (lock_type == cc_lock_write || lock_type == cc_lock_upgrade) { + if (is_write_locked) { + cci_debug_printf ("WARNING %s() multiple write locks.", + __FUNCTION__); + } + is_write_locked = 1; + } + + if (lock_is_for_client) { + if (client_has_lock) { + cci_debug_printf ("WARNING %s() client has multiple locks.", + __FUNCTION__); + } + client_has_lock = 1; + client_lock_type = lock_type; + } + } + } + } + + if (!err) { + cc_uint64 lock_count = io_lock_state->first_pending_lock_index; + + if (in_pending_lock_type == cc_lock_write) { + if (client_has_lock) { + err = cci_check_error (ccErrBadLockType); + } else { + grant_lock = (lock_count == 0); + } + + } else if (in_pending_lock_type == cc_lock_read) { + if (client_has_lock) { + err = cci_check_error (ccErrBadLockType); + } else { + grant_lock = !is_write_locked; + } + + } else if (in_pending_lock_type == cc_lock_upgrade) { + if (!client_has_lock || (client_lock_type != cc_lock_read && + client_lock_type != cc_lock_downgrade)) { + err = cci_check_error (ccErrBadLockType); + } else { + /* don't grant if other clients have read locks */ + grant_lock = (lock_count == 1); + } + + } else if (in_pending_lock_type == cc_lock_downgrade) { + if (!client_has_lock || (client_lock_type != cc_lock_write && + client_lock_type != cc_lock_upgrade)) { + err = cci_check_error (ccErrBadLockType); + } else { + /* downgrades can never block */ + grant_lock = 1; + } + } else { + err = cci_check_error (ccErrBadLockType); + } + } + + if (!err) { + *out_grant_lock = grant_lock; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_lock_status_try_to_grant_pending_locks (ccs_lock_state_t io_lock_state) +{ + cc_int32 err = ccNoError; + cc_uint32 done = 1; + + if (!io_lock_state) { err = cci_check_error (ccErrBadParam); } + + /* The lock array should now be in one of two states: empty or containing + * only read locks because if it contained a write lock we would have just + * deleted it. Look at the pending locks and see if we can grant them. + * Note that downgrade locks mean we must check all pending locks each pass + * since a downgrade lock might be last in the list. */ + + + while (!err && !done) { + cc_uint64 i; + cc_uint64 count = ccs_lock_array_count (io_lock_state->locks); + cc_uint32 granted_lock = 0; + + for (i = io_lock_state->first_pending_lock_index; !err && i < count; i++) { + ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); + cc_uint32 lock_type = 0; + ccs_pipe_t client_pipe = NULL; + cc_uint32 can_grant_lock_now = 0; + + err = ccs_lock_client (lock, &client_pipe); + + if (!err) { + err = ccs_lock_type (lock, &lock_type); + } + + if (!err) { + err = ccs_lock_state_check_pending_lock (io_lock_state, client_pipe, + lock_type, &can_grant_lock_now); + } + + if (!err && can_grant_lock_now) { + err = ccs_lock_status_grant_lock (io_lock_state, i); + if (!err) { granted_lock = 1; } + } + } + + if (!err && !granted_lock) { + done = 1; + } + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_state_add (ccs_lock_state_t io_lock_state, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + cc_uint32 in_lock_type, + cc_uint32 in_block, + cc_uint32 *out_will_block) +{ + cc_int32 err = ccNoError; + cc_uint32 can_grant_lock_now = 0; + cc_uint32 will_block = 0; + + if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + if (!out_will_block ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* Sanity check: if there are any pending locks for this client + * the client must have timed out waiting for our reply. Remove any + * existing pending locks for the client. */ + cc_uint64 i; + cc_uint64 count = ccs_lock_array_count (io_lock_state->locks); + + for (i = io_lock_state->first_pending_lock_index; !err && i < count; i++) { + ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); + cc_uint32 has_pending_lock_for_client = 0; + + err = ccs_lock_is_for_client (lock, in_client_pipe, &has_pending_lock_for_client); + + if (!err && has_pending_lock_for_client) { + cci_debug_printf ("WARNING %s() removing pending lock for client.", __FUNCTION__); + err = ccs_lock_status_remove_lock (io_lock_state, i); + } + } + } + + if (!err) { + err = ccs_lock_state_check_pending_lock (io_lock_state, in_client_pipe, + in_lock_type, &can_grant_lock_now); + } + + if (!err) { + if (!can_grant_lock_now && !in_block) { + err = cci_check_error (io_lock_state->pending_lock_err); + + } else { + cc_uint64 new_lock_index = 0; + + err = ccs_lock_status_add_pending_lock (io_lock_state, + in_client_pipe, + in_reply_pipe, + in_lock_type, + &new_lock_index); + + if (!err) { + if (can_grant_lock_now) { + err = ccs_lock_status_grant_lock (io_lock_state, + new_lock_index); + + if (!err && (in_lock_type == cc_lock_downgrade)) { + /* downgrades can allow us to grant other locks */ + err = ccs_lock_status_try_to_grant_pending_locks (io_lock_state); + } + } else { + will_block = 1; + } + } + } + } + + if (!err) { + *out_will_block = will_block; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_lock_state_remove (ccs_lock_state_t io_lock_state, + ccs_pipe_t in_client_pipe) +{ + cc_int32 err = ccNoError; + cc_uint32 found_lock = 0; + + if (!io_lock_state ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + cc_uint64 i; + cc_uint64 lock_count = io_lock_state->first_pending_lock_index; + + for (i = 0; !err && i < lock_count; i++) { + ccs_lock_t lock = ccs_lock_array_object_at_index (io_lock_state->locks, i); + + err = ccs_lock_is_for_client (lock, in_client_pipe, &found_lock); + + if (!err && found_lock) { + cci_debug_printf ("%s: Removing lock %p.", __FUNCTION__, lock); + err = ccs_lock_status_remove_lock (io_lock_state, i); + break; + } + } + } + + if (!err && !found_lock) { + err = cci_check_error (io_lock_state->no_lock_err); + } + + if (!err) { + err = ccs_lock_status_try_to_grant_pending_locks (io_lock_state); + } + + return cci_check_error (err); +} + diff --git a/src/ccapi/server/ccs_lock_state.h b/src/ccapi/server/ccs_lock_state.h new file mode 100644 index 000000000..1918452c6 --- /dev/null +++ b/src/ccapi/server/ccs_lock_state.h @@ -0,0 +1,57 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_LOCK_STATE_H +#define CCS_LOCK_STATE_H + +#include "ccs_types.h" + +cc_int32 ccs_lock_state_new (ccs_lock_state_t *out_lock_state, + cc_int32 in_invalid_object_err, + cc_int32 in_pending_lock_err, + cc_int32 in_no_lock_err); + +cc_int32 ccs_lock_state_release (ccs_lock_state_t io_lock_state); + +cc_int32 ccs_lock_state_allow_read (ccs_lock_state_t in_lock_state, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_allow_read); + +cc_int32 ccs_lock_state_allow_write (ccs_lock_state_t in_lock_state, + ccs_pipe_t in_client_pipe, + cc_uint32 *out_allow_write); + +cc_int32 ccs_lock_state_add (ccs_lock_state_t io_lock_state, + ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + cc_uint32 in_lock_type, + cc_uint32 in_block, + cc_uint32 *out_will_block); + +cc_int32 ccs_lock_state_remove (ccs_lock_state_t io_lock_state, + ccs_pipe_t in_client_pipe); + +#endif /* CCS_LOCK_STATE_H */ diff --git a/src/ccapi/server/ccs_os_pipe.h b/src/ccapi/server/ccs_os_pipe.h new file mode 100644 index 000000000..57fe64b99 --- /dev/null +++ b/src/ccapi/server/ccs_os_pipe.h @@ -0,0 +1,44 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_OS_PIPE_H +#define CCS_OS_PIPE_H + +#include "ccs_types.h" + +inline cc_int32 ccs_os_pipe_copy (ccs_os_pipe_t *out_pipe, + ccs_os_pipe_t in_pipe); + +inline cc_int32 ccs_os_pipe_release (ccs_os_pipe_t io_pipe); + +inline cc_int32 ccs_os_pipe_compare (ccs_os_pipe_t in_pipe, + ccs_os_pipe_t in_compare_to_pipe, + cc_uint32 *out_equal); + +cc_int32 ccs_os_pipe_valid (ccs_os_pipe_t in_pipe); + + +#endif /* CCS_OS_PIPE_H */ diff --git a/src/ccapi/server/ccs_os_server.h b/src/ccapi/server/ccs_os_server.h new file mode 100644 index 000000000..557ad5905 --- /dev/null +++ b/src/ccapi/server/ccs_os_server.h @@ -0,0 +1,35 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_OS_SERVER_H +#define CCS_OS_SERVER_H + +#include "ccs_types.h" + +cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_reply_pipe, + cci_stream_t in_reply_stream); + +#endif /* CCS_OS_SERVER_H */ diff --git a/src/ccapi/server/ccs_pipe.c b/src/ccapi/server/ccs_pipe.c new file mode 100644 index 000000000..d7521b57f --- /dev/null +++ b/src/ccapi/server/ccs_pipe.c @@ -0,0 +1,163 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" +#include "ccs_os_pipe.h" + +struct ccs_pipe_d { + ccs_os_pipe_t os_pipe; +}; + +struct ccs_pipe_d ccs_pipe_initializer = { CCS_OS_PIPE_NULL }; + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_pipe_new (ccs_pipe_t *out_pipe, + ccs_os_pipe_t in_os_pipe) +{ + cc_int32 err = ccNoError; + ccs_pipe_t new_pipe = NULL; + + if (!out_pipe ) { err = cci_check_error (ccErrBadParam); } + if (!ccs_os_pipe_valid (in_os_pipe)) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + new_pipe = malloc (sizeof (*new_pipe)); + if (new_pipe) { + *new_pipe = ccs_pipe_initializer; + } else { + err = cci_check_error (ccErrNoMem); + } + } + + if (!err) { + err = ccs_os_pipe_copy (&new_pipe->os_pipe, in_os_pipe); + } + + if (!err) { + *out_pipe = new_pipe; + new_pipe = NULL; + } + + ccs_pipe_release (new_pipe); + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_pipe_release (ccs_pipe_t io_pipe) +{ + cc_int32 err = ccNoError; + + if (!io_pipe) { err = ccErrBadParam; } + + if (!err) { + ccs_os_pipe_release (io_pipe->os_pipe); + free (io_pipe); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_pipe_copy (ccs_pipe_t *out_pipe, + ccs_pipe_t in_pipe) +{ + cc_int32 err = ccNoError; + + if (!out_pipe) { err = cci_check_error (ccErrBadParam); } + if (!in_pipe ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_pipe_new (out_pipe, in_pipe->os_pipe); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_pipe_compare (ccs_pipe_t in_pipe, + ccs_pipe_t in_compare_to_pipe, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (!in_pipe ) { err = cci_check_error (ccErrBadParam); } + if (!in_compare_to_pipe) { err = cci_check_error (ccErrBadParam); } + if (!out_equal ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_os_pipe_compare (in_pipe->os_pipe, + in_compare_to_pipe->os_pipe, + out_equal); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_pipe_compare_to_os_pipe (ccs_pipe_t in_pipe, + ccs_os_pipe_t in_compare_to_os_pipe, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (in_pipe) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = ccs_os_pipe_compare (in_pipe->os_pipe, + in_compare_to_os_pipe, + out_equal); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_pipe_valid (ccs_pipe_t in_pipe) +{ + if (in_pipe) { + return ccs_os_pipe_valid (in_pipe->os_pipe); + } else { + return 0; + } +} + + +/* ------------------------------------------------------------------------ */ + +ccs_os_pipe_t ccs_pipe_os (ccs_pipe_t in_pipe) +{ + if (in_pipe) { + return in_pipe->os_pipe; + } else { + return CCS_OS_PIPE_NULL; + } +} diff --git a/src/ccapi/server/ccs_pipe.h b/src/ccapi/server/ccs_pipe.h new file mode 100644 index 000000000..7f3c0d40d --- /dev/null +++ b/src/ccapi/server/ccs_pipe.h @@ -0,0 +1,52 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_PIPE_H +#define CCS_PIPE_H + +#include "ccs_types.h" + +cc_int32 ccs_pipe_new (ccs_pipe_t *out_pipe, + ccs_os_pipe_t in_os_pipe); + +cc_int32 ccs_pipe_copy (ccs_pipe_t *out_pipe, + ccs_pipe_t in_pipe); + +inline cc_int32 ccs_pipe_release (ccs_pipe_t io_pipe); + +cc_int32 ccs_pipe_compare (ccs_pipe_t in_pipe, + ccs_pipe_t in_compare_to_pipe, + cc_uint32 *out_equal); + +cc_int32 ccs_pipe_compare_to_os_pipe (ccs_pipe_t in_pipe, + ccs_os_pipe_t in_compare_to_os_pipe, + cc_uint32 *out_equal); + +cc_int32 ccs_pipe_valid (ccs_pipe_t in_pipe); + +ccs_os_pipe_t ccs_pipe_os (ccs_pipe_t in_pipe); + +#endif /* CCS_PIPE_H */ diff --git a/src/ccapi/server/ccs_server.c b/src/ccapi/server/ccs_server.c new file mode 100644 index 000000000..b7d3be4b1 --- /dev/null +++ b/src/ccapi/server/ccs_server.c @@ -0,0 +1,333 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" +#include "ccs_os_server.h" + +/* Server Globals: */ + +cci_uuid_string_t g_server_id = NULL; +ccs_cache_collection_t g_cache_collection = NULL; +ccs_pipe_array_t g_client_pipe_array = NULL; + +/* ------------------------------------------------------------------------ */ + + cc_int32 ccs_server_initialize (void) +{ + cc_int32 err = ccNoError; + + if (!err) { + err = cci_identifier_new_uuid (&g_server_id); + } + + if (!err) { + err = ccs_cache_collection_new (&g_cache_collection); + } + + if (!err) { + err = ccs_pipe_array_new (&g_client_pipe_array); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + + cc_int32 ccs_server_cleanup (void) +{ + cc_int32 err = ccNoError; + + if (!err) { + free (g_server_id); + cci_check_error (ccs_cache_collection_release (g_cache_collection)); + cci_check_error (ccs_pipe_array_release (g_client_pipe_array)); + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_server_new_identifier (cci_identifier_t *out_identifier) +{ + return cci_check_error (cci_identifier_new (out_identifier, + g_server_id)); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_server_add_client (ccs_os_pipe_t in_connection_os_pipe) +{ + cc_int32 err = ccNoError; + ccs_pipe_t connection_pipe = NULL; + + if (!err) { + err = ccs_pipe_new (&connection_pipe, in_connection_os_pipe); + } + + if (!err) { + cci_debug_printf ("%s: Adding client %p.", __FUNCTION__, connection_pipe); + err = ccs_pipe_array_insert (g_client_pipe_array, + connection_pipe, + ccs_pipe_array_count (g_client_pipe_array)); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_server_remove_client (ccs_os_pipe_t in_connection_os_pipe) +{ + cc_int32 err = ccNoError; + + if (!err) { + cc_uint64 i; + cc_uint64 count = ccs_pipe_array_count (g_client_pipe_array); + cc_uint32 found = 0; + + for (i = 0; !err && i < count; i++) { + ccs_pipe_t client = ccs_pipe_array_object_at_index (g_client_pipe_array, i); + + err = ccs_pipe_compare_to_os_pipe (client, in_connection_os_pipe, &found); + + if (!err && found) { + cci_debug_printf ("%s: Removing client %p.", __FUNCTION__, client); + err = ccs_pipe_array_remove (g_client_pipe_array, i); + break; + } + } + + if (!err && !found) { + cci_debug_printf ("WARNING %s() didn't find client in client list.", + __FUNCTION__); + } + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +static cc_int32 ccs_server_request_demux (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + ccs_cache_collection_t in_cache_collection, + enum cci_msg_id_t in_request_name, + cci_identifier_t in_request_identifier, + cci_stream_t in_request_data, + cc_uint32 *out_reply_immediately, + cci_stream_t *out_reply_data) +{ + cc_int32 err = ccNoError; + + if (!ccs_pipe_valid (in_reply_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!in_request_data ) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_immediately ) { err = cci_check_error (ccErrBadParam); } + if (!out_reply_data ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + if (in_request_name > cci_context_first_msg_id && + in_request_name < cci_context_last_msg_id) { + /* Note: context identifier doesn't need to match. + * Client just uses the identifier to detect server relaunch. */ + + if (!err) { + err = ccs_cache_collection_handle_message (in_client_pipe, + in_reply_pipe, + in_cache_collection, + in_request_name, + in_request_data, + out_reply_immediately, + out_reply_data); + } + + } else if (in_request_name > cci_ccache_first_msg_id && + in_request_name < cci_ccache_last_msg_id) { + ccs_ccache_t ccache = NULL; + + err = ccs_cache_collection_find_ccache (in_cache_collection, + in_request_identifier, + &ccache); + + if (!err) { + err = ccs_ccache_handle_message (in_client_pipe, + in_reply_pipe, + ccache, + in_cache_collection, + in_request_name, + in_request_data, + out_reply_immediately, + out_reply_data); + } + + } else if (in_request_name > cci_ccache_iterator_first_msg_id && + in_request_name < cci_ccache_iterator_last_msg_id) { + ccs_ccache_iterator_t ccache_iterator = NULL; + + err = ccs_cache_collection_find_ccache_iterator (in_cache_collection, + in_request_identifier, + &ccache_iterator); + + if (!err) { + err = ccs_ccache_iterator_handle_message (ccache_iterator, + in_cache_collection, + in_request_name, + in_request_data, + out_reply_data); + } + + if (!err) { + *out_reply_immediately = 1; /* can't block */ + } + + } else if (in_request_name > cci_credentials_iterator_first_msg_id && + in_request_name < cci_credentials_iterator_last_msg_id) { + ccs_credentials_iterator_t credentials_iterator = NULL; + ccs_ccache_t ccache = NULL; + + err = ccs_cache_collection_find_credentials_iterator (in_cache_collection, + in_request_identifier, + &ccache, + &credentials_iterator); + + if (!err) { + err = ccs_credentials_iterator_handle_message (credentials_iterator, + ccache, + in_request_name, + in_request_data, + out_reply_data); + } + + if (!err) { + *out_reply_immediately = 1; /* can't block */ + } + + } else { + err = ccErrBadInternalMessage; + } + } + + return cci_check_error (err); +} + +#pragma mark - + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_server_handle_request (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + cci_stream_t in_request) +{ + cc_int32 err = ccNoError; + enum cci_msg_id_t request_name = 0; + cci_identifier_t request_identifier = NULL; + cc_uint32 reply_immediately = 1; + cci_stream_t reply_data = NULL; + + if (!ccs_pipe_valid (in_client_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + if (!in_request ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_message_read_request_header (in_request, + &request_name, + &request_identifier); + } + + if (!err) { + cc_uint32 server_err = 0; + cc_uint32 valid = 0; + ccs_cache_collection_t cache_collection = g_cache_collection; + + server_err = cci_identifier_is_for_server (request_identifier, + g_server_id, + &valid); + + if (!server_err && !valid) { + server_err = cci_message_invalid_object_err (request_name); + } + + if (!server_err) { + + /* Monolithic server implementation would need to select + * cache collection here. Currently we only support per-user + * servers so we always use the same cache collection. */ + + server_err = ccs_server_request_demux (in_client_pipe, + in_reply_pipe, + cache_collection, + request_name, + request_identifier, + in_request, + &reply_immediately, + &reply_data); + } + + if (server_err || reply_immediately) { + err = ccs_server_send_reply (in_reply_pipe, server_err, reply_data); + } + } + + cci_identifier_release (request_identifier); + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_server_send_reply (ccs_pipe_t in_reply_pipe, + cc_int32 in_reply_err, + cci_stream_t in_reply_data) +{ + cc_int32 err = ccNoError; + cci_stream_t reply = NULL; + + if (!ccs_pipe_valid (in_reply_pipe) ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + err = cci_message_new_reply_header (&reply, in_reply_err); + } + + if (!err && in_reply_data && cci_stream_size (in_reply_data) > 0) { + err = cci_stream_write (in_reply_data, + cci_stream_data (in_reply_data), + cci_stream_size (in_reply_data)); + } + + if (!err) { + err = ccs_os_server_send_reply (in_reply_pipe, reply); + } + + cci_stream_release (reply); + + return cci_check_error (err); +} diff --git a/src/ccapi/server/ccs_server.h b/src/ccapi/server/ccs_server.h new file mode 100644 index 000000000..713271072 --- /dev/null +++ b/src/ccapi/server/ccs_server.h @@ -0,0 +1,50 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_SERVER_H +#define CCS_SERVER_H + +#include "ccs_types.h" + +cc_int32 ccs_server_initialize (void); + +cc_int32 ccs_server_cleanup (void); + +cc_int32 ccs_server_new_identifier (cci_identifier_t *out_identifier); + +cc_int32 ccs_server_add_client (ccs_os_pipe_t in_connection_os_pipe); + +cc_int32 ccs_server_remove_client (ccs_os_pipe_t in_connection_os_pipe); + +cc_int32 ccs_server_handle_request (ccs_pipe_t in_client_pipe, + ccs_pipe_t in_reply_pipe, + cci_stream_t in_request); + +cc_int32 ccs_server_send_reply (ccs_pipe_t in_reply_pipe, + cc_int32 in_reply_err, + cci_stream_t in_reply_data); + +#endif /* CCS_SERVER_H */ diff --git a/src/ccapi/server/ccs_types.h b/src/ccapi/server/ccs_types.h new file mode 100644 index 000000000..f96e8d39d --- /dev/null +++ b/src/ccapi/server/ccs_types.h @@ -0,0 +1,93 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#ifndef CCS_TYPES_H +#define CCS_TYPES_H + +#include "cci_types.h" + +struct cci_array_d; + +typedef struct cci_array_d *ccs_pipe_array_t; + +typedef struct cci_array_d *ccs_lock_array_t; + +#pragma mark - + +/* ccs_os_pipe_t is IPC-specific so it's special cased here */ + +#if TARGET_OS_MAC +#include <mach/mach_types.h> +typedef mach_port_t ccs_os_pipe_t; /* Mach IPC port */ +#define CCS_OS_PIPE_NULL MACH_PORT_NULL + +#else +typedef int ccs_os_pipe_t; /* Unix domain socket */ +#define CCS_OS_PIPE_NULL -1 + +#endif + +#pragma mark - + +struct ccs_pipe_d; +typedef struct ccs_pipe_d *ccs_pipe_t; + +struct ccs_list_d; +struct ccs_list_iterator_d; + +typedef struct ccs_list_d *ccs_cache_collection_list_t; + +typedef struct ccs_list_d *ccs_ccache_list_t; +typedef struct ccs_list_iterator_d *ccs_ccache_list_iterator_t; + +typedef struct ccs_list_d *ccs_credentials_list_t; +typedef struct ccs_list_iterator_d *ccs_credentials_list_iterator_t; + +#pragma mark - + +struct ccs_client_d; +typedef struct ccs_client_d *ccs_client_t; + +struct ccs_lock_d; +typedef struct ccs_lock_d *ccs_lock_t; + +struct ccs_lock_state_d; +typedef struct ccs_lock_state_d *ccs_lock_state_t; + +struct ccs_credentials_d; +typedef struct ccs_credentials_d *ccs_credentials_t; + +typedef ccs_credentials_list_iterator_t ccs_credentials_iterator_t; + +struct ccs_ccache_d; +typedef struct ccs_ccache_d *ccs_ccache_t; + +typedef ccs_ccache_list_iterator_t ccs_ccache_iterator_t; + +struct ccs_cache_collection_d; +typedef struct ccs_cache_collection_d *ccs_cache_collection_t; + +#endif /* CCS_TYPES_H */ diff --git a/src/ccapi/server/mac/CCacheServerInfo.plist b/src/ccapi/server/mac/CCacheServerInfo.plist new file mode 100644 index 000000000..e03d5f3ff --- /dev/null +++ b/src/ccapi/server/mac/CCacheServerInfo.plist @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>CCacheServer</string> + <key>CFBundleGetInfoString</key> + <string>4.1</string> + <key>CFBundleIconFile</key> + <string></string> + <key>CFBundleIdentifier</key> + <string>edu.mit.Kerberos.CCacheServer</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>Kerberos Credentials Cache Server</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleSignature</key> + <string>CCSa</string> + <key>CFBundleVersion</key> + <string>0.0.1d1</string> + <key>CFBundleShortVersionString</key> + <string>5.5</string> + <key>CFBundleGetInfoString</key> + <string>5.5 Copyright MIT</string> + <key>KfMDisplayVersion</key> + <string>5.5 Copyright MIT</string> + <key>KfMDisplayCopyright</key> + <string>Copyright MIT</string> + <key>NSHumanReadableCopyright</key> + <string>5.5 Copyright MIT</string> + <key>LSBackgroundOnly</key> + <string>1</string> +</dict> +</plist> diff --git a/src/ccapi/server/mac/ccs_os_pipe.c b/src/ccapi/server/mac/ccs_os_pipe.c new file mode 100644 index 000000000..c3e7542a6 --- /dev/null +++ b/src/ccapi/server/mac/ccs_os_pipe.c @@ -0,0 +1,79 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" +#include "ccs_os_pipe.h" +#include <mach/port.h> + +/* On Mac OS X ccs_os_pipe_t is a mach_port_t */ + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_os_pipe_copy (ccs_os_pipe_t *out_pipe, + ccs_os_pipe_t in_pipe) +{ + cc_int32 err = ccNoError; + + if (!out_pipe) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_pipe = in_pipe; + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_os_pipe_release (ccs_os_pipe_t io_pipe) +{ + return ccNoError; +} + +/* ------------------------------------------------------------------------ */ + +inline cc_int32 ccs_os_pipe_compare (ccs_os_pipe_t in_pipe, + ccs_os_pipe_t in_compare_to_pipe, + cc_uint32 *out_equal) +{ + cc_int32 err = ccNoError; + + if (!out_equal) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + *out_equal = (in_pipe == in_compare_to_pipe); + } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_os_pipe_valid (ccs_os_pipe_t in_pipe) +{ + return MACH_PORT_VALID (in_pipe); +} + diff --git a/src/ccapi/server/mac/edu.mit.Kerberos.CCacheServer.plist b/src/ccapi/server/mac/edu.mit.Kerberos.CCacheServer.plist new file mode 100644 index 000000000..42e7f2720 --- /dev/null +++ b/src/ccapi/server/mac/edu.mit.Kerberos.CCacheServer.plist @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>Label</key> + <string>edu.mit.Kerberos.CCacheServer</string> + <key>Program</key> + <string>/System/Library/CoreServices/CCacheServer.app/Contents/MacOS/CCacheServer</string> + <key>MachServices</key> + <dict> + <key>edu.mit.Kerberos.CCacheServer.ipcService</key> + <true/> + </dict> + <key>OnDemand</key> + <true/> +</dict> +</plist> diff --git a/src/ccapi/server/mac/main.c b/src/ccapi/server/mac/main.c new file mode 100644 index 000000000..0753a240b --- /dev/null +++ b/src/ccapi/server/mac/main.c @@ -0,0 +1,233 @@ +/* + * $Header$ + * + * Copyright 2006 Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +#include "ccs_common.h" + +#include <syslog.h> +#include <Kerberos/kipc_server.h> +#include "cci_mig_requestServer.h" +#include "cci_mig_reply.h" +#include "ccs_os_server.h" + +/* ------------------------------------------------------------------------ */ + +static boolean_t ccs_server_demux (mach_msg_header_t *request, + mach_msg_header_t *reply) +{ + boolean_t handled = false; + + if (!handled) { + handled = ccs_server (request, reply); + } + + if (!handled && request->msgh_id == MACH_NOTIFY_NO_SENDERS) { + kern_return_t err = KERN_SUCCESS; + + err = ccs_server_remove_client (request->msgh_local_port); + + if (!err) { + /* Check here for a client in our table and free rights associated with it */ + err = mach_port_mod_refs (mach_task_self (), request->msgh_local_port, + MACH_PORT_RIGHT_RECEIVE, -1); + } + + if (!err) { + handled = 1; /* was a port we are tracking */ + } + + cci_check_error (err); + } + + return handled; +} + +/* ------------------------------------------------------------------------ */ + +int main (int argc, const char *argv[]) +{ + cc_int32 err = 0; + + openlog (argv[0], LOG_CONS | LOG_PID, LOG_AUTH); + syslog (LOG_INFO, "Starting up."); + + if (!err) { + err = ccs_server_initialize (); + } + + if (!err) { + err = kipc_server_run_server (ccs_server_demux); + } + + /* cleanup ccs resources */ + ccs_server_cleanup (); + + syslog (LOG_NOTICE, "Exiting: %s (%d)", kipc_error_string (err), err); + + /* exit */ + return err ? 1 : 0; +} + +/* ------------------------------------------------------------------------ */ + +kern_return_t ccs_mipc_create_client_connection (mach_port_t in_server_port, + mach_port_t *out_connection_port) +{ + kern_return_t err = KERN_SUCCESS; + mach_port_t connection_port = MACH_PORT_NULL; + mach_port_t old_notification_target = MACH_PORT_NULL; + + if (!err) { + err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &connection_port); + } + + if (!err) { + err = mach_port_move_member (mach_task_self (), connection_port, kipc_server_get_listen_portset ()); + } + + if (!err) { + /* request no-senders notification so we can tell when client quits/crashes */ + err = mach_port_request_notification (mach_task_self (), connection_port, + MACH_NOTIFY_NO_SENDERS, 1, connection_port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, &old_notification_target ); + } + + if (!err) { + err = ccs_server_add_client (connection_port); + } + + if (!err) { + *out_connection_port = connection_port; + connection_port = MACH_PORT_NULL; + } + + if (MACH_PORT_VALID (connection_port)) { mach_port_deallocate (mach_task_self (), connection_port); } + + return cci_check_error (err); +} + +/* ------------------------------------------------------------------------ */ + +cc_int32 ccs_os_server_send_reply (ccs_pipe_t in_reply_pipe, + cci_stream_t in_reply_stream) +{ + kern_return_t err = KERN_SUCCESS; + cci_mipc_inl_reply_t inl_reply; + mach_msg_type_number_t inl_reply_length = 0; + cci_mipc_ool_reply_t ool_reply = NULL; + mach_msg_type_number_t ool_reply_length = 0; + + if (!ccs_pipe_valid (in_reply_pipe)) { err = cci_check_error (ccErrBadParam); } + if (!in_reply_stream ) { err = cci_check_error (ccErrBadParam); } + + if (!err) { + /* depending on how big the message is, use the fast inline buffer or + * the slow dynamically allocated buffer */ + mach_msg_type_number_t reply_length = cci_stream_size (in_reply_stream); + + if (reply_length > kCCAPIMaxILMsgSize) { + cci_debug_printf ("%s choosing out of line buffer (size is %d)", + __FUNCTION__, reply_length); + + err = vm_read (mach_task_self (), + (vm_address_t) cci_stream_data (in_reply_stream), reply_length, + (vm_address_t *) &ool_reply, &ool_reply_length); + + } else { + //cci_debug_printf ("%s choosing in line buffer (size is %d)", + // __FUNCTION__, reply_length); + + inl_reply_length = reply_length; + memcpy (inl_reply, cci_stream_data (in_reply_stream), reply_length); + } + } + + if (!err) { + err = ccs_mipc_reply (ccs_pipe_os (in_reply_pipe), + inl_reply, inl_reply_length, + ool_reply, ool_reply_length); + } + + if (!err) { + /* Because we use ",dealloc" ool_reply will be freed by mach. Don't double free it. */ + ool_reply = NULL; + ool_reply_length = 0; + } + + if (ool_reply_length) { vm_deallocate (mach_task_self (), (vm_address_t) ool_reply, ool_reply_length); } + + return cci_check_error (err); +} + + +/* ------------------------------------------------------------------------ */ + +kern_return_t ccs_mipc_request (mach_port_t in_connection_port, + mach_port_t in_reply_port, + cci_mipc_inl_request_t in_inl_request, + mach_msg_type_number_t in_inl_requestCnt, + cci_mipc_ool_request_t in_ool_request, + mach_msg_type_number_t in_ool_requestCnt) +{ + kern_return_t err = KERN_SUCCESS; + cci_stream_t request_stream = NULL; + ccs_pipe_t connection_pipe = NULL; + ccs_pipe_t reply_pipe = NULL; + + if (!err) { + err = cci_stream_new (&request_stream); + } + + if (!err) { + if (in_inl_requestCnt) { + err = cci_stream_write (request_stream, in_inl_request, in_inl_requestCnt); + + } else if (in_ool_requestCnt) { + err = cci_stream_write (request_stream, in_ool_request, in_ool_requestCnt); + + } else { + err = cci_check_error (ccErrBadInternalMessage); + } + } + + if (!err) { + err = ccs_pipe_new (&connection_pipe, in_connection_port); + } + + if (!err) { + err = ccs_pipe_new (&reply_pipe, in_reply_port); + } + + if (!err) { + err = ccs_server_handle_request (connection_pipe, reply_pipe, request_stream); + } + + ccs_pipe_release (connection_pipe); + ccs_pipe_release (reply_pipe); + cci_stream_release (request_stream); + if (in_ool_requestCnt) { vm_deallocate (mach_task_self (), (vm_address_t) in_ool_request, in_ool_requestCnt); } + + return cci_check_error (err); +} |
