This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Hi!
This patch adds aliases, ethers, netgroup, rpc and shadow support to getent
plus fixes services (it would not look into service aliases unless explicit
protocol was given). Also, it makes getent --help print the supported
databases. ethers and netgroup don't support list all (you have to provide
at least one key for them), this matches Solaris getent behaviour (well, it
supports only ethers that way).
2001-01-14 Jakub Jelinek <jakub@redhat.com>
* nss/getent.c (print_aliases, aliases_keys, ethers_keys,
netgroup_keys, print_rpc, rpc_keys, print_shadow, shadow_keys):
New functions.
(group_keys, hosts_keys, network_keys, passwd_keys, protocols_keys):
If number is 0, list all.
(services_keys): Likewise. Lookup aliases as well.
(databases): New table.
(build_doc): Prepare argp doc text with list of supported databases.
(main): Change to table driven processing.
--- libc/nss/getent.c.jj Sat Jan 13 00:07:42 2001
+++ libc/nss/getent.c Sun Jan 14 23:50:33 2001
@@ -1,4 +1,4 @@
-/* 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.
@@ -17,13 +17,13 @@
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>
@@ -34,6 +34,7 @@
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <netinet/ether.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
@@ -49,13 +50,9 @@ void (*argp_program_version_hook) (FILE
/* 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. */
@@ -67,10 +64,101 @@ print_version (FILE *stream, struct argp
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)
@@ -91,16 +179,24 @@ 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
@@ -115,6 +211,109 @@ group_keys (int number, char *key[])
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)
@@ -123,8 +322,8 @@ 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);
@@ -140,16 +339,24 @@ print_networks (struct netent *net)
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
@@ -178,16 +385,24 @@ print_passwd (struct passwd *pwd)
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
@@ -209,9 +424,9 @@ print_protocols (struct protoent *proto)
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)
@@ -223,16 +438,24 @@ print_protocols (struct protoent *proto)
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
@@ -247,75 +470,64 @@ protocols_keys (int number, char *key[])
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)
@@ -327,11 +539,21 @@ print_services (struct servent *serv)
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)
{
@@ -353,12 +575,21 @@ services_keys (int number, char *key[])
}
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 ();
}
@@ -381,139 +612,163 @@ services_keys (int number, char *key[])
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 }
+ };
- 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)
+/* build doc */
+static inline void
+build_doc (void)
+{
+ int i, j, len;
+ char *short_doc, *long_doc, *doc, *p;
+
+ 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;
}
Jakub
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |