1 /* Copyright (c) 1998, 1999, 2000 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
21 supported databases: passwd, group, hosts, services, protocols
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <arpa/inet.h>
38 #include <arpa/nameser.h>
40 /* Get libc version number. */
43 #define PACKAGE _libc_intl_domainname
45 /* Name and version of program. */
46 static void print_version (FILE *stream
, struct argp_state
*state
);
47 void (*argp_program_version_hook
) (FILE *, struct argp_state
*) = print_version
;
49 /* Short description of parameters. */
50 static const char args_doc
[] = N_("database [key ...]");
52 /* Short description of program. */
53 static const char doc
[] =
54 N_("getent - get entries from administrative database.");
56 /* Data structure to communicate with argp functions. */
57 static struct argp argp
= {
58 NULL
, NULL
, args_doc
, doc
,
61 /* Print the version information. */
63 print_version (FILE *stream
, struct argp_state
*state
)
65 fprintf (stream
, "getent (GNU %s) %s\n", PACKAGE
, VERSION
);
66 fprintf (stream
, gettext ("\
67 Copyright (C) %s Free Software Foundation, Inc.\n\
68 This is free software; see the source for copying conditions. There is NO\n\
69 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
71 fprintf (stream
, gettext ("Written by %s.\n"), "Thorsten Kukuk");
74 /* This is for group */
76 print_group (struct group
*grp
)
80 printf ("%s:%s:%ld:", grp
->gr_name
? grp
->gr_name
: "",
81 grp
->gr_passwd
? grp
->gr_passwd
: "",
82 (unsigned long)grp
->gr_gid
);
84 while (grp
->gr_mem
[i
] != NULL
)
86 fputs (grp
->gr_mem
[i
], stdout
);
88 if (grp
->gr_mem
[i
] != NULL
)
95 group_keys (int number
, char *key
[])
100 for (i
= 0; i
< number
; ++i
)
104 if (isdigit (key
[i
][0]))
105 grp
= getgrgid (atol (key
[i
]));
107 grp
= getgrnam (key
[i
]);
118 /* This is for networks */
120 print_networks (struct netent
*net
)
124 ip
.s_addr
= htonl (net
->n_net
);
126 fputs (net
->n_name
, stdout
);
127 for (i
= strlen (net
->n_name
); i
< 22; ++i
)
129 fputs (inet_ntoa (ip
), stdout
);
132 while (net
->n_aliases
[i
] != NULL
)
135 fputs (net
->n_aliases
[i
], stdout
);
137 if (net
->n_aliases
[i
] != NULL
)
140 fputs ("\n", stdout
);
144 networks_keys (int number
, char *key
[])
149 for (i
= 0; i
< number
; ++i
)
153 if (isdigit (key
[i
][0]))
154 net
= getnetbyaddr (inet_addr (key
[i
]), AF_UNIX
);
156 net
= getnetbyname (key
[i
]);
161 print_networks (net
);
167 /* Now is all for passwd */
169 print_passwd (struct passwd
*pwd
)
171 printf ("%s:%s:%ld:%ld:%s:%s:%s\n",
172 pwd
->pw_name
? pwd
->pw_name
: "",
173 pwd
->pw_passwd
? pwd
->pw_passwd
: "",
174 (unsigned long)pwd
->pw_uid
,
175 (unsigned long)pwd
->pw_gid
,
176 pwd
->pw_gecos
? pwd
->pw_gecos
: "",
177 pwd
->pw_dir
? pwd
->pw_dir
: "",
178 pwd
->pw_shell
? pwd
->pw_shell
: "");
182 passwd_keys (int number
, char *key
[])
187 for (i
= 0; i
< number
; ++i
)
191 if (isdigit (key
[i
][0]))
192 pwd
= getpwuid (atol (key
[i
]));
194 pwd
= getpwnam (key
[i
]);
205 /* This is for protocols */
207 print_protocols (struct protoent
*proto
)
211 fputs (proto
->p_name
, stdout
);
212 for (i
= strlen (proto
->p_name
); i
< 22; ++i
)
214 printf ("%d", proto
->p_proto
);
217 while (proto
->p_aliases
[i
] != NULL
)
220 fputs (proto
->p_aliases
[i
], stdout
);
223 fputs ("\n", stdout
);
227 protocols_keys (int number
, char *key
[])
232 for (i
= 0; i
< number
; ++i
)
234 struct protoent
*proto
;
236 if (isdigit (key
[i
][0]))
237 proto
= getprotobynumber (atol (key
[i
]));
239 proto
= getprotobyname (key
[i
]);
244 print_protocols (proto
);
250 /* This is for hosts */
252 print_hosts (struct hostent
*host
)
255 char buf
[INET6_ADDRSTRLEN
];
256 const char *ip
= inet_ntop (host
->h_addrtype
, host
->h_addr_list
[0],
260 for (i
= strlen (ip
); i
< 16; ++i
)
262 fputs (host
->h_name
, stdout
);
265 while (host
->h_aliases
[i
] != NULL
)
268 fputs (host
->h_aliases
[i
], stdout
);
271 fputs ("\n", stdout
);
275 hosts_keys (int number
, char *key
[])
280 for (i
= 0; i
< number
; ++i
)
282 struct hostent
*host
= NULL
;
284 if (strchr (key
[i
], ':') != NULL
)
286 char addr
[IN6ADDRSZ
];
287 if (inet_pton (AF_INET6
, key
[i
], &addr
))
288 host
= gethostbyaddr (addr
, sizeof (addr
), AF_INET6
);
290 else if (isdigit (key
[i
][0]))
293 if (inet_pton (AF_INET
, key
[i
], &addr
))
294 host
= gethostbyaddr (addr
, sizeof (addr
), AF_INET
);
296 else if ((host
= gethostbyname2 (key
[i
], AF_INET6
)) == NULL
)
297 host
= gethostbyname2 (key
[i
], AF_INET
);
310 print_services (struct servent
*serv
)
314 fputs (serv
->s_name
, stdout
);
315 for (i
= strlen (serv
->s_name
); i
< 22; ++i
)
317 printf ("%d/%s", ntohs (serv
->s_port
), serv
->s_proto
);
320 while (serv
->s_aliases
[i
] != NULL
)
323 fputs (serv
->s_aliases
[i
], stdout
);
326 fputs ("\n", stdout
);
330 services_keys (int number
, char *key
[])
335 for (i
= 0; i
< number
; ++i
)
337 struct servent
*serv
;
338 char *proto
= strchr (key
[i
], '/');
343 if (isdigit (key
[i
][0]))
345 int port
= htons (atol (key
[i
]));
346 while ((serv
= getservent ()) != NULL
)
347 if (serv
->s_port
== port
)
349 print_services (serv
);
355 while ((serv
= getservent ()) != NULL
)
356 if (strcmp (serv
->s_name
, key
[i
]) == 0)
358 print_services (serv
);
368 if (isdigit (key
[i
][0]))
369 serv
= getservbyport (atol (key
[i
]), proto
);
371 serv
= getservbyname (key
[i
], proto
);
376 print_services (serv
);
383 /* the main function */
385 main (int argc
, char *argv
[])
389 /* Set locale via LC_ALL. */
390 setlocale (LC_ALL
, "");
391 /* Set the text message domain. */
392 textdomain (PACKAGE
);
394 /* Parse and process arguments. */
395 argp_parse (&argp
, argc
, argv
, 0, &remaining
, NULL
);
397 if ((argc
- remaining
) < 1)
399 error (0, 0, gettext ("wrong number of arguments"));
400 argp_help (&argp
, stdout
, ARGP_HELP_SEE
, program_invocation_short_name
);
406 case 'g': /* group */
407 if (strcmp (argv
[1], "group") == 0)
414 while ((grp
= getgrent()) != NULL
)
419 return group_keys (argc
- 2, &argv
[2]);
424 case 'h': /* hosts */
425 if (strcmp (argv
[1], "hosts") == 0)
429 struct hostent
*host
;
432 while ((host
= gethostent()) != NULL
)
437 return hosts_keys (argc
- 2, &argv
[2]);
442 case 'n': /* networks */
443 if (strcmp (argv
[1], "networks") == 0)
450 while ((net
= getnetent()) != NULL
)
451 print_networks (net
);
455 return networks_keys (argc
- 2, &argv
[2]);
460 case 'p': /* passwd, protocols */
461 if (strcmp (argv
[1], "passwd") == 0)
468 while ((pwd
= getpwent()) != NULL
)
473 return passwd_keys (argc
- 2, &argv
[2]);
475 else if (strcmp (argv
[1], "protocols") == 0)
479 struct protoent
*proto
;
482 while ((proto
= getprotoent()) != NULL
)
483 print_protocols (proto
);
487 return protocols_keys (argc
- 2, &argv
[2]);
492 case 's': /* services */
493 if (strcmp (argv
[1], "services") == 0)
497 struct servent
*serv
;
500 while ((serv
= getservent()) != NULL
)
501 print_services (serv
);
505 return services_keys (argc
- 2, &argv
[2]);
512 fprintf (stderr
, _("Unknown database: %s\n"), argv
[1]);
513 argp_help (&argp
, stdout
, ARGP_HELP_SEE
, program_invocation_short_name
);