*** empty log message ***
[krb5.git] / src / lib / krb5 / krb / bld_princ.c
1 /*
2  * $Source$
3  * $Author$
4  *
5  * Copyright 1991 by the Massachusetts Institute of Technology.
6  * All Rights Reserved.
7  *
8  * For copying and distribution information, please see the file
9  * <krb5/copyright.h>.
10  *
11  * Build a principal from a list of strings
12  */
13
14 #if !defined(lint) && !defined(SABER)
15 static char rcsid_bld_princ_c [] =
16 "$Id$";
17 #endif  /* !lint & !SABER */
18
19 #include <krb5/krb5.h>
20 #include <krb5/ext-proto.h>
21
22 #ifdef __STDC__
23 #include <stdarg.h>
24 #else
25 #include <varargs.h>
26 #endif
27
28 krb5_error_code
29 #ifdef __STDC__
30 krb5_build_principal(krb5_principal *princ, int rlen, const char *realm, ...)
31 #else
32 krb5_build_principal(princ, rlen, realm, va_alist)
33 krb5_principal *princ;
34 int rlen;
35 const char *realm;
36 va_dcl
37 #endif
38 {
39     va_list ap;
40     krb5_error_code retval;
41
42 #ifdef __STDC__
43     va_start(ap, realm);
44 #else
45     va_start(ap);
46 #endif
47     retval = krb5_build_principal_va(princ, realm, ap);
48     va_end(ap);
49     return retval;
50 }
51
52 krb5_error_code
53 krb5_build_principal_va(princ, rlen, realm, ap)
54 krb5_principal *princ;
55 int rlen;
56 const char *realm;
57 va_list ap;
58 {
59     register int i, count = 0;
60     register char *next;
61     krb5_principal princ_ret;
62
63     /* guess at an initial sufficent count of 2 pieces */
64     count = 2 + 2;              /* plus 2 for realm & null terminator */
65
66     /* get space for array and realm, and insert realm */
67     princ_ret = (krb5_principal) malloc(sizeof(*princ_ret) * (count));
68     if (!princ_ret)
69         return ENOMEM;
70     if (!(princ_ret[0] = (krb5_data *) malloc(sizeof(*princ_ret[0])))) {
71         xfree(princ_ret);
72         return ENOMEM;
73     }
74     princ_ret[0]->length = rlen;
75     princ_ret[0]->data = malloc(rlen);
76     if (!princ_ret[0]->data) {
77         xfree(princ_ret[0]);
78         xfree(princ_ret);
79         return ENOMEM;
80     }
81     memcpy(princ_ret[0]->data, realm, rlen);
82
83     /* process rest of components */
84
85     for (i = 1, next = va_arg(ap, char *);
86          next;
87          next = va_arg(ap, char *), i++) {
88         if (i == count-1) {
89             /* not big enough.  realloc the array */
90             krb5_principal p_tmp;
91             p_tmp = (krb5_principal) realloc((char *)princ_ret, sizeof(*princ_ret)*(count*2));
92             if (!p_tmp)
93                 goto free_out;
94             princ_ret = p_tmp;
95             count *= 2;
96         }
97         if (!(princ_ret[i] =
98               (krb5_data *) malloc(sizeof(*princ_ret[i])))) {
99         free_out:
100             for (i--; i >= 0; i--) {
101                 xfree(princ_ret[i]->data);
102                 xfree(princ_ret[i]);
103             }
104             xfree(princ_ret);
105             return (ENOMEM);
106         }
107         princ_ret[i]->length = strlen(next);
108         princ_ret[i]->data = strdup(next);
109         if (!princ_ret[i]->data) {
110             xfree(princ_ret[i]);
111             goto free_out;
112         }
113     }
114     princ_ret[i] = 0;                   /* put a null as the last entry */
115     *princ = princ_ret;
116     return 0;
117 }