summaryrefslogtreecommitdiffstats
path: root/support/export/hostname.c
diff options
context:
space:
mode:
authorhjl <hjl>1999-10-18 23:21:12 +0000
committerhjl <hjl>1999-10-18 23:21:12 +0000
commit8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9 (patch)
tree0904ef8554ed680fe3244fa618685e1fb7ea148b /support/export/hostname.c
downloadnfs-utils-8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9.tar.gz
nfs-utils-8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9.tar.xz
nfs-utils-8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9.zip
Initial revision
Diffstat (limited to 'support/export/hostname.c')
-rw-r--r--support/export/hostname.c262
1 files changed, 262 insertions, 0 deletions
diff --git a/support/export/hostname.c b/support/export/hostname.c
new file mode 100644
index 0000000..a37d4de
--- /dev/null
+++ b/support/export/hostname.c
@@ -0,0 +1,262 @@
+/*
+ * support/export/hostname.c
+ *
+ * Functions for hostname.
+ *
+ */
+
+#include "config.h"
+
+/*
+#define TEST
+*/
+
+#include <string.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#ifdef TEST
+#define xmalloc malloc
+#else
+#include "xmalloc.h"
+#include "misc.h"
+#endif
+
+#define ALIGNMENT sizeof (char *)
+
+static int
+align (int len, int al)
+{
+ int i;
+ i = len % al;
+ if (i)
+ len += al - i;
+ return len;
+}
+
+struct hostent *
+get_hostent (const char *addr, int len, int type)
+{
+ struct hostent *cp;
+ int len_ent;
+ const char *name;
+ int len_name;
+ int num_aliases = 1;
+ int len_aliases = sizeof (char *);
+ int num_addr_list = 1;
+ int len_addr_list = sizeof (char *);
+ int pos;
+ struct in_addr *ipv4;
+
+ switch (type)
+ {
+ case AF_INET:
+ ipv4 = (struct in_addr *) addr;
+ name = inet_ntoa (*ipv4);
+ break;
+
+ default:
+ return NULL;
+ }
+
+ len_ent = align (sizeof (*cp), ALIGNMENT);
+ len_name = align (strlen (name) + 1, ALIGNMENT);
+
+ num_addr_list++;
+ len_addr_list += align (len, ALIGNMENT) + sizeof (char *);
+
+ cp = (struct hostent *) xmalloc (len_ent + len_name + len_aliases
+ + len_addr_list);
+
+ cp->h_addrtype = type;
+ cp->h_length = len;
+ pos = len_ent;
+ cp->h_name = (char *) &(((char *) cp) [pos]);
+ strcpy (cp->h_name, name);
+
+ pos += len_name;
+ cp->h_aliases = (char **) &(((char *) cp) [pos]);
+ pos += num_aliases * sizeof (char *);
+ cp->h_aliases [0] = NULL;
+
+ pos = len_ent + len_name + len_aliases;
+ cp->h_addr_list = (char **) &(((char *) cp) [pos]);
+ pos += num_addr_list * sizeof (char *);
+ cp->h_addr_list [0] = (char *) &(((char *) cp) [pos]);
+ memcpy (cp->h_addr_list [0], addr, cp->h_length);
+ pos += align (cp->h_length, ALIGNMENT);
+ cp->h_addr_list [1] = NULL;
+
+ return cp;
+}
+
+struct hostent *
+hostent_dup (struct hostent *hp)
+{
+ int len_ent = align (sizeof (*hp), ALIGNMENT);
+ int len_name = align (strlen (hp->h_name) + 1, ALIGNMENT);
+ int num_aliases = 1;
+ int len_aliases = sizeof (char *);
+ int num_addr_list = 1;
+ int len_addr_list = sizeof (char *);
+ int pos, i;
+ char **sp;
+ struct hostent *cp;
+
+ for (sp = hp->h_aliases; *sp; sp++)
+ {
+ num_aliases++;
+ len_aliases += align (strlen (*sp) + 1, ALIGNMENT)
+ + sizeof (char *);
+ }
+
+ for (sp = hp->h_addr_list; *sp; sp++)
+ {
+ num_addr_list++;
+ len_addr_list += align (hp->h_length, ALIGNMENT)
+ + sizeof (char *);
+ }
+
+ cp = (struct hostent *) xmalloc (len_ent + len_name + len_aliases
+ + len_addr_list);
+
+ *cp = *hp;
+ pos = len_ent;
+ cp->h_name = (char *) &(((char *) cp) [pos]);
+ strcpy (cp->h_name, hp->h_name);
+
+ pos += len_name;
+ cp->h_aliases = (char **) &(((char *) cp) [pos]);
+ pos += num_aliases * sizeof (char *);
+ for (sp = hp->h_aliases, i = 0; i < num_aliases; i++, sp++)
+ if (*sp)
+ {
+ cp->h_aliases [i] = (char *) &(((char *) cp) [pos]);
+ strcpy (cp->h_aliases [i], *sp);
+ pos += align (strlen (*sp) + 1, ALIGNMENT);
+ }
+ else
+ cp->h_aliases [i] = *sp;
+
+ pos = len_ent + len_name + len_aliases;
+ cp->h_addr_list = (char **) &(((char *) cp) [pos]);
+ pos += num_addr_list * sizeof (char *);
+ for (sp = hp->h_addr_list, i = 0; i < num_addr_list; i++, sp++)
+ if (*sp)
+ {
+ cp->h_addr_list [i] = (char *) &(((char *) cp) [pos]);
+ memcpy (cp->h_addr_list [i], *sp, hp->h_length);
+ pos += align (hp->h_length, ALIGNMENT);
+ }
+ else
+ cp->h_addr_list [i] = *sp;
+
+ return cp;
+}
+
+static int
+is_hostname(const char *sp)
+{
+ if (*sp == '\0' || *sp == '@')
+ return 0;
+
+ for (; *sp; sp++)
+ {
+ if (*sp == '*' || *sp == '?' || *sp == '[' || *sp == '/')
+ return 0;
+ if (*sp == '\\' && sp[1])
+ sp++;
+ }
+
+ return 1;
+}
+
+int
+matchhostname (const char *h1, const char *h2)
+{
+ struct hostent *hp1, *hp2;
+ int status;
+
+ if (strcasecmp (h1, h2) == 0)
+ return 1;
+
+ if (!is_hostname (h1) || !is_hostname (h2))
+ return 0;
+
+ hp1 = gethostbyname (h1);
+ if (hp1 == NULL)
+ return 0;
+
+ hp1 = hostent_dup (hp1);
+
+ hp2 = gethostbyname (h2);
+ if (hp2)
+ {
+ if (strcasecmp (hp1->h_name, hp2->h_name) == 0)
+ status = 1;
+ else
+ {
+ char **ap1, **ap2;
+
+ status = 0;
+ for (ap1 = hp1->h_addr_list; *ap1 && status == 0; ap1++)
+ for (ap2 = hp2->h_addr_list; *ap2; ap2++)
+ if (memcmp (*ap1, *ap2, sizeof (struct in_addr)) == 0)
+ {
+ status = 1;
+ break;
+ }
+ }
+ }
+ else
+ status = 0;
+
+ free (hp1);
+ return status;
+}
+
+#ifdef TEST
+void
+print_host (struct hostent *hp)
+{
+ char **sp;
+
+ if (hp)
+ {
+ printf ("official hostname: %s\n", hp->h_name);
+ printf ("aliases:\n");
+ for (sp = hp->h_aliases; *sp; sp++)
+ printf (" %s\n", *sp);
+ printf ("IP addresses:\n");
+ for (sp = hp->h_addr_list; *sp; sp++)
+ printf (" %s\n", inet_ntoa (*(struct in_addr *) *sp));
+ }
+ else
+ printf ("Not host information\n");
+}
+
+int
+main (int argc, char **argv)
+{
+ struct hostent *hp = gethostbyname (argv [1]);
+ struct hostent *cp;
+ struct in_addr addr;
+
+ print_host (hp);
+
+ if (hp)
+ {
+ cp = hostent_dup (hp);
+ print_host (cp);
+ free (cp);
+ }
+ printf ("127.0.0.1 == %s: %d\n", argv [1],
+ matchhostname ("127.0.0.1", argv [1]));
+ addr.s_addr = inet_addr(argv [2]);
+ printf ("%s\n", inet_ntoa (addr));
+ cp = get_hostent ((const char *)&addr, sizeof(addr), AF_INET);
+ print_host (cp);
+ return 0;
+}
+#endif