added sethostname syscall with proper error checks

Change-Id: I4b4e0a7c4035e19d5843b86ee1f714096adcecd2
This commit is contained in:
Morgawr 2014-04-24 02:12:48 +02:00 committed by Lionel Sambuc
parent b6bd719869
commit 91c835edc2
9 changed files with 375 additions and 6 deletions

View File

@ -1,7 +1,7 @@
# $NetBSD: Makefile,v 1.22 2007/12/31 15:31:24 ad Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
SUBDIR= cat chmod date df echo ed expr \
SUBDIR= cat chmod date df echo ed expr hostname \
kill ksh ln ls mkdir pax pwd rm rmdir \
sleep stty sync test

6
bin/hostname/Makefile Normal file
View File

@ -0,0 +1,6 @@
# $NetBSD: Makefile,v 1.8 1997/07/20 22:37:07 christos Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
PROG= hostname
.include <bsd.prog.mk>

87
bin/hostname/hostname.1 Normal file
View File

@ -0,0 +1,87 @@
.\" $NetBSD: hostname.1,v 1.19 2013/07/19 11:19:23 wiz Exp $
.\"
.\" Copyright (c) 1983, 1988, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)hostname.1 8.2 (Berkeley) 4/28/95
.\"
.Dd July 19, 2013
.Dt HOSTNAME 1
.Os
.Sh NAME
.Nm hostname
.Nd set or print name of current host system
.Sh SYNOPSIS
.Nm
.Op Fl AadfIis
.Op Ar name-of-host
.Sh DESCRIPTION
.Nm
prints the name of the current host.
The super-user can set the host name by supplying an argument; this is
usually done in the network initialization script
.Pa /etc/rc.d/network ,
normally run at boot
time.
.Pp
Options:
.Bl -tag -width flag
.It Fl A
Display the FQDN of each address on all interfaces.
.It Fl a
Display alias name(s) of the host.
.It Fl d
Display the DNS domain.
.It Fl f
Display the FQDN for the hostname.
.It Fl I
Display each IP address on all interfaces.
.It Fl i
Display the IP address(es) for the hostname.
.It Fl s
Display the short hostname.
.El
.Sh NOTES
With the exception of
.Fl I
and
.Fl s ,
the other options will retrieve their results from the resolver.
.Sh SEE ALSO
.Xr domainname 1 ,
.Xr getaddrinfo 3 ,
.Xr gethostbyname 3 ,
.Xr gethostname 3 ,
.Xr getifaddrs 3 ,
.Xr getnameinfo 3 ,
.Xr sethostname 3 ,
.Xr hosts 5
.Sh HISTORY
The
.Nm
utility appeared in
.Bx 4.2 .

209
bin/hostname/hostname.c Normal file
View File

@ -0,0 +1,209 @@
/* $NetBSD: hostname.c,v 1.20 2013/07/19 15:53:00 christos Exp $ */
/*
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1988, 1993\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)hostname.c 8.2 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: hostname.c,v 1.20 2013/07/19 15:53:00 christos Exp $");
#endif
#endif /* not lint */
#include <sys/param.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <err.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
__dead static void usage(void);
int
main(int argc, char *argv[])
{
int ch, Aflag, aflag, dflag, Iflag, iflag, fflag, sflag, i;
char *p, hostname[MAXHOSTNAMELEN + 1];
struct addrinfo hints, *ainfos, *ai;
struct hostent *hent;
struct ifaddrs *ifa, *ifp;
struct sockaddr_in6 *sin6;
char buf[MAX(MAXHOSTNAMELEN + 1, INET6_ADDRSTRLEN)];
setprogname(argv[0]);
Aflag = aflag = dflag = Iflag = iflag = fflag = sflag = 0;
while ((ch = getopt(argc, argv, "AadIifs")) != -1)
switch (ch) {
case 'A':
Aflag = 1;
break;
case 'a':
aflag = 1;
break;
case 'd':
dflag = 1;
break;
case 'I':
Iflag = 1;
break;
case 'i':
iflag = 1;
break;
case 'f':
fflag = 1;
break;
case 's':
sflag = 1;
break;
case '?':
default:
usage();
}
argc -= optind;
argv += optind;
if (argc > 1)
usage();
if (*argv) {
if (sethostname(*argv, strlen(*argv)))
err(1, "sethostname");
} else if (Aflag || Iflag) {
if (getifaddrs(&ifa) == -1)
err(1, "getifaddrs");
for (ifp = ifa; ifp; ifp = ifp->ifa_next) {
if (ifp->ifa_addr == NULL ||
#if !defined(__minix)
ifp->ifa_flags & IFF_LOOPBACK ||
#endif
!(ifp->ifa_flags & IFF_UP))
continue;
switch(ifp->ifa_addr->sa_family) {
case AF_INET:
break;
case AF_INET6:
/* Skip link local addresses */
sin6 = (struct sockaddr_in6 *)ifp->ifa_addr;
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr))
continue;
break;
default:
/* We only translate IPv4 or IPv6 addresses */
continue;
}
i = getnameinfo(ifp->ifa_addr, ifp->ifa_addr->sa_len,
buf, sizeof(buf), NULL, 0,
Iflag ? NI_NUMERICHOST: NI_NAMEREQD);
if (i) {
if (Iflag && i != EAI_NONAME)
errx(1, "getnameinfo: %s",
gai_strerror(i));
} else
printf("%s\n", buf);
}
freeifaddrs(ifa);
} else {
if (gethostname(hostname, sizeof(hostname)))
err(1, "gethostname");
hostname[sizeof(hostname) - 1] = '\0';
if (aflag) {
if ((hent = gethostbyname(hostname)) == NULL)
errx(1, "gethostbyname: %s",
hstrerror(h_errno));
for (i = 0; hent->h_aliases[i]; i++)
printf("%s\n", hent->h_aliases[i]);
} else if (dflag || iflag || fflag) {
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_CANONNAME;
i = getaddrinfo(hostname, NULL, &hints, &ainfos);
if (i)
errx(1, "getaddrinfo: %s", gai_strerror(i));
if (ainfos) {
if (dflag) {
if ((p = strchr(ainfos->ai_canonname,
'.')))
printf("%s\n", p + 1);
} else if (iflag) {
for (ai = ainfos; ai; ai = ai->ai_next)
{
i = getnameinfo(ai->ai_addr,
ai->ai_addrlen,
buf, sizeof(buf), NULL, 0,
NI_NUMERICHOST);
if (i)
errx(1,
"getnameinfo: %s",
gai_strerror(i));
printf("%s\n", buf);
}
} else {
if (sflag &&
(p = strchr(ainfos->ai_canonname,
'.')))
*p = '\0';
printf("%s\n", ainfos->ai_canonname);
}
freeaddrinfo(ainfos);
}
} else {
if (sflag && (p = strchr(hostname, '.')))
*p = '\0';
printf("%s\n", hostname);
}
}
exit(0);
/* NOTREACHED */
}
static void
usage(void)
{
(void)fprintf(stderr, "usage: %s [-AadfIis] [name-of-host]\n",
getprogname());
exit(1);
/* NOTREACHED */
}

