1 /* ccapi/common/cci_identifier.c */ 2 /* 3 * Copyright 2006, 2007 Massachusetts Institute of Technology. 4 * All Rights Reserved. 5 * 6 * Export of this software from the United States of America may 7 * require a specific license from the United States Government. 8 * It is the responsibility of any person or organization contemplating 9 * export to obtain such a license before exporting. 10 * 11 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 12 * distribute this software and its documentation for any purpose and 13 * without fee is hereby granted, provided that the above copyright 14 * notice appear in all copies and that both that copyright notice and 15 * this permission notice appear in supporting documentation, and that 16 * the name of M.I.T. not be used in advertising or publicity pertaining 17 * to distribution of the software without specific, written prior 18 * permission. Furthermore if you modify this software you must label 19 * your software as modified software and not distribute it in such a 20 * fashion that it might be confused with the original M.I.T. software. 21 * M.I.T. makes no representations about the suitability of 22 * this software for any purpose. It is provided "as is" without express 23 * or implied warranty. 24 */ 25 26 #include "cci_common.h" 27 #include "cci_os_identifier.h" 28 29 struct cci_identifier_d { 30 cci_uuid_string_t server_id; 31 cci_uuid_string_t object_id; 32 }; 33 34 struct cci_identifier_d cci_identifier_initializer = { NULL, NULL }; 35 36 #define cci_uninitialized_server_id "NEEDS_SYNC" 37 #define cci_uninitialized_object_id "NEEDS_SYNC" 38 39 struct cci_identifier_d cci_identifier_uninitialized_d = { 40 cci_uninitialized_server_id, 41 cci_uninitialized_object_id 42 }; 43 const cci_identifier_t cci_identifier_uninitialized = &cci_identifier_uninitialized_d; 44 45 /* ------------------------------------------------------------------------ */ 46 47 cc_int32 cci_identifier_new_uuid (cci_uuid_string_t *out_uuid_string) 48 { 49 return cci_os_identifier_new_uuid (out_uuid_string); 50 } 51 52 /* ------------------------------------------------------------------------ */ 53 54 static cc_int32 cci_identifier_alloc (cci_identifier_t *out_identifier, 55 cci_uuid_string_t in_server_id, 56 cci_uuid_string_t in_object_id) 57 { 58 cc_int32 err = ccNoError; 59 cci_identifier_t identifier = NULL; 60 61 if (!out_identifier) { err = cci_check_error (ccErrBadParam); } 62 if (!in_server_id ) { err = cci_check_error (ccErrBadParam); } 63 if (!in_object_id ) { err = cci_check_error (ccErrBadParam); } 64 65 if (!err) { 66 identifier = malloc (sizeof (*identifier)); 67 if (identifier) { 68 *identifier = cci_identifier_initializer; 69 } else { 70 err = cci_check_error (ccErrNoMem); 71 } 72 } 73 74 if (!err) { 75 identifier->server_id = strdup (in_server_id); 76 if (!identifier->server_id) { err = cci_check_error (ccErrNoMem); } 77 } 78 79 if (!err) { 80 identifier->object_id = strdup (in_object_id); 81 if (!identifier->object_id) { err = cci_check_error (ccErrNoMem); } 82 } 83 84 if (!err) { 85 *out_identifier = identifier; 86 identifier = NULL; /* take ownership */ 87 } 88 89 cci_identifier_release (identifier); 90 91 return cci_check_error (err); 92 } 93 94 /* ------------------------------------------------------------------------ */ 95 96 cc_int32 cci_identifier_new (cci_identifier_t *out_identifier, 97 cci_uuid_string_t in_server_id) 98 { 99 cc_int32 err = ccNoError; 100 cci_uuid_string_t object_id = NULL; 101 102 if (!out_identifier) { err = cci_check_error (ccErrBadParam); } 103 if (!in_server_id ) { err = cci_check_error (ccErrBadParam); } 104 105 if (!err) { 106 err = cci_os_identifier_new_uuid (&object_id); 107 } 108 109 if (!err) { 110 err = cci_identifier_alloc (out_identifier, in_server_id, object_id); 111 } 112 113 if (object_id) { free (object_id); } 114 115 return cci_check_error (err); 116 } 117 118 /* ------------------------------------------------------------------------ */ 119 120 cc_int32 cci_identifier_copy (cci_identifier_t *out_identifier, 121 cci_identifier_t in_identifier) 122 { 123 cc_int32 err = ccNoError; 124 125 if (!out_identifier) { err = cci_check_error (ccErrBadParam); } 126 if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } 127 128 if (!err) { 129 err = cci_identifier_alloc (out_identifier, 130 in_identifier->server_id, 131 in_identifier->object_id); 132 } 133 134 return cci_check_error (err); 135 } 136 137 /* ------------------------------------------------------------------------ */ 138 139 cc_int32 cci_identifier_release (cci_identifier_t in_identifier) 140 { 141 cc_int32 err = ccNoError; 142 143 /* Do not free the static "uninitialized" identifier */ 144 if (!err && in_identifier && in_identifier != cci_identifier_uninitialized) { 145 free (in_identifier->server_id); 146 free (in_identifier->object_id); 147 free (in_identifier); 148 } 149 150 return cci_check_error (err); 151 } 152 153 #ifdef TARGET_OS_MAC 154 #pragma mark - 155 #endif 156 157 /* ------------------------------------------------------------------------ */ 158 159 cc_int32 cci_identifier_compare (cci_identifier_t in_identifier, 160 cci_identifier_t in_compare_to_identifier, 161 cc_uint32 *out_equal) 162 { 163 cc_int32 err = ccNoError; 164 165 if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } 166 if (!in_compare_to_identifier) { err = cci_check_error (ccErrBadParam); } 167 if (!out_equal ) { err = cci_check_error (ccErrBadParam); } 168 169 if (!err) { 170 *out_equal = (!strcmp (in_identifier->object_id, 171 in_compare_to_identifier->object_id) && 172 !strcmp (in_identifier->server_id, 173 in_compare_to_identifier->server_id)); 174 } 175 176 return cci_check_error (err); 177 } 178 179 /* ------------------------------------------------------------------------ */ 180 181 cc_int32 cci_identifier_is_for_server (cci_identifier_t in_identifier, 182 cci_uuid_string_t in_server_id, 183 cc_uint32 *out_is_for_server) 184 { 185 cc_int32 err = ccNoError; 186 187 if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } 188 if (!in_server_id ) { err = cci_check_error (ccErrBadParam); } 189 if (!out_is_for_server) { err = cci_check_error (ccErrBadParam); } 190 191 if (!err) { 192 *out_is_for_server = (!strcmp (in_identifier->server_id, in_server_id) || 193 !strcmp (in_identifier->server_id, cci_uninitialized_server_id)); 194 } 195 196 return cci_check_error (err); 197 } 198 199 /* ------------------------------------------------------------------------ */ 200 201 cc_int32 cci_identifier_compare_server_id (cci_identifier_t in_identifier, 202 cci_identifier_t in_compare_to_identifier, 203 cc_uint32 *out_equal_server_id) 204 { 205 cc_int32 err = ccNoError; 206 207 if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } 208 if (!in_compare_to_identifier) { err = cci_check_error (ccErrBadParam); } 209 if (!out_equal_server_id ) { err = cci_check_error (ccErrBadParam); } 210 211 if (!err) { 212 *out_equal_server_id = (!strcmp (in_identifier->server_id, 213 in_compare_to_identifier->server_id)); 214 } 215 216 return cci_check_error (err); 217 } 218 219 /* ------------------------------------------------------------------------ */ 220 221 cc_int32 cci_identifier_is_initialized (cci_identifier_t in_identifier, 222 cc_uint32 *out_is_initialized) 223 { 224 cc_int32 err = ccNoError; 225 226 if (!in_identifier ) { err = cci_check_error (ccErrBadParam); } 227 if (!out_is_initialized) { err = cci_check_error (ccErrBadParam); } 228 229 if (!err) { 230 *out_is_initialized = (strcmp (in_identifier->server_id, 231 cci_uninitialized_server_id) != 0); 232 } 233 234 return cci_check_error (err); 235 } 236 237 #ifdef TARGET_OS_MAC 238 #pragma mark - 239 #endif 240 241 /* ------------------------------------------------------------------------ */ 242 243 cc_uint32 cci_identifier_read (cci_identifier_t *out_identifier, 244 k5_ipc_stream io_stream) 245 { 246 cc_int32 err = ccNoError; 247 cci_uuid_string_t server_id = NULL; 248 cci_uuid_string_t object_id = NULL; 249 250 if (!out_identifier) { err = cci_check_error (ccErrBadParam); } 251 if (!io_stream ) { err = cci_check_error (ccErrBadParam); } 252 253 if (!err) { 254 err = krb5int_ipc_stream_read_string (io_stream, &server_id); 255 } 256 257 if (!err) { 258 err = krb5int_ipc_stream_read_string (io_stream, &object_id); 259 } 260 261 if (!err) { 262 err = cci_identifier_alloc (out_identifier, server_id, object_id); 263 } 264 265 krb5int_ipc_stream_free_string (server_id); 266 krb5int_ipc_stream_free_string (object_id); 267 268 return cci_check_error (err); 269 } 270 271 /* ------------------------------------------------------------------------ */ 272 273 cc_uint32 cci_identifier_write (cci_identifier_t in_identifier, 274 k5_ipc_stream io_stream) 275 { 276 cc_int32 err = ccNoError; 277 278 if (!in_identifier) { err = cci_check_error (ccErrBadParam); } 279 if (!io_stream ) { err = cci_check_error (ccErrBadParam); } 280 281 if (!err) { 282 err = krb5int_ipc_stream_write_string (io_stream, in_identifier->server_id); 283 } 284 285 if (!err) { 286 err = krb5int_ipc_stream_write_string (io_stream, in_identifier->object_id); 287 } 288 289 return cci_check_error (err); 290 } 291