1 /* gcc -O2 -Wall -W -pthread -o bind_pthread -c bind_pthread.c */
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <pthread.h>
5 #include <stdlib.h>
6 #include <netdb.h>
7 #include <string.h>
8 #include <err.h>
9 #include <errno.h>
10 
11 volatile int stop = 0;
12 
13 #define IP2INT(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) <<  8) | (d))
14 #define INT2IP(x)        \
15     ((x) >> 24) & 0xFF,  \
16     ((x) >> 16) & 0xFF,  \
17     ((x) >>  8) & 0xFF,  \
18     ((x) >>  0) & 0xFF
19 #define INT2IP_REV(x)    \
20     ((x) >>  0) & 0xFF,  \
21     ((x) >>  8) & 0xFF,  \
22     ((x) >> 16) & 0xFF,  \
23     ((x) >> 24) & 0xFF
24 
in_ptr(unsigned int ip)25 static void in_ptr(unsigned int ip)
26 {
27  int ern;
28  char rbuf[1024];
29  struct hostent rres, *hent;
30 
31  ip = htonl(ip);
32  if (gethostbyaddr_r((char *)&ip, 4, AF_INET, &rres, rbuf, sizeof(rbuf),
33                      &hent, &ern) != 0)
34    hent = NULL;
35  ip = ntohl(ip);
36 
37  flockfile(stdout);
38  if (!hent)
39    printf("%u.%u.%u.%u.in-addr.arpa. IN.PTR:ret=3#NAME\n", INT2IP_REV(ip));
40  else
41    printf("%u.%u.%u.%u.in-addr.arpa. IN.PTR %s\n",
42           INT2IP_REV(ip), hent->h_name);
43  fflush(stdout);
44  funlockfile(stdout);
45 }
46 
in_a(const char * buf)47 static void in_a(const char *buf)
48 {
49  int ern;
50  char rbuf[1024];
51  struct hostent rres, *hent;
52 
53  if (gethostbyname_r(buf, &rres, rbuf, sizeof(rbuf), &hent, &ern) != 0)
54    hent = NULL;
55 
56  flockfile(stdout);
57  if (!hent)
58    printf("%s. IN.A:ret=3#NAME\n", buf);
59  else
60  {
61    unsigned int ip = *(unsigned int *)hent->h_addr_list[0];
62 
63    ip = ntohl(ip);
64    printf("%s. IN.A %u.%u.%u.%u\n", hent->h_name, INT2IP_REV(ip));
65  }
66 
67  fflush(stdout);
68  funlockfile(stdout);
69 }
70 
threadfunc(void * ctx)71 static void *threadfunc(void *ctx)
72 {
73   char buf[1024];
74 
75   flockfile(stdin);
76   while (!feof(stdin) && fgets(buf, sizeof(buf), stdin))
77   {
78     unsigned int a, b, c, d;
79 
80     funlockfile(stdin);
81 
82     if (buf[0] && (buf[strlen(buf) - 1] == '\n'))
83       buf[strlen(buf) - 1] = 0;
84 
85     if (0) { }
86     else if (sscanf(buf, "in.ptr %u.%u.%u.%u", &a, &b, &c, &d) == 4)
87       in_ptr(IP2INT(a, b, c, d));
88     else if ((strlen(buf) > strlen("in.a ")) &&
89              !memcmp(buf, "in.a ", strlen("in.a ")))
90     {
91       char *ptr = buf;
92 
93       ptr += strlen("in.a ");
94       ptr += strspn(ptr, " ");
95 
96       in_a(ptr);
97     }
98     else
99       return (ctx);
100 
101     flockfile(stdin);
102   }
103   funlockfile(stdin);
104 
105   return (NULL);
106 }
107 
108 #define EQ(x, y) (strcmp(x, y) == 0)
109 
main(int argc,char * argv[])110 int main(int argc, char *argv[])
111 {
112   unsigned int nr_thrd = 1;
113   pthread_t *a;
114   unsigned int i;
115   void *ret = NULL;
116 
117   if ((argc == 3) &&
118       EQ(argv[1], "-c"))
119     nr_thrd = atoi(argv[2]);
120 
121   a = calloc(nr_thrd, sizeof(pthread_t));
122   if (!a)
123     errno = ENOMEM, err(EXIT_FAILURE, "init");
124 
125   for (i = 0; i < nr_thrd; i++)
126     pthread_create(a + i, NULL, threadfunc, a + i);
127 
128   for (i = 0; i < nr_thrd; i++)
129     pthread_join(a[i], &ret);
130 
131   exit (EXIT_SUCCESS);
132 }
133