-/* Copyright (c) 1998, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (c) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* getent: get entries from administrative database
- supported databases: passwd, group, hosts, services, protocols
- and networks */
+/* getent: get entries from administrative database. */
+#include <aliases.h>
#include <argp.h>
#include <grp.h>
#include <pwd.h>
+#include <shadow.h>
#include <ctype.h>
#include <error.h>
#include <libintl.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <netinet/ether.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
/* Short description of parameters. */
static const char args_doc[] = N_("database [key ...]");
-/* Short description of program. */
-static const char doc[] =
- N_("getent - get entries from administrative database.");
-
/* Data structure to communicate with argp functions. */
static struct argp argp = {
- NULL, NULL, args_doc, doc,
+ NULL, NULL, args_doc, NULL,
};
/* Print the version information. */
Copyright (C) %s Free Software Foundation, Inc.\n\
This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "1999");
+"), "2001");
fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk");
}
+/* This is for aliases */
+static inline void
+print_aliases (struct aliasent *alias)
+{
+ unsigned int i = 0;
+
+ printf ("%s: ", alias->alias_name);
+ for (i = strlen (alias->alias_name); i < 14; ++i)
+ fputs (" ", stdout);
+
+ for (i = 0;
+ i < alias->alias_members_len;
+ ++i)
+ printf ("%s%s",
+ alias->alias_members [i],
+ i + 1 == alias->alias_members_len ? "\n" : ", ");
+}
+
+static int
+aliases_keys (int number, char *key[])
+{
+ int result = 0;
+ int i;
+ struct aliasent *alias;
+
+ if (!number)
+ {
+ setaliasent ();
+ while ((alias = getaliasent()) != NULL)
+ print_aliases (alias);
+ endaliasent ();
+ return result;
+ }
+
+ for (i = 0; i < number; ++i)
+ {
+ alias = getaliasbyname (key[i]);
+
+ if (alias == NULL)
+ result = 2;
+ else
+ print_aliases (alias);
+ }
+
+ return result;
+}
+
+/* This is for ethers */
+static int
+ethers_keys (int number, char *key[])
+{
+ int result = 0;
+ int i;
+
+ if (!number)
+ {
+ fprintf (stderr, _("Enumeration not supported on %s\n"), "ethers");
+ return 3;
+ }
+
+ for (i = 0; i < number; ++i)
+ {
+ struct ether_addr *ethp, eth;
+ char buffer [1024], *p;
+
+ ethp = ether_aton (key[i]);
+ if (ethp)
+ {
+ if (ether_ntohost (buffer, ethp))
+ {
+ result = 2;
+ continue;
+ }
+ p = buffer;
+ }
+ else
+ {
+ if (ether_hostton (key[i], ð))
+ {
+ result = 2;
+ continue;
+ }
+ p = key[i];
+ ethp = ð
+ }
+ printf ("%s %s\n", ether_ntoa (ethp), p);
+ }
+
+ return result;
+}
+
/* This is for group */
static inline void
print_group (struct group *grp)
fputs ("\n", stdout);
}
-static inline int
+static int
group_keys (int number, char *key[])
{
int result = 0;
int i;
+ struct group *grp;
- for (i = 0; i < number; ++i)
+ if (!number)
{
- struct group *grp;
+ setgrent ();
+ while ((grp = getgrent()) != NULL)
+ print_group (grp);
+ endgrent ();
+ return result;
+ }
+ for (i = 0; i < number; ++i)
+ {
if (isdigit (key[i][0]))
grp = getgrgid (atol (key[i]));
else
return result;
}
+/* This is for hosts */
+static inline void
+print_hosts (struct hostent *host)
+{
+ unsigned int i;
+ char buf[INET6_ADDRSTRLEN];
+ const char *ip = inet_ntop (host->h_addrtype, host->h_addr_list[0],
+ buf, sizeof (buf));
+
+ fputs (ip, stdout);
+ for (i = strlen (ip); i < 15; ++i)
+ fputs (" ", stdout);
+ fputs (" ", stdout);
+ fputs (host->h_name, stdout);
+
+ i = 0;
+ while (host->h_aliases[i] != NULL)
+ {
+ fputs (" ", stdout);
+ fputs (host->h_aliases[i], stdout);
+ ++i;
+ }
+ fputs ("\n", stdout);
+}
+
+static int
+hosts_keys (int number, char *key[])
+{
+ int result = 0;
+ int i;
+ struct hostent *host;
+
+ if (!number)
+ {
+ sethostent (0);
+ while ((host = gethostent()) != NULL)
+ print_hosts (host);
+ endhostent ();
+ return result;
+ }
+
+ for (i = 0; i < number; ++i)
+ {
+ struct hostent *host = NULL;
+
+ if (strchr (key[i], ':') != NULL)
+ {
+ char addr[IN6ADDRSZ];
+ if (inet_pton (AF_INET6, key[i], &addr))
+ host = gethostbyaddr (addr, sizeof (addr), AF_INET6);
+ }
+ else if (isdigit (key[i][0]))
+ {
+ char addr[INADDRSZ];
+ if (inet_pton (AF_INET, key[i], &addr))
+ host = gethostbyaddr (addr, sizeof (addr), AF_INET);
+ }
+ else if ((host = gethostbyname2 (key[i], AF_INET6)) == NULL)
+ host = gethostbyname2 (key[i], AF_INET);
+
+ if (host == NULL)
+ result = 2;
+ else
+ print_hosts (host);
+ }
+
+ return result;
+}
+
+/* This is for netgroup */
+static int
+netgroup_keys (int number, char *key[])
+{
+ int result = 0;
+ int i, j;
+
+ if (!number)
+ {
+ fprintf (stderr, _("Enumeration not supported on %s\n"), "netgroup");
+ return 3;
+ }
+
+ for (i = 0; i < number; ++i)
+ {
+ if (!setnetgrent (key[i]))
+ result = 2;
+ else
+ {
+ char *p[3];
+
+ fputs (key[i], stdout);
+ for (j = strlen (key[i]); j < 21; ++j)
+ fputs (" ", stdout);
+
+ while (getnetgrent (p, p + 1, p + 2))
+ printf (" (%s, %s, %s)", p[0] ?: " ", p[1] ?: "", p[2] ?: "");
+ fputs ("\n", stdout);
+ }
+ }
+
+ return result;
+}
+
/* This is for networks */
static inline void
print_networks (struct netent *net)
struct in_addr ip;
ip.s_addr = htonl (net->n_net);
- fputs (net->n_name, stdout);
- for (i = strlen (net->n_name); i < 22; ++i)
+ printf ("%s ", net->n_name);
+ for (i = strlen (net->n_name); i < 21; ++i)
fputs (" ", stdout);
fputs (inet_ntoa (ip), stdout);
fputs ("\n", stdout);
}
-static inline int
+static int
networks_keys (int number, char *key[])
{
int result = 0;
int i;
+ struct netent *net;
- for (i = 0; i < number; ++i)
+ if (!number)
{
- struct netent *net;
+ setnetent (0);
+ while ((net = getnetent()) != NULL)
+ print_networks (net);
+ endnetent ();
+ return result;
+ }
+ for (i = 0; i < number; ++i)
+ {
if (isdigit (key[i][0]))
net = getnetbyaddr (inet_addr (key[i]), AF_UNIX);
else
pwd->pw_shell ? pwd->pw_shell : "");
}
-static inline int
+static int
passwd_keys (int number, char *key[])
{
int result = 0;
int i;
+ struct passwd *pwd;
- for (i = 0; i < number; ++i)
+ if (!number)
{
- struct passwd *pwd;
+ setpwent ();
+ while ((pwd = getpwent()) != NULL)
+ print_passwd (pwd);
+ endpwent ();
+ return result;
+ }
+ for (i = 0; i < number; ++i)
+ {
if (isdigit (key[i][0]))
pwd = getpwuid (atol (key[i]));
else
unsigned int i;
fputs (proto->p_name, stdout);
- for (i = strlen (proto->p_name); i < 22; ++i)
+ for (i = strlen (proto->p_name); i < 21; ++i)
fputs (" ", stdout);
- printf ("%d", proto->p_proto);
+ printf (" %d", proto->p_proto);
i = 0;
while (proto->p_aliases[i] != NULL)
fputs ("\n", stdout);
}
-static inline int
+static int
protocols_keys (int number, char *key[])
{
int result = 0;
int i;
+ struct protoent *proto;
- for (i = 0; i < number; ++i)
+ if (!number)
{
- struct protoent *proto;
+ setprotoent (0);
+ while ((proto = getprotoent()) != NULL)
+ print_protocols (proto);
+ endprotoent ();
+ return result;
+ }
+ for (i = 0; i < number; ++i)
+ {
if (isdigit (key[i][0]))
proto = getprotobynumber (atol (key[i]));
else
return result;
}
-/* This is for hosts */
+/* Now is all for rpc */
static inline void
-print_hosts (struct hostent *host)
+print_rpc (struct rpcent *rpc)
{
- unsigned int i;
- char buf[INET6_ADDRSTRLEN];
- const char *ip = inet_ntop (host->h_addrtype, host->h_addr_list[0],
- buf, sizeof (buf));
+ int i;
- fputs (ip, stdout);
- for (i = strlen (ip); i < 15; ++i)
+ fputs (rpc->r_name, stdout);
+ for (i = strlen (rpc->r_name); i < 15; ++i)
fputs (" ", stdout);
- fputs (" ", stdout);
- fputs (host->h_name, stdout);
+ printf (" %d%s", rpc->r_number, rpc->r_aliases[0] ? " " : "");
- i = 0;
- while (host->h_aliases[i] != NULL)
- {
- fputs (" ", stdout);
- fputs (host->h_aliases[i], stdout);
- ++i;
- }
+ for (i = 0; rpc->r_aliases[i]; ++i)
+ printf (" %s", rpc->r_aliases[i]);
fputs ("\n", stdout);
}
-static inline int
-hosts_keys (int number, char *key[])
+static int
+rpc_keys (int number, char *key[])
{
int result = 0;
int i;
+ struct rpcent *rpc;
- for (i = 0; i < number; ++i)
+ if (!number)
{
- struct hostent *host = NULL;
+ setrpcent (0);
+ while ((rpc = getrpcent()) != NULL)
+ print_rpc (rpc);
+ endrpcent ();
+ return result;
+ }
- if (strchr (key[i], ':') != NULL)
- {
- char addr[IN6ADDRSZ];
- if (inet_pton (AF_INET6, key[i], &addr))
- host = gethostbyaddr (addr, sizeof (addr), AF_INET6);
- }
- else if (isdigit (key[i][0]))
- {
- char addr[INADDRSZ];
- if (inet_pton (AF_INET, key[i], &addr))
- host = gethostbyaddr (addr, sizeof (addr), AF_INET);
- }
- else if ((host = gethostbyname2 (key[i], AF_INET6)) == NULL)
- host = gethostbyname2 (key[i], AF_INET);
+ for (i = 0; i < number; ++i)
+ {
+ if (isdigit (key[i][0]))
+ rpc = getrpcbynumber (atol (key[i]));
+ else
+ rpc = getrpcbyname (key[i]);
- if (host == NULL)
+ if (rpc == NULL)
result = 2;
else
- print_hosts (host);
+ print_rpc (rpc);
}
return result;
}
/* for services */
-static inline void
+static void
print_services (struct servent *serv)
{
unsigned int i;
fputs (serv->s_name, stdout);
- for (i = strlen (serv->s_name); i < 22; ++i)
+ for (i = strlen (serv->s_name); i < 21; ++i)
fputs (" ", stdout);
- printf ("%d/%s", ntohs (serv->s_port), serv->s_proto);
+ printf (" %d/%s", ntohs (serv->s_port), serv->s_proto);
i = 0;
while (serv->s_aliases[i] != NULL)
fputs ("\n", stdout);
}
-static inline int
+static int
services_keys (int number, char *key[])
{
int result = 0;
int i;
+ struct servent *serv;
+
+ if (!number)
+ {
+ setservent (0);
+ while ((serv = getservent()) != NULL)
+ print_services (serv);
+ endservent ();
+ return result;
+ }
for (i = 0; i < number; ++i)
{
}
else
{
+ int j;
+
while ((serv = getservent ()) != NULL)
if (strcmp (serv->s_name, key[i]) == 0)
{
print_services (serv);
break;
}
+ else
+ for (j = 0; serv->s_aliases[j]; ++j)
+ if (strcmp (serv->s_aliases[j], key[i]) == 0)
+ {
+ print_services (serv);
+ break;
+ }
}
endservent ();
}
return result;
}
-/* the main function */
-int
-main (int argc, char *argv[])
+/* This is for shadow */
+static inline void
+print_shadow (struct spwd *sp)
{
- int remaining;
-
- /* Set locale via LC_ALL. */
- setlocale (LC_ALL, "");
- /* Set the text message domain. */
- textdomain (PACKAGE);
+ printf ("%s:%s:",
+ sp->sp_namp ? sp->sp_namp : "",
+ sp->sp_pwdp ? sp->sp_pwdp : "");
+
+#define SHADOW_FIELD(n) \
+ if (sp->n == -1) \
+ fputs (":", stdout); \
+ else \
+ printf ("%ld:", sp->n)
+
+ SHADOW_FIELD (sp_lstchg);
+ SHADOW_FIELD (sp_min);
+ SHADOW_FIELD (sp_max);
+ SHADOW_FIELD (sp_warn);
+ SHADOW_FIELD (sp_inact);
+ SHADOW_FIELD (sp_expire);
+ if (sp->sp_flag == ~0ul)
+ fputs ("\n", stdout);
+ else
+ printf ("%lu\n", sp->sp_flag);
+}
- /* Parse and process arguments. */
- argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+static int
+shadow_keys (int number, char *key[])
+{
+ int result = 0;
+ int i;
- if ((argc - remaining) < 1)
+ if (!number)
{
- error (0, 0, gettext ("wrong number of arguments"));
- argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
- return 1;
+ struct spwd *sp;
+
+ setspent ();
+ while ((sp = getspent()) != NULL)
+ print_shadow (sp);
+ endpwent ();
+ return result;
}
- switch(argv[1][0])
+ for (i = 0; i < number; ++i)
{
- case 'g': /* group */
- if (strcmp (argv[1], "group") == 0)
- {
- if (argc == 2)
- {
- struct group *grp;
+ struct spwd *sp;
- setgrent ();
- while ((grp = getgrent()) != NULL)
- print_group (grp);
- endgrent ();
- }
- else
- return group_keys (argc - 2, &argv[2]);
- }
- else
- goto error;
- break;
- case 'h': /* hosts */
- if (strcmp (argv[1], "hosts") == 0)
- {
- if (argc == 2)
- {
- struct hostent *host;
+ sp = getspnam (key[i]);
- sethostent (0);
- while ((host = gethostent()) != NULL)
- print_hosts (host);
- endhostent ();
- }
- else
- return hosts_keys (argc - 2, &argv[2]);
- }
+ if (sp == NULL)
+ result = 2;
else
- goto error;
- break;
- case 'n': /* networks */
- if (strcmp (argv[1], "networks") == 0)
- {
- if (argc == 2)
- {
- struct netent *net;
+ print_shadow (sp);
+ }
- setnetent (0);
- while ((net = getnetent()) != NULL)
- print_networks (net);
- endnetent ();
- }
- else
- return networks_keys (argc - 2, &argv[2]);
- }
- else
- goto error;
- break;
- case 'p': /* passwd, protocols */
- if (strcmp (argv[1], "passwd") == 0)
- {
- if (argc == 2)
- {
- struct passwd *pwd;
+ return result;
+}
- setpwent ();
- while ((pwd = getpwent()) != NULL)
- print_passwd (pwd);
- endpwent ();
- }
- else
- return passwd_keys (argc - 2, &argv[2]);
- }
- else if (strcmp (argv[1], "protocols") == 0)
- {
- if (argc == 2)
- {
- struct protoent *proto;
+struct
+ {
+ const char *name;
+ int (*func) (int number, char *key[]);
+ } databases[] =
+ {
+#define D(name) { #name, name ## _keys },
+D(aliases)
+D(ethers)
+D(group)
+D(hosts)
+D(netgroup)
+D(networks)
+D(passwd)
+D(protocols)
+D(rpc)
+D(services)
+D(shadow)
+#undef D
+ { NULL, NULL }
+ };
+
+/* build doc */
+static inline void
+build_doc (void)
+{
+ int i, j, len;
+ char *short_doc, *long_doc, *doc, *p;
- setprotoent (0);
- while ((proto = getprotoent()) != NULL)
- print_protocols (proto);
- endprotoent ();
- }
- else
- return protocols_keys (argc - 2, &argv[2]);
- }
- else
- goto error;
- break;
- case 's': /* services */
- if (strcmp (argv[1], "services") == 0)
+ short_doc = _("getent - get entries from administrative database.");
+ long_doc = _("Supported databases:");
+ len = strlen (short_doc) + strlen (long_doc) + 3;
+
+ for (i = 0; databases[i].name; ++i)
+ len += strlen (databases[i].name) + 1;
+
+ doc = (char *) malloc (len);
+ if (!doc)
+ doc = short_doc;
+ else
+ {
+ p = stpcpy (doc, short_doc);
+ *p++ = '\v';
+ p = stpcpy (p, long_doc);
+ *p++ = '\n';
+
+ for (i = 0, j = 0; databases[i].name; ++i)
{
- if (argc == 2)
+ len = strlen (databases[i].name);
+ if (i)
{
- struct servent *serv;
-
- setservent (0);
- while ((serv = getservent()) != NULL)
- print_services (serv);
- endservent ();
+ if (j + len > 60)
+ {
+ j = 0;
+ *p++ = '\n';
+ }
+ else
+ *p++ = ' ';
}
- else
- return services_keys (argc - 2, &argv[2]);
+
+ memcpy (p, databases[i].name, len);
+ p += len;
+ j += len + 1;
}
- else
- goto error;
- break;
- default:
- error:
- fprintf (stderr, _("Unknown database: %s\n"), argv[1]);
+ }
+
+ argp.doc = doc;
+}
+
+/* the main function */
+int
+main (int argc, char *argv[])
+{
+ int remaining, i;
+
+ /* Set locale via LC_ALL. */
+ setlocale (LC_ALL, "");
+ /* Set the text message domain. */
+ textdomain (PACKAGE);
+
+ /* Build argp.doc. */
+ build_doc ();
+
+ /* Parse and process arguments. */
+ argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+ if ((argc - remaining) < 1)
+ {
+ error (0, 0, gettext ("wrong number of arguments"));
argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
return 1;
}
- return 0;
+ for (i = 0; databases[i].name; ++i)
+ if (argv[1][0] == databases[i].name[0]
+ && !strcmp (argv[1], databases[i].name))
+ return databases[i].func (argc - 2, &argv[2]);
+
+ fprintf (stderr, _("Unknown database: %s\n"), argv[1]);
+ argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
+ return 1;
}