getproto.c 4.1 KB

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