February 5, 2007 at 2:18PM Getting a list of hostnames associated with a host.
I needed something for a shell script over the weekend to get a list the primary hostname and any aliases, all of them, I couldn’t think of any commands, and hostname doesn’t do quite what I wanted, so I knocked this out. It might be of use to somebody:
/*
* hostnames.c
* by Keith Gaughan (http://talideon.com/)
*
* Lists all the names associated with a given host (or the current one if
* non is specified.
*
* Copyleft (k) Keith Gaughan, 2007.
* All rights reversed. Do what you will with it, just don't come crying to
* me if something bad happens.
*
* To compile, type: gcc -lc -Os -Wall -o hostnames hostnames.c
* You might need an implementation of strlcpy().
*/
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
/* Sigh... */
#ifndef FALSE
#define FALSE 0
#define TRUE (!(FALSE))
#endif
static int quiet = FALSE;
static void echo(char* key, char* val) {
if (quiet) {
printf("%s\n", val);
} else {
printf("%s: %s\n", key, val);
}
}
int main(int argc, char** argv) {
char buf[250];
struct hostent* h;
char** aliases;
int arg = 1;
/* Check for quiet flag */
if (argc > 1 && strcmp(argv[arg], "-q") == 0) {
argc--;
arg++;
quiet = TRUE;
}
if (argc > 1) {
/* Use the one passed in on the command line. */
strlcpy(buf, argv[arg], sizeof buf);
} else if (gethostname(buf, sizeof buf) != 0) {
perror("Could not read host name");
return 1;
}
h = gethostbyname(buf);
if (h == NULL) {
herror("Could not fetch host details");
return 2;
}
echo("Official hostname", h->h_name);
aliases = h->h_aliases;
while (*aliases) {
echo("Alias", *aliases);
aliases++;
}
return 0;
}
Watch for the use of strlcpy(): you’ll need a copy, Linux boy.
1 On February 6, 2007 at 13:38, Revence 27 wrote:
You also use those global vars to toggle states? May concurrency eat you raw.
Otherwise, I love the look of the code. And I hate that you do ... wait, lemme talk. I’m not getting billed. And it’s a long time since I flamed witcha.
Presenting, bit’s I’d re-write or copy (you’ll have to clean this up - Textuality is quite elusive, and no preview):
#define TRUE (!(FALSE))Eh! Neat! But I like this better:#if !defined(cplusplus) && !defined(REVBOOLDEF) #define REVBOOLDEF #define false 0 #define true (!(false)) / Shameless plagiary!/ #endifNo global vars. Concurrency can massacre you.
/ In check for quiet flag, I’d .../ if (argc > 1 && !strcmp(argv[arg], “-q”)) / ... /;It’s good for freaking little ones out into running over to the shop for you, after they’ve peered over your shoulder ...Still at the check for the quiet flag, after the if block ...
else printf(”Usage:nhostname [something]n”);You don’t lose too many calories, and it keeps being helpful even to the kinds of people who would never use it.2 On February 6, 2007 at 13:40, Revence 27 wrote:
You also use those global vars to toggle states? May concurrency eat you raw.
Otherwise, I love the look of the code. And I hate that you do ... wait, lemme talk. I’m not getting billed. And it’s a long time since I flamed witcha.
Presenting, bit’s I’d re-write or copy (you’ll have to clean this up - Textuality is quite elusive, and no preview):
#define TRUE (!(FALSE))Eh! Neat! But I like this better:#if !defined(cplusplus) && !defined(REVBOOLDEF) #define REVBOOLDEF #define false 0 #define true (!(false)) / Shameless plagiary!/ #endifNo global vars. Concurrency can massacre you.
/ In check for quiet flag, I’d .../ if (argc > 1 && !strcmp(argv[arg], “-q”)) / ... /;It’s good for freaking little ones out into running over to the shop for you, after they’ve peered over your shoulder ...Still at the check for the quiet flag, after the if block ...
else printf(”Usage:nhostname [something]n”);You don’t lose too many calories, and it keeps being helpful even to the kinds of people who would never use it.3 On February 7, 2007 at 9:28, Keith wrote:
Textuality is hardly all that hard. You just start preformatted blocks with
=preand end them with=/pre, just as stated in the documentation.Global variables are just fine in this state. It’s global state, and considering that (a) the app is single threaded and (b) it’s C and there’s no way to encapsulate global state.
On the topic of how the boolean is defined, remember that this is C and traditionally in C, constants are given uppercase names and anyway, the way you’re doing it, you’d also have to give a
typedefforboolor you’ll get warnings when you compile the code with a C++ compiler. I’m not doing anything different from the code for just about any C program written over the last 35 years.That little bit for checking for the quiet flag could be bundled up in a macro, but I didn’t see the point, hence the comment.
Your
elseshowing usage info doesn’t make sense.-qisn’t a required flag. Your way of doing things, the message would get shown regardless of whether it’s justified or not. Now, if there was a help flag, it’d make sense to check for that and print the usage info, but there isn’t. And anyway, you’re asking me to write usage info out to stdout rather than stderr, which is a big no-no.Note to self: catch duplicate posts.
4 On February 7, 2007 at 10:10, Revence 27 wrote:
Yeah, catch duplicates. I thought it is one way you trap spam.
Okay, it’s just Textuality si too divorced from the usual tomfoolery I usually do. But ‘tis powerful, as well. I once knew it better than you. Then you blacked out. Think of a preview button. A few more lines ...
Yeah, on the TRUE/FALSE thing ... I like my non-C stuff to lose itself into my C++ stuff. Without being C++. I mean, C-99 has bool. So, by putting it there, I am closer to C-99 (in ANSI ‘89). Just thought it’d look neat. It’s neat, hell! I hate tradition, pal. And that stuff, on top of looking a hell of a lot more intelligible and neater, it is good with C++. Very coherent.
Yeah, but if you haven’t yet written
checkforconcurrencyrisk.pl, mine doesn’t differentiate between what will be end up asa.outand what will end up aslib.o. So, global vars are forbidden everywhere. If you can’t pass them to funcs, the ideology says, you can’t be trusted with them in global.Well, the else makes sense, because you don’t deal with many args. Just one, which should be
-q’ or the hostname. More than that can throw an error, if it wants.But this was neat, nonetheless. Undeniably. Did you send for your Solaris 10? So I may be putting the FreeBSD things on the hind for a while ...
5 On February 7, 2007 at 10:13, Revence 27 wrote:
Oh, frig! I messed it up again! Please, Gaga, remove this bugger, and the duplicate, and clean up behind me, pleease! I promise to recite the Textuality manual before I format again. Mwa! Kiss for being good.
6 On February 7, 2007 at 14:27, Keith wrote:
Problem is, C99 isn’t widely implemented, so I’ll be sticking with C89, thank you very much.
And on Solaris, nope. Not going near it, and even if I was, I could just burn an ISO.
7 On February 7, 2007 at 14:28, Keith wrote:
Oh, and read through the code again, the usage isn’t