Update copyright notices with scripts/update-copyrights
[glibc.git] / hesiod / nss_hesiod / hesiod-service.c
blob45bd14c9f57ed0c736675eab8511fbac3bb5e60e
1 /* Copyright (C) 1997-2014 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #include <errno.h>
20 #include <hesiod.h>
21 #include <netdb.h>
22 #include <netinet/in.h>
23 #include <nss.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
28 #include "nss_hesiod.h"
30 /* Hesiod uses a format for service entries that differs from the
31 traditional format. We therefore declare our own parser. */
33 #define ENTNAME servent
35 struct servent_data {};
37 #define TRAILING_LIST_MEMBER s_aliases
38 #define TRAILING_LIST_SEPARATOR_P isspace
39 #include <nss/nss_files/files-parse.c>
40 #define ISSC_OR_SPACE(c) ((c) == ';' || isspace (c))
41 LINE_PARSER
42 ("#",
43 STRING_FIELD (result->s_name, ISSC_OR_SPACE, 1);
44 STRING_FIELD (result->s_proto, ISSC_OR_SPACE, 1);
45 INT_FIELD (result->s_port, ISSC_OR_SPACE, 10, 0, htons);
48 enum nss_status
49 _nss_hesiod_setservent (int stayopen)
51 return NSS_STATUS_SUCCESS;
54 enum nss_status
55 _nss_hesiod_endservent (void)
57 return NSS_STATUS_SUCCESS;
60 static enum nss_status
61 lookup (const char *name, const char *type, const char *protocol,
62 struct servent *serv, char *buffer, size_t buflen, int *errnop)
64 struct parser_data *data = (void *) buffer;
65 size_t linebuflen;
66 void *context;
67 char **list, **item;
68 int parse_res;
69 int found;
70 int olderr = errno;
72 context = _nss_hesiod_init ();
73 if (context == NULL)
74 return NSS_STATUS_UNAVAIL;
76 list = hesiod_resolve (context, name, type);
77 if (list == NULL)
79 int err = errno;
80 hesiod_end (context);
81 __set_errno (olderr);
82 return err == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
85 linebuflen = buffer + buflen - data->linebuffer;
87 item = list;
88 found = 0;
91 size_t len = strlen (*item) + 1;
93 if (linebuflen < len)
95 hesiod_free_list (context, list);
96 hesiod_end (context);
97 *errnop = ERANGE;
98 return NSS_STATUS_TRYAGAIN;
101 memcpy (data->linebuffer, *item, len);
103 parse_res = parse_line (buffer, serv, data, buflen, errnop);
104 if (parse_res == -1)
106 hesiod_free_list (context, list);
107 hesiod_end (context);
108 return NSS_STATUS_TRYAGAIN;
111 if (parse_res > 0)
112 found = protocol == NULL || strcasecmp (serv->s_proto, protocol) == 0;
114 ++item;
116 while (*item != NULL && !found);
118 hesiod_free_list (context, list);
119 hesiod_end (context);
121 if (found == 0)
123 __set_errno (olderr);
124 return NSS_STATUS_NOTFOUND;
127 return NSS_STATUS_SUCCESS;
130 enum nss_status
131 _nss_hesiod_getservbyname_r (const char *name, const char *protocol,
132 struct servent *serv,
133 char *buffer, size_t buflen, int *errnop)
135 return lookup (name, "service", protocol, serv, buffer, buflen, errnop);
138 enum nss_status
139 _nss_hesiod_getservbyport_r (const int port, const char *protocol,
140 struct servent *serv,
141 char *buffer, size_t buflen, int *errnop)
143 char portstr[6]; /* Port numbers are restricted to 16 bits. */
145 snprintf (portstr, sizeof portstr, "%d", ntohs (port));
147 return lookup (portstr, "port", protocol, serv, buffer, buflen, errnop);