int xconnect_stream(const len_and_sockaddr *lsa) FAST_FUNC;
/* Get local address of bound or accepted socket */
len_and_sockaddr *get_sock_lsa(int fd) FAST_FUNC RETURNS_MALLOC;
+/* Get remote address of connected or accepted socket */
+len_and_sockaddr *get_peer_lsa(int fd) FAST_FUNC RETURNS_MALLOC;
/* Return malloc'ed len_and_sockaddr with socket address of host:port
* Currently will return IPv4 or IPv6 sockaddrs only
* (depending on host), but in theory nothing prevents e.g.
}
#endif
-len_and_sockaddr* FAST_FUNC get_sock_lsa(int fd)
+static len_and_sockaddr* get_lsa(int fd, int (*get_name)(int fd, struct sockaddr *addr, socklen_t *addrlen))
{
len_and_sockaddr lsa;
len_and_sockaddr *lsa_ptr;
lsa.len = LSA_SIZEOF_SA;
- if (getsockname(fd, &lsa.u.sa, &lsa.len) != 0)
+ if (get_name(fd, &lsa.u.sa, &lsa.len) != 0)
return NULL;
lsa_ptr = xzalloc(LSA_LEN_SIZE + lsa.len);
if (lsa.len > LSA_SIZEOF_SA) { /* rarely (if ever) happens */
lsa_ptr->len = lsa.len;
- getsockname(fd, &lsa_ptr->u.sa, &lsa_ptr->len);
+ get_name(fd, &lsa_ptr->u.sa, &lsa_ptr->len);
} else {
memcpy(lsa_ptr, &lsa, LSA_LEN_SIZE + lsa.len);
}
return lsa_ptr;
}
+len_and_sockaddr* FAST_FUNC get_sock_lsa(int fd)
+{
+ return get_lsa(fd, getsockname);
+}
+
+len_and_sockaddr* FAST_FUNC get_peer_lsa(int fd)
+{
+ return get_lsa(fd, getpeername);
+}
+
void FAST_FUNC xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen)
{
if (connect(s, s_addr, addrlen) < 0) {
free(response);
}
-/* libbb candidate */
-static
-len_and_sockaddr* get_peer_lsa(int fd)
-{
- len_and_sockaddr *lsa;
- socklen_t len = 0;
-
- if (getpeername(fd, NULL, &len) != 0)
- return NULL;
- lsa = xzalloc(LSA_LEN_SIZE + len);
- lsa->len = len;
- getpeername(fd, &lsa->u.sa, &lsa->len);
- return lsa;
-}
-
static void
handle_port(void)
{
IF_FEATURE_TELNETD_STANDALONE(int sock)
IF_NOT_FEATURE_TELNETD_STANDALONE(void)
) {
+#if !ENABLE_FEATURE_TELNETD_STANDALONE
+ enum { sock = 0 );
+#endif
const char *login_argv[2];
struct termios termbuf;
int fd, pid;
ndelay_on(fd);
close_on_exec_on(fd);
-#if ENABLE_FEATURE_TELNETD_STANDALONE
/* SO_KEEPALIVE by popular demand */
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));
+#if ENABLE_FEATURE_TELNETD_STANDALONE
ts->sockfd_read = sock;
ndelay_on(sock);
if (sock == 0) { /* We are called with fd 0 - we are in inetd mode */
if (sock > G.maxfd)
G.maxfd = sock;
#else
- /* SO_KEEPALIVE by popular demand */
- setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));
/* ts->sockfd_read = 0; - done by xzalloc */
ts->sockfd_write = 1;
ndelay_on(0);
/* Restore default signal handling ASAP */
bb_signals((1 << SIGCHLD) + (1 << SIGPIPE), SIG_DFL);
+ if (ENABLE_FEATURE_UTMP) {
+ len_and_sockaddr *lsa = get_peer_lsa(sock);
+ char *hostname = NULL;
+ if (lsa) {
+ hostname = xmalloc_sockaddr2dotted(&lsa->u.sa);
+ free(lsa);
+ }
+ write_new_utmp(pid, LOGIN_PROCESS, tty_name, /*username:*/ "LOGIN", hostname);
+ free(hostname);
+ }
+
/* Make new session and process group */
setsid();
pid = getpid();
tcsetpgrp(0, pid); /* switch this tty's process group to us */
-//TODO: fetch remote addr via getpeername (see ftpd.c)
- write_new_utmp(pid, LOGIN_PROCESS, tty_name, /*username:*/ "LOGIN", /*hostname:*/ NULL);
-
/* The pseudo-terminal allocated to the client is configured to operate
* in cooked mode, and with XTABS CRMOD enabled (see tty(4)) */
tcgetattr(0, &termbuf);