View File

@ -24,6 +24,7 @@
./bin/ed minix-sys
./bin/expr minix-sys
./bin/getopts minix-sys
./bin/hostname minix-sys
./bin/intr minix-sys
./bin/kill minix-sys
./bin/ksh minix-sys
@ -2087,6 +2088,7 @@
./usr/man/man1/hexdump.1 minix-sys
./usr/man/man1/host.1 minix-sys
./usr/man/man1/hostaddr.1 minix-sys
./usr/man/man1/hostname.1 minix-sys
./usr/man/man1/id.1 minix-sys
./usr/man/man1/if.1 minix-sys
./usr/man/man1/ifdef.1 minix-sys

View File

@ -19,4 +19,6 @@
#define _PATH_SERVACCES "/etc/serv.access"
#define _PATH_HOSTNAME_FILE "/etc/hostname.file"
#endif /* _MINIX_PATHS_H_ */

View File

@ -10,7 +10,7 @@
.if defined(__MINIX)
# Unsupported by Minix.
# closefrom.c confstr.c extattr.c getdevmajor.c \
# pthread_atfork.c setdomainname.c sethostname.c setproctitle.c \
# pthread_atfork.c setdomainname.c setproctitle.c \
# sysctl.c sysctlbyname.c sysctlgetmibinfo.c sysctlnametomib.c \
# wait3.c
@ -39,7 +39,7 @@ SRCS+= _errno.c alarm.c alphasort.c arc4random.c assert.c basename.c clock.c \
psignal.c \
ptree.c pwcache.c pw_scan.c raise.c randomid.c rb.c readdir.c \
rewinddir.c scandir.c seekdir.c \
setjmperr.c setmode.c setprogname.c \
sethostname.c setjmperr.c setmode.c setprogname.c \
shquote.c shquotev.c sighold.c sigignore.c siginterrupt.c \
sysctl.c sysctlbyname.c sysctlgetmibinfo.c sysctlnametomib.c \
siglist.c signal.c signame.c sigrelse.c \

View File

@ -7,20 +7,19 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <minix/paths.h>
#ifdef __weak_alias
__weak_alias(gethostname, _gethostname)
#endif
#define HOSTNAME_FILE "/etc/hostname.file"
int gethostname(char *buf, size_t len)
{
int fd;
int r;
char *nl;
if ((fd= open(HOSTNAME_FILE, O_RDONLY)) < 0) return -1;
if ((fd= open(_PATH_HOSTNAME_FILE, O_RDONLY)) < 0) return -1;
r= read(fd, buf, len);
close(fd);

View File

@ -0,0 +1,64 @@
/* gethostname(2) system call emulation */
#include <sys/cdefs.h>
#include "namespace.h"
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <minix/paths.h>
#ifdef __weak_alias
__weak_alias(sethostname, _sethostname)
#endif
int sethostname(const char *buf, size_t len)
{
int fd;
int r;
int tmperr;
char name[20];
strlcpy(name, "/tmp/hostname.XXXXX",sizeof(name));
fd = mkstemp(name);
if (fd == -1)
return -1;
r = fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (r == -1) {
tmperr = errno;
close(fd);
unlink(name);
errno = tmperr;
return -1;
}
r = write(fd, buf, len);
tmperr = errno;
close(fd);
if (r == -1) {
unlink(name);
errno = tmperr;
return -1;
}
if (r < len) {
unlink(name);
errno = ENOSPC;
return -1;
}
r = rename(name, _PATH_HOSTNAME_FILE);
if (r == -1) {
tmperr = errno;
unlink(name);
errno = tmperr;
}
return 0;
}