* SUCH DAMAGE.
*/
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rexec.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <sys/uio.h>
int rexecoptions;
-static char ahostbuf[NI_MAXHOST];
+libc_freeres_ptr (static char *ahostbuf);
int
-rexec_af(ahost, rport, name, pass, cmd, fd2p, af)
- char **ahost;
- int rport;
- const char *name, *pass, *cmd;
- int *fd2p;
- sa_family_t af;
+rexec_af (char **ahost, int rport, const char *name, const char *pass,
+ const char *cmd, int *fd2p, sa_family_t af)
{
- struct sockaddr_storage sa2, from;
+ struct sockaddr_storage from;
struct addrinfo hints, *res0;
const char *orig_name = name;
const char *orig_pass = pass;
}
if (res0->ai_canonname){
- strncpy(ahostbuf, res0->ai_canonname, sizeof(ahostbuf));
- ahostbuf[sizeof(ahostbuf)-1] = '\0';
+ free (ahostbuf);
+ ahostbuf = __strdup (res0->ai_canonname);
+ if (ahostbuf == NULL) {
+ perror ("rexec: strdup");
+ return (-1);
+ }
*ahost = ahostbuf;
- }
- else{
+ } else {
*ahost = NULL;
+ __set_errno (ENOENT);
+ return -1;
}
ruserpass(res0->ai_canonname, &name, &pass);
retry:
+ /* NB: No SOCK_CLOEXEC for backwards compatibility. */
s = __socket(res0->ai_family, res0->ai_socktype, 0);
if (s < 0) {
perror("rexec: socket");
port = 0;
} else {
char num[32];
- int s2, sa2len;
+ int s2;
+ union
+ {
+ struct sockaddr_storage ss;
+ struct sockaddr sa;
+ } sa2;
+ socklen_t sa2len;
s2 = __socket(res0->ai_family, res0->ai_socktype, 0);
if (s2 < 0) {
}
__listen(s2, 1);
sa2len = sizeof (sa2);
- if (__getsockname(s2, (struct sockaddr *)&sa2, &sa2len) < 0) {
+ if (__getsockname(s2, &sa2.sa, &sa2len) < 0) {
perror("getsockname");
(void) __close(s2);
goto bad;
- } else if (sa2len != SA_LEN((struct sockaddr *)&sa2)) {
+ } else if (sa2len != SA_LEN(&sa2.sa)) {
__set_errno(EINVAL);
(void) __close(s2);
goto bad;
}
port = 0;
- if (!getnameinfo((struct sockaddr *)&sa2, sa2len,
+ if (!getnameinfo(&sa2.sa, sa2len,
NULL, 0, servbuff, sizeof(servbuff),
NI_NUMERICSERV))
port = atoi(servbuff);
(void) sprintf(num, "%u", port);
(void) __write(s, num, strlen(num)+1);
- { int len = sizeof (from);
- s3 = accept(s2, (struct sockaddr *)&from, &len);
+ { socklen_t len = sizeof (from);
+ s3 = TEMP_FAILURE_RETRY (accept(s2, (struct sockaddr *)&from,
+ &len));
__close(s2);
if (s3 < 0) {
perror("accept");
}
*fd2p = s3;
}
- (void) __write(s, name, strlen(name) + 1);
- /* should public key encypt the password here */
- (void) __write(s, pass, strlen(pass) + 1);
- (void) __write(s, cmd, strlen(cmd) + 1);
+
+ struct iovec iov[3] =
+ {
+ [0] = { .iov_base = (void *) name, .iov_len = strlen (name) + 1 },
+ /* should public key encypt the password here */
+ [1] = { .iov_base = (void *) pass, .iov_len = strlen (pass) + 1 },
+ [2] = { .iov_base = (void *) cmd, .iov_len = strlen (cmd) + 1 }
+ };
+ (void) TEMP_FAILURE_RETRY (__writev (s, iov, 3));
/* We don't need the memory allocated for the name and the password
in ruserpass anymore. */
libc_hidden_def (rexec_af)
int
-rexec(ahost, rport, name, pass, cmd, fd2p)
- char **ahost;
- int rport;
- const char *name, *pass, *cmd;
- int *fd2p;
+rexec (char **ahost, int rport, const char *name, const char *pass,
+ const char *cmd, int *fd2p)
{
return rexec_af(ahost, rport, name, pass, cmd, fd2p, AF_INET);
}