From 2a708d9795c2474be8af2b4920c3806fc7b8f5cf Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Sat, 23 Apr 2022 02:41:04 -0500 Subject: hostname: Add ability to set node name --- hostname/hostname.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file 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 #include +/* open, read, close */ +#include +#include + +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() -- cgit v1.2.3-70-g09d2