Changed to using rfc2553 name resolution for http
[ntk/apt.git] / methods / rfc2553emu.cc
CommitLineData
934b6582
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
3// $Id: rfc2553emu.cc,v 1.1 1999/05/25 05:56:24 jgg Exp $
4/* ######################################################################
5
6 RFC 2553 Emulation - Provides emulation for RFC 2553 getaddrinfo,
7 freeaddrinfo and getnameinfo
8
9 Originally written by Jason Gunthorpe <jgg@debian.org> and placed into
10 the Public Domain, do with it what you will.
11
12 ##################################################################### */
13 /*}}}*/
14#include "rfc2553emu.h"
15#include <stdlib.h>
16#include <arpa/inet.h>
17#include <iostream.h>
18
19#ifndef HAVE_GETADDRINFO
20int getaddrinfo(const char *nodename, const char *servname,
21 const struct addrinfo *hints,
22 struct addrinfo **res)
23{
24 struct addrinfo **Result;
25 hostent *Addr;
26 unsigned int Port;
27 int Proto;
28 const char *End;
29 char **CurAddr;
30
31 Addr = gethostbyname(nodename);
32 if (Addr == 0)
33 {
34 if (h_errno == TRY_AGAIN)
35 return EAI_AGAIN;
36 if (h_errno == NO_RECOVERY)
37 return EAI_FAIL;
38 return EAI_NONAME;
39 }
40
41 // No A records
42 if (Addr->h_addr_list[0] == 0)
43 return EAI_NONAME;
44
45 // Try to convert the service as a number
46 Port = htons(strtol(servname,(char **)&End,0));
47 Proto = SOCK_STREAM;
48
49 if (hints != 0 && hints->ai_socktype != 0)
50 Proto = hints->ai_socktype;
51
52 // Not a number, must be a name.
53 if (End != servname + strlen(End))
54 {
55 struct servent *Srv = 0;
56
57 // Do a lookup in the service database
58 if (hints == 0 || hints->ai_socktype == SOCK_STREAM)
59 Srv = getservbyname(servname,"tcp");
60 if (hints != 0 && hints->ai_socktype == SOCK_DGRAM)
61 Srv = getservbyname(servname,"udp");
62 if (Srv == 0)
63 return EAI_NONAME;
64
65 // Get the right protocol
66 Port = Srv->s_port;
67 if (strcmp(Srv->s_proto,"tcp") == 0)
68 Proto = SOCK_STREAM;
69 else
70 {
71 if (strcmp(Srv->s_proto,"udp") == 0)
72 Proto = SOCK_DGRAM;
73 else
74 return EAI_NONAME;
75 }
76
77 if (hints != 0 && hints->ai_socktype != Proto &&
78 hints->ai_socktype != 0)
79 return EAI_SERVICE;
80 }
81
82 // Start constructing the linked list
83 *res = 0;
84 for (CurAddr = Addr->h_addr_list; *CurAddr != 0; CurAddr++)
85 {
86 // New result structure
87 *Result = (struct addrinfo *)calloc(sizeof(**Result),1);
88 if (*Result == 0)
89 {
90 freeaddrinfo(*res);
91 return EAI_MEMORY;
92 }
93 if (*res == 0)
94 *res = *Result;
95
96 (*Result)->ai_family = AF_INET;
97 (*Result)->ai_socktype = Proto;
98
99 // If we have the IPPROTO defines we can set the protocol field
100 #ifdef IPPROTO_TCP
101 if (Proto == SOCK_STREAM)
102 (*Result)->ai_protocol = IPPROTO_TCP;
103 if (Proto == SOCK_DGRAM)
104 (*Result)->ai_protocol = IPPROTO_UDP;
105 #endif
106
107 // Allocate space for the address
108 (*Result)->ai_addrlen = sizeof(struct sockaddr_in);
109 (*Result)->ai_addr = (struct sockaddr *)calloc(sizeof(sockaddr_in),1);
110 if ((*Result)->ai_addr == 0)
111 {
112 freeaddrinfo(*res);
113 return EAI_MEMORY;
114 }
115
116 // Set the address
117 ((struct sockaddr_in *)(*Result)->ai_addr)->sin_family = AF_INET;
118 ((struct sockaddr_in *)(*Result)->ai_addr)->sin_port = Port;
119 ((struct sockaddr_in *)(*Result)->ai_addr)->sin_addr = *(in_addr *)(*CurAddr);
120
121 Result = &(*Result)->ai_next;
122 }
123
124 return 0;
125}
126
127void freeaddrinfo(struct addrinfo *ai)
128{
129 struct addrinfo *Tmp;
130 while (ai != 0)
131 {
132 free(ai->ai_addr);
133 Tmp = ai;
134 ai = ai->ai_next;
135 free(ai);
136 }
137}
138
139#endif // HAVE_GETADDRINFO