1 /* Copyright 1996 by the Massachusetts Institute of Technology.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions
5 * are met:
6 *
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 *
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26 * OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /* This file is part of the Hesiod library. It implements
30 * backward-compatibility interfaces.
31 */
32
33 static const char rcsid[] = "$Id: hescompat.c,v 1.3 1999-10-23 19:29:15 danw Exp $";
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <errno.h>
38 #include "hesiod.h"
39
40 static int inited = 0;
41 static void *context;
42 static char *bindname, **list;
43 static struct passwd *pw;
44 static struct servent *serv;
45 static struct hesiod_postoffice *po;
46 static struct hes_postoffice compatpo;
47 static int errval = HES_ER_UNINIT;
48
49 static int init_context(void);
50 static void translate_errors(void);
51
hes_init(void)52 int hes_init(void)
53 {
54 init_context();
55 return errval;
56 }
57
hes_to_bind(const char * name,const char * type)58 char *hes_to_bind(const char *name, const char *type)
59 {
60 if (init_context() < 0)
61 return NULL;
62 if (bindname)
63 free(bindname);
64 bindname = hesiod_to_bind(context, name, type);
65 if (!bindname)
66 translate_errors();
67 return bindname;
68 }
69
hes_resolve(const char * name,const char * type)70 char **hes_resolve(const char *name, const char *type)
71 {
72 if (init_context() < 0)
73 return NULL;
74
75 /* In the old Hesiod interface, the caller was responsible for freeing
76 * the returned strings but not the vector of strings itself.
77 */
78 if (list)
79 free(list);
80
81 list = hesiod_resolve(context, name, type);
82 if (!list)
83 translate_errors();
84 return list;
85 }
86
hes_error(void)87 int hes_error(void)
88 {
89 return errval;
90 }
91
hes_getpwnam(const char * name)92 struct passwd *hes_getpwnam(const char *name)
93 {
94 if (init_context() < 0)
95 return NULL;
96 if (pw)
97 hesiod_free_passwd(context, pw);
98 pw = hesiod_getpwnam(context, name);
99 if (!pw)
100 translate_errors();
101 return pw;
102 }
103
hes_getpwuid(uid_t uid)104 struct passwd *hes_getpwuid(uid_t uid)
105 {
106 if (init_context() < 0)
107 return NULL;
108 if (pw)
109 hesiod_free_passwd(context, pw);
110 pw = hesiod_getpwuid(context, uid);
111 if (!pw)
112 translate_errors();
113 return pw;
114 }
115
hes_getservbyname(const char * name,const char * proto)116 struct servent *hes_getservbyname(const char *name, const char *proto)
117 {
118 if (init_context() < 0)
119 return NULL;
120 if (serv)
121 hesiod_free_servent(context, serv);
122 serv = hesiod_getservbyname(context, name, proto);
123 if (!serv)
124 translate_errors();
125 return serv;
126 }
127
hes_getmailhost(const char * name)128 struct hes_postoffice *hes_getmailhost(const char *name)
129 {
130 if (init_context() < 0)
131 return NULL;
132 if (po)
133 hesiod_free_postoffice(context, po);
134 po = hesiod_getmailhost(context, name);
135 if (!po)
136 {
137 translate_errors();
138 return NULL;
139 }
140 compatpo.po_type = po->hesiod_po_type;
141 compatpo.po_host = po->hesiod_po_host;
142 compatpo.po_name = po->hesiod_po_name;
143 return &compatpo;
144 }
145
init_context(void)146 static int init_context(void)
147 {
148 if (!inited)
149 {
150 inited = 1;
151 if (hesiod_init(&context) < 0)
152 {
153 errval = HES_ER_CONFIG;
154 return -1;
155 }
156 errval = HES_ER_OK;
157 }
158 return 0;
159 }
160
translate_errors(void)161 static void translate_errors(void)
162 {
163 switch (errno)
164 {
165 case ENOENT:
166 errval = HES_ER_NOTFOUND;
167 break;
168 case ECONNREFUSED:
169 case EMSGSIZE:
170 errval = HES_ER_NET;
171 break;
172 case ENOMEM:
173 default:
174 /* Not a good match, but the best we can do. */
175 errval = HES_ER_CONFIG;
176 break;
177 }
178 }
179