diff --git a/ChangeLog b/ChangeLog index 82722de8a2..bff2892913 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2001-01-14 Jakub Jelinek + + * 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. + +2001-01-14 Thorsten Kukuk + + * sunrpc/xdr.c (xdr_long, xdr_u_long): Fix comments about this + functions. + +2001-01-03 Jakub Jelinek + + * sunrpc/xdr.c (xdr_long, xdr_u_long): Return FALSE if trying to + encode value which does not fit in the 32bit type. + 2001-01-15 Hiroyuki Machida * sysdeps/unix/sysv/linux/mips/register-dump.h (REGISTER_DUMP): diff --git a/nss/getent.c b/nss/getent.c index 5834d790a0..709293a8b6 100644 --- a/nss/getent.c +++ b/nss/getent.c @@ -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 , 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 #include #include #include +#include #include #include #include @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -49,13 +50,9 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; /* 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_state *state) 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; + + if (!number) + { + setgrent (); + while ((grp = getgrent()) != NULL) + print_group (grp); + endgrent (); + return result; + } for (i = 0; i < number; ++i) { - struct group *grp; - if (isdigit (key[i][0])) grp = getgrgid (atol (key[i])); else @@ -115,138 +211,6 @@ group_keys (int number, char *key[]) return result; } -/* This is for networks */ -static inline void -print_networks (struct netent *net) -{ - unsigned int i; - 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) - fputs (" ", stdout); - fputs (inet_ntoa (ip), stdout); - - i = 0; - while (net->n_aliases[i] != NULL) - { - fputs (" ", stdout); - fputs (net->n_aliases[i], stdout); - ++i; - if (net->n_aliases[i] != NULL) - fputs (",", stdout); - } - fputs ("\n", stdout); -} - -static inline int -networks_keys (int number, char *key[]) -{ - int result = 0; - int i; - - for (i = 0; i < number; ++i) - { - struct netent *net; - - if (isdigit (key[i][0])) - net = getnetbyaddr (inet_addr (key[i]), AF_UNIX); - else - net = getnetbyname (key[i]); - - if (net == NULL) - result = 2; - else - print_networks (net); - } - - return result; -} - -/* Now is all for passwd */ -static inline void -print_passwd (struct passwd *pwd) -{ - printf ("%s:%s:%ld:%ld:%s:%s:%s\n", - pwd->pw_name ? pwd->pw_name : "", - pwd->pw_passwd ? pwd->pw_passwd : "", - (unsigned long)pwd->pw_uid, - (unsigned long)pwd->pw_gid, - pwd->pw_gecos ? pwd->pw_gecos : "", - pwd->pw_dir ? pwd->pw_dir : "", - pwd->pw_shell ? pwd->pw_shell : ""); -} - -static inline int -passwd_keys (int number, char *key[]) -{ - int result = 0; - int i; - - for (i = 0; i < number; ++i) - { - struct passwd *pwd; - - if (isdigit (key[i][0])) - pwd = getpwuid (atol (key[i])); - else - pwd = getpwnam (key[i]); - - if (pwd == NULL) - result = 2; - else - print_passwd (pwd); - } - - return result; -} - -/* This is for protocols */ -static inline void -print_protocols (struct protoent *proto) -{ - unsigned int i; - - fputs (proto->p_name, stdout); - for (i = strlen (proto->p_name); i < 22; ++i) - fputs (" ", stdout); - printf ("%d", proto->p_proto); - - i = 0; - while (proto->p_aliases[i] != NULL) - { - fputs (" ", stdout); - fputs (proto->p_aliases[i], stdout); - ++i; - } - fputs ("\n", stdout); -} - -static inline int -protocols_keys (int number, char *key[]) -{ - int result = 0; - int i; - - for (i = 0; i < number; ++i) - { - struct protoent *proto; - - if (isdigit (key[i][0])) - proto = getprotobynumber (atol (key[i])); - else - proto = getprotobyname (key[i]); - - if (proto == NULL) - result = 2; - else - print_protocols (proto); - } - - return result; -} - /* This is for hosts */ static inline void print_hosts (struct hostent *host) @@ -272,11 +236,21 @@ print_hosts (struct hostent *host) fputs ("\n", stdout); } -static inline int +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) { @@ -306,16 +280,254 @@ hosts_keys (int number, char *key[]) return result; } -/* for services */ +/* 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) +{ + unsigned int i; + struct in_addr ip; + ip.s_addr = htonl (net->n_net); + + printf ("%s ", net->n_name); + for (i = strlen (net->n_name); i < 21; ++i) + fputs (" ", stdout); + fputs (inet_ntoa (ip), stdout); + + i = 0; + while (net->n_aliases[i] != NULL) + { + fputs (" ", stdout); + fputs (net->n_aliases[i], stdout); + ++i; + if (net->n_aliases[i] != NULL) + fputs (",", stdout); + } + fputs ("\n", stdout); +} + +static int +networks_keys (int number, char *key[]) +{ + int result = 0; + int i; + struct netent *net; + + if (!number) + { + 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 + net = getnetbyname (key[i]); + + if (net == NULL) + result = 2; + else + print_networks (net); + } + + return result; +} + +/* Now is all for passwd */ +static inline void +print_passwd (struct passwd *pwd) +{ + printf ("%s:%s:%ld:%ld:%s:%s:%s\n", + pwd->pw_name ? pwd->pw_name : "", + pwd->pw_passwd ? pwd->pw_passwd : "", + (unsigned long)pwd->pw_uid, + (unsigned long)pwd->pw_gid, + pwd->pw_gecos ? pwd->pw_gecos : "", + pwd->pw_dir ? pwd->pw_dir : "", + pwd->pw_shell ? pwd->pw_shell : ""); +} + +static int +passwd_keys (int number, char *key[]) +{ + int result = 0; + int i; + struct passwd *pwd; + + if (!number) + { + 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 + pwd = getpwnam (key[i]); + + if (pwd == NULL) + result = 2; + else + print_passwd (pwd); + } + + return result; +} + +/* This is for protocols */ +static inline void +print_protocols (struct protoent *proto) +{ + unsigned int i; + + fputs (proto->p_name, stdout); + for (i = strlen (proto->p_name); i < 21; ++i) + fputs (" ", stdout); + printf (" %d", proto->p_proto); + + i = 0; + while (proto->p_aliases[i] != NULL) + { + fputs (" ", stdout); + fputs (proto->p_aliases[i], stdout); + ++i; + } + fputs ("\n", stdout); +} + +static int +protocols_keys (int number, char *key[]) +{ + int result = 0; + int i; + struct protoent *proto; + + if (!number) + { + 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 + proto = getprotobyname (key[i]); + + if (proto == NULL) + result = 2; + else + print_protocols (proto); + } + + return result; +} + +/* Now is all for rpc */ +static inline void +print_rpc (struct rpcent *rpc) +{ + int i; + + fputs (rpc->r_name, stdout); + for (i = strlen (rpc->r_name); i < 15; ++i) + fputs (" ", stdout); + printf (" %d%s", rpc->r_number, rpc->r_aliases[0] ? " " : ""); + + for (i = 0; rpc->r_aliases[i]; ++i) + printf (" %s", rpc->r_aliases[i]); + fputs ("\n", stdout); +} + +static int +rpc_keys (int number, char *key[]) +{ + int result = 0; + int i; + struct rpcent *rpc; + + if (!number) + { + setrpcent (0); + while ((rpc = getrpcent()) != NULL) + print_rpc (rpc); + endrpcent (); + return result; + } + + for (i = 0; i < number; ++i) + { + if (isdigit (key[i][0])) + rpc = getrpcbynumber (atol (key[i])); + else + rpc = getrpcbyname (key[i]); + + if (rpc == NULL) + result = 2; + else + print_rpc (rpc); + } + + return result; +} + +/* for services */ +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,17 +612,147 @@ services_keys (int number, char *key[]) return result; } +/* This is for shadow */ +static inline void +print_shadow (struct spwd *sp) +{ + 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); +} + +static int +shadow_keys (int number, char *key[]) +{ + int result = 0; + int i; + + if (!number) + { + struct spwd *sp; + + setspent (); + while ((sp = getspent()) != NULL) + print_shadow (sp); + endpwent (); + return result; + } + + for (i = 0; i < number; ++i) + { + struct spwd *sp; + + sp = getspnam (key[i]); + + if (sp == NULL) + result = 2; + else + print_shadow (sp); + } + + return result; +} + +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; + + 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) + { + len = strlen (databases[i].name); + if (i) + { + if (j + len > 60) + { + j = 0; + *p++ = '\n'; + } + else + *p++ = ' '; + } + + memcpy (p, databases[i].name, len); + p += len; + j += len + 1; + } + } + + argp.doc = doc; +} + /* the main function */ int main (int argc, char *argv[]) { - int remaining; + 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); @@ -402,118 +763,12 @@ main (int argc, char *argv[]) return 1; } - switch(argv[1][0]) - { - case 'g': /* group */ - if (strcmp (argv[1], "group") == 0) - { - if (argc == 2) - { - struct group *grp; + 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]); - 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; - - sethostent (0); - while ((host = gethostent()) != NULL) - print_hosts (host); - endhostent (); - } - else - return hosts_keys (argc - 2, &argv[2]); - } - else - goto error; - break; - case 'n': /* networks */ - if (strcmp (argv[1], "networks") == 0) - { - if (argc == 2) - { - struct netent *net; - - 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; - - 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; - - 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) - { - if (argc == 2) - { - struct servent *serv; - - setservent (0); - while ((serv = getservent()) != NULL) - print_services (serv); - endservent (); - } - else - return services_keys (argc - 2, &argv[2]); - } - else - goto error; - break; - default: - error: - fprintf (stderr, _("Unknown database: %s\n"), argv[1]); - argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name); - return 1; - } - - return 0; + fprintf (stderr, _("Unknown database: %s\n"), argv[1]); + argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name); + return 1; }