(root)/
glibc-2.38/
hesiod/
nss_hesiod/
hesiod-proto.c
       1  /* Copyright (C) 1997-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <errno.h>
      19  #include <hesiod.h>
      20  #include <netdb.h>
      21  #include <netinet/in.h>
      22  #include <nss.h>
      23  #include <stdio.h>
      24  #include <stdlib.h>
      25  #include <string.h>
      26  
      27  NSS_DECLARE_MODULE_FUNCTIONS (hesiod)
      28  
      29  /* Declare a parser for Hesiod protocol entries.  Although the format
      30     of the entries is identical to those in /etc/protocols, here is no
      31     predefined parser for us to use.  */
      32  
      33  #define ENTNAME protoent
      34  
      35  struct protoent_data {};
      36  
      37  #define TRAILING_LIST_MEMBER		p_aliases
      38  #define TRAILING_LIST_SEPARATOR_P	isspace
      39  #include <nss/nss_files/files-parse.c>
      40  LINE_PARSER
      41  ("#",
      42   STRING_FIELD (result->p_name, isspace, 1);
      43   INT_FIELD (result->p_proto, isspace, 1, 10,);
      44   )
      45  
      46  enum nss_status
      47  _nss_hesiod_setprotoent (int stayopen)
      48  {
      49    return NSS_STATUS_SUCCESS;
      50  }
      51  
      52  enum nss_status
      53  _nss_hesiod_endprotoent (void)
      54  {
      55    return NSS_STATUS_SUCCESS;
      56  }
      57  
      58  static enum nss_status
      59  lookup (const char *name, const char *type, struct protoent *proto,
      60  	char *buffer, size_t buflen, int *errnop)
      61  {
      62    struct parser_data *data = (void *) buffer;
      63    size_t linebuflen;
      64    void *context;
      65    char **list, **item;
      66    int parse_res;
      67    int found;
      68    int olderr = errno;
      69  
      70    if (hesiod_init (&context) < 0)
      71      return NSS_STATUS_UNAVAIL;
      72  
      73    list = hesiod_resolve (context, name, type);
      74    if (list == NULL)
      75      {
      76        int err = errno;
      77        hesiod_end (context);
      78        __set_errno (olderr);
      79        return err == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL;
      80      }
      81  
      82    linebuflen = buffer + buflen - data->linebuffer;
      83  
      84    item = list;
      85    found = 0;
      86    do
      87      {
      88        size_t len = strlen (*item) + 1;
      89  
      90        if (linebuflen < len)
      91  	{
      92  	  hesiod_free_list (context, list);
      93  	  hesiod_end (context);
      94  	  *errnop = ERANGE;
      95  	  return NSS_STATUS_TRYAGAIN;
      96  	}
      97  
      98        memcpy (data->linebuffer, *item, len);
      99  
     100        parse_res = parse_line (buffer, proto, data, buflen, errnop);
     101        if (parse_res == -1)
     102  	{
     103  	  hesiod_free_list (context, list);
     104  	  hesiod_end (context);
     105  	  return NSS_STATUS_TRYAGAIN;
     106  	}
     107  
     108        if (parse_res > 0)
     109  	found = 1;
     110  
     111        ++item;
     112      }
     113    while (*item != NULL && !found);
     114  
     115    hesiod_free_list (context, list);
     116    hesiod_end (context);
     117  
     118    if (found == 0)
     119      {
     120        __set_errno (olderr);
     121        return NSS_STATUS_NOTFOUND;
     122      }
     123  
     124    return NSS_STATUS_SUCCESS;
     125  }
     126  
     127  enum nss_status
     128  _nss_hesiod_getprotobyname_r (const char *name, struct protoent *proto,
     129  			      char *buffer, size_t buflen, int *errnop)
     130  {
     131    return lookup (name, "protocol", proto, buffer, buflen, errnop);
     132  }
     133  
     134  enum nss_status
     135  _nss_hesiod_getprotobynumber_r (const int protocol, struct protoent *proto,
     136  				char *buffer, size_t buflen, int *errnop)
     137  {
     138    char protostr[21];
     139  
     140    snprintf (protostr, sizeof protostr, "%d", protocol);
     141  
     142    return lookup (protostr, "protonum", proto, buffer, buflen, errnop);
     143  }