diff options
-rw-r--r-- | hostname/hostname.c | 62 |
1 files changed, 59 insertions, 3 deletions
diff --git a/hostname/hostname.c b/hostname/hostname.c index 3dc1224..d19e4b8 100644 --- a/hostname/hostname.c +++ b/hostname/hostname.c @@ -18,6 +18,18 @@ #include <sys/socket.h> #include <netdb.h> +/* open, read, close */ +#include <sys/stat.h> +#include <fcntl.h> + +int sethostname(const char *value, +#ifdef __linux__ + size_t +#else + int +#endif + namelen); + int do_print_nodename(bool verbose, bool domain, bool fqdn, bool address, bool shorten) { long hostname = sysconf(_SC_HOST_NAME_MAX); @@ -113,9 +125,53 @@ int do_print_nodename(bool verbose, bool domain, bool fqdn, bool address, bool s int do_set_nodename(bool file, const char *value) { - fprintf(stderr, "setting nodenamet to %s %s not yet supported\n", - (file ? "contents of file" : "literal string"), value); - return 1; + size_t len; + + if(file) + { + /* This is insane. There is no validation whatsoever. + * However, strace on net-tools hostname(1) shows this to be + * the exact algorithm used, so... */ + char buf[1024]; + int fildes = open(value, O_RDONLY); + ssize_t result = 0; + + if(fildes == -1) + { + perror("open"); + return EXIT_FAILURE; + } + + while(true) + { + char *curr = buf; + result = read(fildes, buf, sizeof buf); + switch(result) + { + case -1: + perror("read"); + close(fildes); + return EXIT_FAILURE; + case 0: + close(fildes); + return EXIT_SUCCESS; + } + do + { + len = result; + char *pos = strchr(curr, '\n'); + if(pos) + { + len = pos - curr; + } + sethostname(curr, (len > 63) ? 63 : len); + } while((curr = strchr(curr, '\n'))); + } + } + + len = strlen(value); + sethostname(value, len); + return EXIT_SUCCESS; } void usage() |