Updates for move of net apps to rosapps
[reactos.git] / reactos / apps / utils / net / ncftp / sio / StrAddr.c
1 #include "syshdrs.h"
2
3 #ifndef INADDR_ANY
4 # define INADDR_ANY ((unsigned long int) 0x00000000)
5 #endif
6
7 #ifndef INADDR_NONE
8 # define INADDR_NONE ((unsigned long int) 0xffffffff)
9 #endif
10
11 /* Linux libc 5.3.x has a bug that causes isalnum() to not work! */
12 #define ISALNUM(c) ( (((c) >= 'A') && ((c) <= 'Z')) || (((c) >= 'a') && ((c) <= 'z')) || (((c) >= '0') && ((c) <= '9')) )
13
14 static unsigned int
15 ServiceNameToPortNumber(const char *const s)
16 {
17 char str[64];
18 char *cp;
19 struct servent *sp;
20
21 strncpy(str, s, sizeof(str) - 1);
22 str[sizeof(str) - 1] = '\0';
23 cp = str;
24 if (isdigit(*cp)) {
25 while (isdigit(*cp))
26 cp++;
27 *cp = '\0';
28 return (atoi(str));
29 }
30 for (;; cp++) {
31 if ((*cp == '\0')
32 || ((!ISALNUM(*cp)) && (*cp != '-') && (*cp != '_')))
33 break;
34 }
35 *cp = '\0';
36
37 sp = getservbyname(str, "tcp");
38 if (sp != NULL) {
39 /* endservent(); */
40 return ((unsigned int) ntohs((unsigned short) sp->s_port));
41 }
42 sp = getservbyname(str, "udp");
43 if (sp != NULL) {
44 /* endservent(); */
45 return ((unsigned int) ntohs((unsigned short) sp->s_port));
46 }
47 return (0); /* error */
48 } /* ServiceNameToPortNumber */
49
50
51
52
53 int
54 AddrStrToAddr(const char * const s, struct sockaddr_in * const sa, const int defaultport)
55 {
56 char portstr[128];
57 unsigned long ipnum;
58 unsigned int port;
59 struct hostent *hp;
60 char *hostcp, *atsign, *colon, *cp, *p2;
61
62 memset(sa, 0, sizeof(struct sockaddr_in));
63 strncpy(portstr, s, sizeof(portstr));
64 portstr[sizeof(portstr) - 1] = '\0';
65
66 if ((colon = strchr(portstr, ':')) != NULL) {
67 /* Does it look like a URL? http://host ? */
68 if ((colon[1] == '/') && (colon[2] == '/')) {
69 *colon = '\0';
70 port = 0;
71 hostcp = colon + 3;
72 for (cp = hostcp; *cp != '\0'; cp++) {
73 if ((!ISALNUM(*cp)) && (*cp != '.')) {
74 /* http://host:port */
75 if ((*cp == ':') && (isdigit(cp[1]))) {
76 *cp++ = '\0';
77 p2 = cp;
78 while (isdigit(*cp))
79 cp++;
80 *cp = '\0';
81 port = atoi(p2);
82 }
83 *cp = '\0';
84 break;
85 }
86 }
87 if (port == 0)
88 port = ServiceNameToPortNumber(portstr);
89 } else {
90 /* Look for host.name.domain:port */
91 *colon = '\0';
92 hostcp = portstr;
93 port = (unsigned int) atoi(colon + 1);
94 }
95 } else if ((atsign = strchr(portstr, '@')) != NULL) {
96 /* Look for port@host.name.domain */
97 *atsign = '\0';
98 hostcp = atsign + 1;
99 port = (unsigned int) atoi(portstr);
100 } else if (defaultport > 0) {
101 /* Have just host.name.domain, use that w/ default port. */
102 port = (unsigned int) defaultport;
103 hostcp = portstr;
104 } else {
105 /* If defaultport <= 0, they must supply a port number
106 * in the host/port string.
107 */
108 errno = EADDRNOTAVAIL;
109 return (kAddrStrToAddrMiscErr);
110 }
111
112 sa->sin_port = htons((short) port);
113
114 ipnum = inet_addr(hostcp);
115 if (ipnum != INADDR_NONE) {
116 sa->sin_family = AF_INET;
117 sa->sin_addr.s_addr = ipnum;
118 } else {
119 errno = 0;
120 hp = gethostbyname(hostcp);
121 if (hp == NULL) {
122 if (errno == 0)
123 errno = ENOENT;
124 return (kAddrStrToAddrBadHost);
125 }
126 sa->sin_family = hp->h_addrtype;
127 memcpy(&sa->sin_addr.s_addr, hp->h_addr_list[0],
128 (size_t) hp->h_length);
129 }
130 return (0);
131 } /* AddrStrToAddr */
132
133
134
135 char *
136 AddrToAddrStr(char *const dst, size_t dsize, struct sockaddr_in * const saddrp, int dns, const char *fmt)
137 {
138 const char *addrNamePtr;
139 struct hostent *hp;
140 char str[128];
141 char *dlim, *dp;
142 const char *cp;
143 struct servent *pp;
144
145 if (dns == 0) {
146 addrNamePtr = inet_ntoa(saddrp->sin_addr);
147 } else {
148 hp = gethostbyaddr((char *) &saddrp->sin_addr, (int) sizeof(struct in_addr), AF_INET);
149 if ((hp != NULL) && (hp->h_name != NULL) && (hp->h_name[0] != '\0')) {
150 addrNamePtr = hp->h_name;
151 } else {
152 addrNamePtr = inet_ntoa(saddrp->sin_addr);
153 }
154 }
155 if (fmt == NULL)
156 fmt = "%h:%p";
157 for (dp = dst, dlim = dp + dsize - 1; ; fmt++) {
158 if (*fmt == '\0') {
159 break; /* done */
160 } else if (*fmt == '%') {
161 fmt++;
162 if (*fmt == '%') {
163 if (dp < dlim)
164 *dp++ = '%';
165 } else if (*fmt == 'p') {
166 sprintf(str, "%u", (unsigned int) ntohs(saddrp->sin_port));
167 for (cp = str; *cp != '\0'; cp++)
168 if (dp < dlim)
169 *dp++ = *cp;
170 *dp = '\0';
171 } else if (*fmt == 'h') {
172 if (addrNamePtr != NULL) {
173 cp = addrNamePtr;
174 } else {
175 cp = "unknown";
176 }
177 for ( ; *cp != '\0'; cp++)
178 if (dp < dlim)
179 *dp++ = *cp;
180 *dp = '\0';
181 } else if (*fmt == 's') {
182 pp = getservbyport((int) (saddrp->sin_port), "tcp");
183 if (pp == NULL)
184 pp = getservbyport((int) (saddrp->sin_port), "udp");
185 if (pp == NULL) {
186 sprintf(str, "%u", (unsigned int) ntohs(saddrp->sin_port));
187 cp = str;
188 } else {
189 cp = pp->s_name;
190 }
191 for ( ; *cp != '\0'; cp++)
192 if (dp < dlim)
193 *dp++ = *cp;
194 /* endservent(); */
195 *dp = '\0';
196 } else if ((*fmt == 't') || (*fmt == 'u')) {
197 pp = getservbyport((int) (saddrp->sin_port), (*fmt == 'u') ? "udp" : "tcp");
198 if (pp == NULL) {
199 sprintf(str, "%u", (unsigned int) ntohs(saddrp->sin_port));
200 cp = str;
201 } else {
202 cp = pp->s_name;
203 }
204 for ( ; *cp != '\0'; cp++)
205 if (dp < dlim)
206 *dp++ = *cp;
207 /* endservent(); */
208 *dp = '\0';
209 } else if (*fmt == '\0') {
210 break;
211 } else {
212 if (dp < dlim)
213 *dp++ = *fmt;
214 }
215 } else if (dp < dlim) {
216 *dp++ = *fmt;
217 }
218 }
219 *dp = '\0';
220 return (dst);
221 } /* AddrToAddrStr */