getproto.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Copyright (C) 2010 Bernhard Reutner-Fischer <uclibc@uclibc.org>
  4. *
  5. * Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
  6. */
  7. /* /etc/protocols
  8. # protocol-name number [aliases ...]
  9. ip 0 IP # internet protocol, pseudo protocol number
  10. protocol-name: case sensitive friendly name of the IP protocol
  11. number: decimal protocol number
  12. aliases: case sensitive optional space or tab separated list of other names
  13. */
  14. #include <features.h>
  15. #include <netdb.h>
  16. #include <string.h>
  17. #include <stdlib.h>
  18. #include <netinet/in.h>
  19. #include <arpa/inet.h>
  20. #include <errno.h>
  21. #include <unistd.h>
  22. #include "internal/parse_config.h"
  23. #include <bits/uClibc_mutex.h>
  24. __UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
  25. #define MAXALIASES 35
  26. #define BUFSZ (80) /* one line */
  27. #define SBUFSIZE (BUFSZ + 1 + (sizeof(char *) * MAXALIASES))
  28. static parser_t *protop = NULL;
  29. static struct protoent protoe;
  30. static char *protobuf = NULL;
  31. static smallint proto_stayopen;
  32. void setprotoent(int stayopen)
  33. {
  34. __UCLIBC_MUTEX_LOCK(mylock);
  35. if (protop)
  36. config_close(protop);
  37. protop = config_open(_PATH_PROTOCOLS);
  38. if (stayopen)
  39. proto_stayopen = 1;
  40. __UCLIBC_MUTEX_UNLOCK(mylock);
  41. }
  42. libc_hidden_def(setprotoent)
  43. void endprotoent(void)
  44. {
  45. __UCLIBC_MUTEX_LOCK(mylock);
  46. if (protop) {
  47. config_close(protop);
  48. protop = NULL;
  49. }
  50. proto_stayopen = 0;
  51. __UCLIBC_MUTEX_UNLOCK(mylock);
  52. }
  53. libc_hidden_def(endprotoent)
  54. int getprotoent_r(struct protoent *result_buf,
  55. char *buf, size_t buflen, struct protoent **result)
  56. {
  57. char **alias, *cp = NULL;
  58. char **proto_aliases;
  59. char **tok = NULL;
  60. const size_t aliaslen = sizeof(*proto_aliases) * MAXALIASES;
  61. int ret = ERANGE;
  62. *result = NULL;
  63. if (buflen < aliaslen
  64. || (buflen - aliaslen) < BUFSZ + 1)
  65. goto DONE_NOUNLOCK;
  66. __UCLIBC_MUTEX_LOCK(mylock);
  67. //tok = (char **) buf;
  68. ret = ENOENT;
  69. if (protop == NULL)
  70. setprotoent(proto_stayopen);
  71. if (protop == NULL)
  72. goto DONE;
  73. protop->data = buf;
  74. protop->data_len = aliaslen;
  75. protop->line_len = buflen - aliaslen;
  76. /* <name>[[:space:]]<protonumber>[[:space:]][<aliases>] */
  77. if (!config_read(protop, &tok, 3, 2, "# \t/", PARSE_NORMAL)) {
  78. goto DONE;
  79. }
  80. result_buf->p_name = *(tok++);
  81. result_buf->p_proto = atoi(*(tok++));
  82. result_buf->p_aliases = alias = proto_aliases = tok;
  83. cp = *alias;
  84. while (cp && *cp) {
  85. if (alias < &proto_aliases[MAXALIASES - 1])
  86. *alias++ = cp;
  87. cp = strpbrk(cp, " \t");
  88. if (cp != NULL)
  89. *cp++ = '\0';
  90. }
  91. *alias = NULL;
  92. *result = result_buf;
  93. ret = 0;
  94. DONE:
  95. __UCLIBC_MUTEX_UNLOCK(mylock);
  96. DONE_NOUNLOCK:
  97. errno = ret;
  98. return errno;
  99. }
  100. libc_hidden_def(getprotoent_r)
  101. static void __initbuf(void)
  102. {
  103. if (!protobuf) {
  104. protobuf = malloc(SBUFSIZE);
  105. if (!protobuf)
  106. abort();
  107. }
  108. }
  109. struct protoent *getprotoent(void)
  110. {
  111. struct protoent *result;
  112. __initbuf();
  113. getprotoent_r(&protoe, protobuf, SBUFSIZE, &result);
  114. return result;
  115. }
  116. int getprotobyname_r(const char *name,
  117. struct protoent *result_buf, char *buf, size_t buflen,
  118. struct protoent **result)
  119. {
  120. register char **cp;
  121. int ret;
  122. __UCLIBC_MUTEX_LOCK(mylock);
  123. setprotoent(proto_stayopen);
  124. while (!(ret = getprotoent_r(result_buf, buf, buflen, result))) {
  125. if (strcmp(name, result_buf->p_name) == 0)
  126. break;
  127. for (cp = result_buf->p_aliases; *cp; cp++)
  128. if (strcmp(name, *cp) == 0)
  129. goto gotname;
  130. }
  131. gotname:
  132. if (!proto_stayopen)
  133. endprotoent();
  134. __UCLIBC_MUTEX_UNLOCK(mylock);
  135. return *result ? 0 : ret;
  136. }
  137. libc_hidden_def(getprotobyname_r)
  138. struct protoent *getprotobyname(const char *name)
  139. {
  140. struct protoent *result;
  141. __initbuf();
  142. getprotobyname_r(name, &protoe, protobuf, SBUFSIZE, &result);
  143. return result;
  144. }
  145. int getprotobynumber_r(int proto,
  146. struct protoent *result_buf, char *buf,
  147. size_t buflen, struct protoent **result)
  148. {
  149. int ret;
  150. __UCLIBC_MUTEX_LOCK(mylock);
  151. setprotoent(proto_stayopen);
  152. while (!(ret = getprotoent_r(result_buf, buf, buflen, result))) {
  153. if (proto == result_buf->p_proto)
  154. break;
  155. }
  156. if (!proto_stayopen)
  157. endprotoent();
  158. __UCLIBC_MUTEX_UNLOCK(mylock);
  159. return *result ? 0 : ret;
  160. }
  161. libc_hidden_def(getprotobynumber_r)
  162. struct protoent *getprotobynumber(int proto)
  163. {
  164. struct protoent *result;
  165. __initbuf();
  166. getprotobynumber_r(proto, &protoe, protobuf, SBUFSIZE, &result);
  167. return result;
  168. }