1 #pragma ident "%Z%%M% %I% %E% SMI" 2 /* 3 * lib/krb5/krb/copy_addrs.c 4 * 5 * Copyright 1990 by the Massachusetts Institute of Technology. 6 * All Rights Reserved. 7 * 8 * Export of this software from the United States of America may 9 * require a specific license from the United States Government. 10 * It is the responsibility of any person or organization contemplating 11 * export to obtain such a license before exporting. 12 * 13 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 14 * distribute this software and its documentation for any purpose and 15 * without fee is hereby granted, provided that the above copyright 16 * notice appear in all copies and that both that copyright notice and 17 * this permission notice appear in supporting documentation, and that 18 * the name of M.I.T. not be used in advertising or publicity pertaining 19 * to distribution of the software without specific, written prior 20 * permission. Furthermore if you modify this software you must label 21 * your software as modified software and not distribute it in such a 22 * fashion that it might be confused with the original M.I.T. software. 23 * M.I.T. makes no representations about the suitability of 24 * this software for any purpose. It is provided "as is" without express 25 * or implied warranty. 26 * 27 * 28 * krb5_copy_addresses() 29 */ 30 31 #include <k5-int.h> 32 33 /*ARGSUSED*/ 34 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 35 krb5_copy_addr(context, inad, outad) 36 krb5_context context; 37 const krb5_address FAR *inad; 38 krb5_address FAR * FAR *outad; 39 { 40 krb5_address FAR *tmpad; 41 42 if (!(tmpad = (krb5_address FAR *)malloc(sizeof(*tmpad)))) 43 return ENOMEM; 44 #ifdef HAVE_C_STRUCTURE_ASSIGNMENT 45 *tmpad = *inad; 46 #else 47 memcpy(tmpad, inad, sizeof(krb5_address)); 48 #endif 49 if (!(tmpad->contents = (krb5_octet *)malloc(inad->length))) { 50 krb5_xfree(tmpad); 51 return ENOMEM; 52 } 53 memcpy((char *)tmpad->contents, (char *)inad->contents, inad->length); 54 *outad = tmpad; 55 return 0; 56 } 57 58 /* 59 * Copy an address array, with fresh allocation. 60 */ 61 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 62 krb5_copy_addresses(context, inaddr, outaddr) 63 krb5_context context; 64 krb5_address FAR * const FAR * inaddr; 65 krb5_address FAR * FAR * FAR *outaddr; 66 { 67 krb5_error_code retval; 68 krb5_address ** tempaddr; 69 register int nelems = 0; 70 71 if (!inaddr) { 72 *outaddr = 0; 73 return 0; 74 } 75 76 while (inaddr[nelems]) nelems++; 77 78 /* one more for a null terminated list */ 79 if (!(tempaddr = (krb5_address **) calloc(nelems+1, sizeof(*tempaddr)))) 80 return ENOMEM; 81 82 for (nelems = 0; inaddr[nelems]; nelems++) { 83 retval = krb5_copy_addr(context, inaddr[nelems], &tempaddr[nelems]); 84 if (retval) { 85 krb5_free_addresses(context, tempaddr); 86 return retval; 87 } 88 } 89 90 *outaddr = tempaddr; 91 return 0; 92 } 93 94 #if 0 95 /* 96 * Append an address array, to another address array, with fresh allocation. 97 * Note that this function may change the value of *outaddr even if it 98 * returns failure, but it will not change the contents of the list. 99 */ 100 krb5_error_code 101 krb5_append_addresses(context, inaddr, outaddr) 102 krb5_context context; 103 krb5_address * const * inaddr; 104 krb5_address ***outaddr; 105 { 106 krb5_error_code retval; 107 krb5_address ** tempaddr; 108 krb5_address ** tempaddr2; 109 register int nelems = 0; 110 register int norigelems = 0; 111 112 if (!inaddr) 113 return 0; 114 115 tempaddr2 = *outaddr; 116 117 while (inaddr[nelems]) nelems++; 118 while (tempaddr2[norigelems]) norigelems++; 119 120 tempaddr = (krb5_address **) realloc((char *)*outaddr, 121 (nelems + norigelems + 1) * sizeof(*tempaddr)); 122 if (!tempaddr) 123 return ENOMEM; 124 125 /* The old storage has been freed. */ 126 *outaddr = tempaddr; 127 128 129 for (nelems = 0; inaddr[nelems]; nelems++) { 130 retval = krb5_copy_addr(context, inaddr[nelems], 131 &tempaddr[norigelems + nelems]); 132 if (retval) 133 goto cleanup; 134 } 135 136 tempaddr[norigelems + nelems] = 0; 137 return 0; 138 139 cleanup: 140 while (--nelems >= 0) 141 krb5_free_address(context, tempaddr[norigelems + nelems]); 142 143 /* Try to allocate a smaller amount of memory for *outaddr. */ 144 tempaddr = (krb5_address **) realloc((char *)tempaddr, 145 (norigelems + 1) * sizeof(*tempaddr)); 146 if (tempaddr) 147 *outaddr = tempaddr; 148 return retval; 149 } 150 #endif 151 152