7 /* split string into host and port, destroy string
9 /* #include <host_port.h>
11 /* const char *host_port(string, host, def_host, port, def_service)
18 /* host_port() splits a string into substrings with the host
19 /* name or address, and the service name or port number.
20 /* The input string is modified.
22 /* The following input formats are understood (null means
23 /* a null pointer argument):
25 /* When def_service is not null, and def_host is null:
27 /* [host]:port, [host]:, [host]
29 /* host:port, host:, host
31 /* When def_host is not null, and def_service is null:
35 /* Other combinations of def_service and def_host are
36 /* not supported and produce undefined results.
38 /* The result is a null pointer in case of success.
39 /* In case of problems the result is a string pointer with
44 /* Typical client usage allows the user to omit the service port,
45 /* in which case the client connects to a pre-determined default
50 /* buf = mystrdup(endpoint);
51 /* if ((parse_error = host_port(buf, &host, NULL, &port, defport)) != 0)
52 /* msg_fatal("%s in \"%s\"", parse_error, endpoint);
53 /* if ((aierr = hostname_to_sockaddr(host, port, SOCK_STREAM, &res)) != 0)
54 /* msg_fatal("%s: %s", endpoint, MAI_STRERROR(aierr));
59 /* Typical server usage allows the user to omit the host, meaning
60 /* listen on all available network addresses:
64 /* buf = mystrdup(endpoint);
65 /* if ((parse_error = host_port(buf, &host, "", &port, NULL)) != 0)
66 /* msg_fatal("%s in \"%s\"", parse_error, endpoint);
69 /* if ((aierr = hostname_to_sockaddr(host, port, SOCK_STREAM, &res)) != 0)
70 /* msg_fatal("%s: %s", endpoint, MAI_STRERROR(aierr));
75 /* The Secure Mailer license must be distributed with this software.
78 /* IBM T.J. Watson Research
80 /* Yorktown Heights, NY 10598, USA
89 /* Utility library. */
93 #include <stringops.h>
94 #include <valid_hostname.h>
98 #include <host_port.h>
100 /* host_port - parse string into host and port, destroy string */
102 const char *host_port(char *buf
, char **host
, char *def_host
,
103 char **port
, char *def_service
)
108 * [host]:port, [host]:, [host].
112 if ((cp
= split_at(cp
, ']')) == 0)
113 return ("missing \"]\"");
114 if (*cp
&& *cp
++ != ':')
115 return ("garbage after \"]\"");
116 *port
= *cp
? cp
: def_service
;
120 * host:port, host:, host, :port, port.
123 if ((cp
= split_at_right(buf
, ':')) != 0) {
124 *host
= *buf
? buf
: def_host
;
125 *port
= *cp
? cp
: def_service
;
127 *host
= def_host
? def_host
: (*buf
? buf
: 0);
128 *port
= def_service
? def_service
: (*buf
? buf
: 0);
132 return ("missing host information");
134 return ("missing service information");
137 * Final sanity checks. We're still sloppy, allowing bare numerical
138 * network addresses instead of requiring proper [ipaddress] forms.
140 if (*host
!= def_host
&& !valid_hostname(*host
, DONT_GRIPE
)
141 && !valid_hostaddr(*host
, DONT_GRIPE
))
142 return ("valid hostname or network address required");
143 if (*port
!= def_service
&& ISDIGIT(**port
) && !alldig(*port
))
144 return ("garbage after numerical service");
152 #include <vstring_vstream.h>
154 #define STR(x) vstring_str(x)
156 int main(int unused_argc
, char **unused_argv
)
158 VSTRING
*in_buf
= vstring_alloc(10);
159 VSTRING
*parse_buf
= vstring_alloc(10);
164 while (vstring_fgets_nonl(in_buf
, VSTREAM_IN
)) {
165 vstream_printf(">> %s\n", STR(in_buf
));
166 vstream_fflush(VSTREAM_OUT
);
167 if (*STR(in_buf
) == '#')
169 vstring_strcpy(parse_buf
, STR(in_buf
));
170 if ((err
= host_port(STR(parse_buf
), &host
, (char *) 0, &port
, "default-service")) != 0) {
171 msg_warn("%s in %s", err
, STR(in_buf
));
173 vstream_printf("host %s port %s\n", host
, port
);
174 vstream_fflush(VSTREAM_OUT
);
177 vstring_free(in_buf
);
178 vstring_free(parse_buf
);