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