1 /* Copyright (c) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
20 /* getent: get entries from administrative database. */
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <netinet/ether.h>
38 #include <arpa/inet.h>
39 #include <arpa/nameser.h>
41 /* Get libc version number. */
44 #define PACKAGE _libc_intl_domainname
46 /* Name and version of program. */
47 static void print_version (FILE *stream
, struct argp_state
*state
);
48 void (*argp_program_version_hook
) (FILE *, struct argp_state
*) = print_version
;
50 /* Short description of parameters. */
51 static const char args_doc
[] = N_("database [key ...]");
53 /* Data structure to communicate with argp functions. */
54 static struct argp argp
= {
55 NULL
, NULL
, args_doc
, NULL
,
58 /* Print the version information. */
60 print_version (FILE *stream
, struct argp_state
*state
)
62 fprintf (stream
, "getent (GNU %s) %s\n", PACKAGE
, VERSION
);
63 fprintf (stream
, gettext ("\
64 Copyright (C) %s Free Software Foundation, Inc.\n\
65 This is free software; see the source for copying conditions. There is NO\n\
66 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
68 fprintf (stream
, gettext ("Written by %s.\n"), "Thorsten Kukuk");
71 /* This is for aliases */
73 print_aliases (struct aliasent
*alias
)
77 printf ("%s: ", alias
->alias_name
);
78 for (i
= strlen (alias
->alias_name
); i
< 14; ++i
)
82 i
< alias
->alias_members_len
;
85 alias
->alias_members
[i
],
86 i
+ 1 == alias
->alias_members_len
? "\n" : ", ");
90 aliases_keys (int number
, char *key
[])
94 struct aliasent
*alias
;
99 while ((alias
= getaliasent()) != NULL
)
100 print_aliases (alias
);
105 for (i
= 0; i
< number
; ++i
)
107 alias
= getaliasbyname (key
[i
]);
112 print_aliases (alias
);
118 /* This is for ethers */
120 ethers_keys (int number
, char *key
[])
127 fprintf (stderr
, _("Enumeration not supported on %s\n"), "ethers");
131 for (i
= 0; i
< number
; ++i
)
133 struct ether_addr
*ethp
, eth
;
134 char buffer
[1024], *p
;
136 ethp
= ether_aton (key
[i
]);
139 if (ether_ntohost (buffer
, ethp
))
148 if (ether_hostton (key
[i
], ð
))
156 printf ("%s %s\n", ether_ntoa (ethp
), p
);
162 /* This is for group */
164 print_group (struct group
*grp
)
168 printf ("%s:%s:%ld:", grp
->gr_name
? grp
->gr_name
: "",
169 grp
->gr_passwd
? grp
->gr_passwd
: "",
170 (unsigned long)grp
->gr_gid
);
172 while (grp
->gr_mem
[i
] != NULL
)
174 fputs (grp
->gr_mem
[i
], stdout
);
176 if (grp
->gr_mem
[i
] != NULL
)
179 fputs ("\n", stdout
);
183 group_keys (int number
, char *key
[])
192 while ((grp
= getgrent()) != NULL
)
198 for (i
= 0; i
< number
; ++i
)
200 if (isdigit (key
[i
][0]))
201 grp
= getgrgid (atol (key
[i
]));
203 grp
= getgrnam (key
[i
]);
214 /* This is for hosts */
216 print_hosts (struct hostent
*host
)
219 char buf
[INET6_ADDRSTRLEN
];
220 const char *ip
= inet_ntop (host
->h_addrtype
, host
->h_addr_list
[0],
224 for (i
= strlen (ip
); i
< 15; ++i
)
227 fputs (host
->h_name
, stdout
);
230 while (host
->h_aliases
[i
] != NULL
)
233 fputs (host
->h_aliases
[i
], stdout
);
236 fputs ("\n", stdout
);
240 hosts_keys (int number
, char *key
[])
244 struct hostent
*host
;
249 while ((host
= gethostent()) != NULL
)
255 for (i
= 0; i
< number
; ++i
)
257 struct hostent
*host
= NULL
;
259 if (strchr (key
[i
], ':') != NULL
)
261 char addr
[IN6ADDRSZ
];
262 if (inet_pton (AF_INET6
, key
[i
], &addr
))
263 host
= gethostbyaddr (addr
, sizeof (addr
), AF_INET6
);
265 else if (isdigit (key
[i
][0]))
268 if (inet_pton (AF_INET
, key
[i
], &addr
))
269 host
= gethostbyaddr (addr
, sizeof (addr
), AF_INET
);
271 else if ((host
= gethostbyname2 (key
[i
], AF_INET6
)) == NULL
)
272 host
= gethostbyname2 (key
[i
], AF_INET
);
283 /* This is for netgroup */
285 netgroup_keys (int number
, char *key
[])
292 fprintf (stderr
, _("Enumeration not supported on %s\n"), "netgroup");
296 for (i
= 0; i
< number
; ++i
)
298 if (!setnetgrent (key
[i
]))
304 fputs (key
[i
], stdout
);
305 for (j
= strlen (key
[i
]); j
< 21; ++j
)
308 while (getnetgrent (p
, p
+ 1, p
+ 2))
309 printf (" (%s, %s, %s)", p
[0] ?: " ", p
[1] ?: "", p
[2] ?: "");
310 fputs ("\n", stdout
);
317 /* This is for networks */
319 print_networks (struct netent
*net
)
323 ip
.s_addr
= htonl (net
->n_net
);
325 printf ("%s ", net
->n_name
);
326 for (i
= strlen (net
->n_name
); i
< 21; ++i
)
328 fputs (inet_ntoa (ip
), stdout
);
331 while (net
->n_aliases
[i
] != NULL
)
334 fputs (net
->n_aliases
[i
], stdout
);
336 if (net
->n_aliases
[i
] != NULL
)
339 fputs ("\n", stdout
);
343 networks_keys (int number
, char *key
[])
352 while ((net
= getnetent()) != NULL
)
353 print_networks (net
);
358 for (i
= 0; i
< number
; ++i
)
360 if (isdigit (key
[i
][0]))
361 net
= getnetbyaddr (inet_addr (key
[i
]), AF_UNIX
);
363 net
= getnetbyname (key
[i
]);
368 print_networks (net
);
374 /* Now is all for passwd */
376 print_passwd (struct passwd
*pwd
)
378 printf ("%s:%s:%ld:%ld:%s:%s:%s\n",
379 pwd
->pw_name
? pwd
->pw_name
: "",
380 pwd
->pw_passwd
? pwd
->pw_passwd
: "",
381 (unsigned long)pwd
->pw_uid
,
382 (unsigned long)pwd
->pw_gid
,
383 pwd
->pw_gecos
? pwd
->pw_gecos
: "",
384 pwd
->pw_dir
? pwd
->pw_dir
: "",
385 pwd
->pw_shell
? pwd
->pw_shell
: "");
389 passwd_keys (int number
, char *key
[])
398 while ((pwd
= getpwent()) != NULL
)
404 for (i
= 0; i
< number
; ++i
)
406 if (isdigit (key
[i
][0]))
407 pwd
= getpwuid (atol (key
[i
]));
409 pwd
= getpwnam (key
[i
]);
420 /* This is for protocols */
422 print_protocols (struct protoent
*proto
)
426 fputs (proto
->p_name
, stdout
);
427 for (i
= strlen (proto
->p_name
); i
< 21; ++i
)
429 printf (" %d", proto
->p_proto
);
432 while (proto
->p_aliases
[i
] != NULL
)
435 fputs (proto
->p_aliases
[i
], stdout
);
438 fputs ("\n", stdout
);
442 protocols_keys (int number
, char *key
[])
446 struct protoent
*proto
;
451 while ((proto
= getprotoent()) != NULL
)
452 print_protocols (proto
);
457 for (i
= 0; i
< number
; ++i
)
459 if (isdigit (key
[i
][0]))
460 proto
= getprotobynumber (atol (key
[i
]));
462 proto
= getprotobyname (key
[i
]);
467 print_protocols (proto
);
473 /* Now is all for rpc */
475 print_rpc (struct rpcent
*rpc
)
479 fputs (rpc
->r_name
, stdout
);
480 for (i
= strlen (rpc
->r_name
); i
< 15; ++i
)
482 printf (" %d%s", rpc
->r_number
, rpc
->r_aliases
[0] ? " " : "");
484 for (i
= 0; rpc
->r_aliases
[i
]; ++i
)
485 printf (" %s", rpc
->r_aliases
[i
]);
486 fputs ("\n", stdout
);
490 rpc_keys (int number
, char *key
[])
499 while ((rpc
= getrpcent()) != NULL
)
505 for (i
= 0; i
< number
; ++i
)
507 if (isdigit (key
[i
][0]))
508 rpc
= getrpcbynumber (atol (key
[i
]));
510 rpc
= getrpcbyname (key
[i
]);
523 print_services (struct servent
*serv
)
527 fputs (serv
->s_name
, stdout
);
528 for (i
= strlen (serv
->s_name
); i
< 21; ++i
)
530 printf (" %d/%s", ntohs (serv
->s_port
), serv
->s_proto
);
533 while (serv
->s_aliases
[i
] != NULL
)
536 fputs (serv
->s_aliases
[i
], stdout
);
539 fputs ("\n", stdout
);
543 services_keys (int number
, char *key
[])
547 struct servent
*serv
;
552 while ((serv
= getservent()) != NULL
)
553 print_services (serv
);
558 for (i
= 0; i
< number
; ++i
)
560 struct servent
*serv
;
561 char *proto
= strchr (key
[i
], '/');
566 if (isdigit (key
[i
][0]))
568 int port
= htons (atol (key
[i
]));
569 while ((serv
= getservent ()) != NULL
)
570 if (serv
->s_port
== port
)
572 print_services (serv
);
580 while ((serv
= getservent ()) != NULL
)
581 if (strcmp (serv
->s_name
, key
[i
]) == 0)
583 print_services (serv
);
587 for (j
= 0; serv
->s_aliases
[j
]; ++j
)
588 if (strcmp (serv
->s_aliases
[j
], key
[i
]) == 0)
590 print_services (serv
);
600 if (isdigit (key
[i
][0]))
601 serv
= getservbyport (htons (atol (key
[i
])), proto
);
603 serv
= getservbyname (key
[i
], proto
);
608 print_services (serv
);
615 /* This is for shadow */
617 print_shadow (struct spwd
*sp
)
620 sp
->sp_namp
? sp
->sp_namp
: "",
621 sp
->sp_pwdp
? sp
->sp_pwdp
: "");
623 #define SHADOW_FIELD(n) \
625 fputs (":", stdout); \
627 printf ("%ld:", sp->n)
629 SHADOW_FIELD (sp_lstchg
);
630 SHADOW_FIELD (sp_min
);
631 SHADOW_FIELD (sp_max
);
632 SHADOW_FIELD (sp_warn
);
633 SHADOW_FIELD (sp_inact
);
634 SHADOW_FIELD (sp_expire
);
635 if (sp
->sp_flag
== ~0ul)
636 fputs ("\n", stdout
);
638 printf ("%lu\n", sp
->sp_flag
);
642 shadow_keys (int number
, char *key
[])
652 while ((sp
= getspent()) != NULL
)
658 for (i
= 0; i
< number
; ++i
)
662 sp
= getspnam (key
[i
]);
676 int (*func
) (int number
, char *key
[]);
679 #define D(name) { #name, name ## _keys },
700 char *short_doc
, *long_doc
, *doc
, *p
;
702 short_doc
= _("getent - get entries from administrative database.");
703 long_doc
= _("Supported databases:");
704 len
= strlen (short_doc
) + strlen (long_doc
) + 3;
706 for (i
= 0; databases
[i
].name
; ++i
)
707 len
+= strlen (databases
[i
].name
) + 1;
709 doc
= (char *) malloc (len
);
714 p
= stpcpy (doc
, short_doc
);
716 p
= stpcpy (p
, long_doc
);
719 for (i
= 0, j
= 0; databases
[i
].name
; ++i
)
721 len
= strlen (databases
[i
].name
);
733 memcpy (p
, databases
[i
].name
, len
);
742 /* the main function */
744 main (int argc
, char *argv
[])
748 /* Set locale via LC_ALL. */
749 setlocale (LC_ALL
, "");
750 /* Set the text message domain. */
751 textdomain (PACKAGE
);
753 /* Build argp.doc. */
756 /* Parse and process arguments. */
757 argp_parse (&argp
, argc
, argv
, 0, &remaining
, NULL
);
759 if ((argc
- remaining
) < 1)
761 error (0, 0, gettext ("wrong number of arguments"));
762 argp_help (&argp
, stdout
, ARGP_HELP_SEE
, program_invocation_short_name
);
766 for (i
= 0; databases
[i
].name
; ++i
)
767 if (argv
[1][0] == databases
[i
].name
[0]
768 && !strcmp (argv
[1], databases
[i
].name
))
769 return databases
[i
].func (argc
- 2, &argv
[2]);
771 fprintf (stderr
, _("Unknown database: %s\n"), argv
[1]);
772 argp_help (&argp
, stdout
, ARGP_HELP_SEE
, program_invocation_short_name
);