Document copyright year range notation in README.
[glibc.git] / nss / getent.c
blob7d9422373ceea7e5d202c0e8fcbcfb92eb690ffa
1 /* Copyright (c) 1998-2008, 2009, 2010, 2011 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 Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the 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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 /* getent: get entries from administrative database. */
22 #include <aliases.h>
23 #include <argp.h>
24 #include <ctype.h>
25 #include <error.h>
26 #include <grp.h>
27 #include <gshadow.h>
28 #include <libintl.h>
29 #include <locale.h>
30 #include <mcheck.h>
31 #include <netdb.h>
32 #include <pwd.h>
33 #include <shadow.h>
34 #include <stdbool.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <arpa/inet.h>
39 #include <arpa/nameser.h>
40 #include <netinet/ether.h>
41 #include <netinet/in.h>
42 #include <sys/socket.h>
44 /* Get libc version number. */
45 #include <version.h>
47 #define PACKAGE _libc_intl_domainname
49 /* Name and version of program. */
50 static void print_version (FILE *stream, struct argp_state *state);
51 void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
53 /* Short description of parameters. */
54 static const char args_doc[] = N_("database [key ...]");
56 /* Supported options. */
57 static const struct argp_option args_options[] =
59 { "service", 's', "CONFIG", 0, N_("Service configuration to be used") },
60 { "no-idn", 'i', NULL, 0, N_("disable IDN encoding") },
61 { NULL, 0, NULL, 0, NULL },
64 /* Short description of program. */
65 static const char doc[] = N_("Get entries from administrative database.");
67 /* Prototype for option handler. */
68 static error_t parse_option (int key, char *arg, struct argp_state *state);
70 /* Function to print some extra text in the help message. */
71 static char *more_help (int key, const char *text, void *input);
73 /* Data structure to communicate with argp functions. */
74 static struct argp argp =
76 args_options, parse_option, args_doc, doc, NULL, more_help
79 /* Additional getaddrinfo flags for IDN encoding. */
80 static int idn_flags = AI_IDN | AI_CANONIDN;
82 /* Print the version information. */
83 static void
84 print_version (FILE *stream, struct argp_state *state)
86 fprintf (stream, "getent (GNU %s) %s\n", PACKAGE, VERSION);
87 fprintf (stream, gettext ("\
88 Copyright (C) %s Free Software Foundation, Inc.\n\
89 This is free software; see the source for copying conditions. There is NO\n\
90 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
91 "), "2011");
92 fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk");
95 /* This is for aliases */
96 static inline void
97 print_aliases (struct aliasent *alias)
99 unsigned int i = 0;
101 printf ("%s: ", alias->alias_name);
102 for (i = strlen (alias->alias_name); i < 14; ++i)
103 fputs_unlocked (" ", stdout);
105 for (i = 0; i < alias->alias_members_len; ++i)
106 printf ("%s%s",
107 alias->alias_members [i],
108 i + 1 == alias->alias_members_len ? "\n" : ", ");
111 static int
112 aliases_keys (int number, char *key[])
114 int result = 0;
115 int i;
116 struct aliasent *alias;
118 if (number == 0)
120 setaliasent ();
121 while ((alias = getaliasent ()) != NULL)
122 print_aliases (alias);
123 endaliasent ();
124 return result;
127 for (i = 0; i < number; ++i)
129 alias = getaliasbyname (key[i]);
131 if (alias == NULL)
132 result = 2;
133 else
134 print_aliases (alias);
137 return result;
140 /* This is for ethers */
141 static int
142 ethers_keys (int number, char *key[])
144 int result = 0;
145 int i;
147 if (number == 0)
149 fprintf (stderr, _("Enumeration not supported on %s\n"), "ethers");
150 return 3;
153 for (i = 0; i < number; ++i)
155 struct ether_addr *ethp, eth;
156 char buffer [1024], *p;
158 ethp = ether_aton (key[i]);
159 if (ethp != NULL)
161 if (ether_ntohost (buffer, ethp))
163 result = 2;
164 continue;
166 p = buffer;
168 else
170 if (ether_hostton (key[i], &eth))
172 result = 2;
173 continue;
175 p = key[i];
176 ethp = &eth;
178 printf ("%s %s\n", ether_ntoa (ethp), p);
181 return result;
184 /* This is for group */
185 static inline void
186 print_group (struct group *grp)
188 unsigned int i = 0;
190 printf ("%s:%s:%lu:", grp->gr_name ? grp->gr_name : "",
191 grp->gr_passwd ? grp->gr_passwd : "",
192 (unsigned long int) grp->gr_gid);
194 while (grp->gr_mem[i] != NULL)
196 fputs_unlocked (grp->gr_mem[i], stdout);
197 ++i;
198 if (grp->gr_mem[i] != NULL)
199 putchar_unlocked (',');
201 putchar_unlocked ('\n');
204 static int
205 group_keys (int number, char *key[])
207 int result = 0;
208 int i;
209 struct group *grp;
211 if (number == 0)
213 setgrent ();
214 while ((grp = getgrent ()) != NULL)
215 print_group (grp);
216 endgrent ();
217 return result;
220 for (i = 0; i < number; ++i)
222 errno = 0;
223 char *ep;
224 gid_t arg_gid = strtoul(key[i], &ep, 10);
226 if (errno != EINVAL && *key[i] != '\0' && *ep == '\0')
227 /* Valid numeric gid. */
228 grp = getgrgid (arg_gid);
229 else
230 grp = getgrnam (key[i]);
232 if (grp == NULL)
233 result = 2;
234 else
235 print_group (grp);
238 return result;
241 /* This is for gshadow */
242 static void
243 print_gshadow (struct sgrp *sg)
245 unsigned int i = 0;
247 printf ("%s:%s:",
248 sg->sg_namp ? sg->sg_namp : "",
249 sg->sg_passwd ? sg->sg_passwd : "");
251 while (sg->sg_adm[i] != NULL)
253 fputs_unlocked (sg->sg_adm[i], stdout);
254 ++i;
255 if (sg->sg_adm[i] != NULL)
256 putchar_unlocked (',');
259 putchar_unlocked (':');
261 i = 0;
262 while (sg->sg_mem[i] != NULL)
264 fputs_unlocked (sg->sg_mem[i], stdout);
265 ++i;
266 if (sg->sg_mem[i] != NULL)
267 putchar_unlocked (',');
270 putchar_unlocked ('\n');
273 static int
274 gshadow_keys (int number, char *key[])
276 int result = 0;
277 int i;
279 if (number == 0)
281 struct sgrp *sg;
283 setsgent ();
284 while ((sg = getsgent ()) != NULL)
285 print_gshadow (sg);
286 endsgent ();
287 return result;
290 for (i = 0; i < number; ++i)
292 struct sgrp *sg;
294 sg = getsgnam (key[i]);
296 if (sg == NULL)
297 result = 2;
298 else
299 print_gshadow (sg);
302 return result;
305 /* This is for hosts */
306 static void
307 print_hosts (struct hostent *host)
309 unsigned int cnt;
311 for (cnt = 0; host->h_addr_list[cnt] != NULL; ++cnt)
313 char buf[INET6_ADDRSTRLEN];
314 const char *ip = inet_ntop (host->h_addrtype, host->h_addr_list[cnt],
315 buf, sizeof (buf));
317 printf ("%-15s %s", ip, host->h_name);
319 unsigned int i;
320 for (i = 0; host->h_aliases[i] != NULL; ++i)
322 putchar_unlocked (' ');
323 fputs_unlocked (host->h_aliases[i], stdout);
325 putchar_unlocked ('\n');
329 static int
330 hosts_keys (int number, char *key[])
332 int result = 0;
333 int i;
334 struct hostent *host;
336 if (number == 0)
338 sethostent (0);
339 while ((host = gethostent ()) != NULL)
340 print_hosts (host);
341 endhostent ();
342 return result;
345 for (i = 0; i < number; ++i)
347 struct hostent *host = NULL;
348 char addr[IN6ADDRSZ];
350 if (inet_pton (AF_INET6, key[i], &addr) > 0)
351 host = gethostbyaddr (addr, IN6ADDRSZ, AF_INET6);
352 else if (inet_pton (AF_INET, key[i], &addr) > 0)
353 host = gethostbyaddr (addr, INADDRSZ, AF_INET);
354 else if ((host = gethostbyname2 (key[i], AF_INET6)) == NULL)
355 host = gethostbyname2 (key[i], AF_INET);
357 if (host == NULL)
358 result = 2;
359 else
360 print_hosts (host);
363 return result;
366 /* This is for hosts, but using getaddrinfo */
367 static int
368 ahosts_keys_int (int af, int xflags, int number, char *key[])
370 int result = 0;
371 int i;
372 struct hostent *host;
374 if (number == 0)
376 sethostent (0);
377 while ((host = gethostent ()) != NULL)
378 print_hosts (host);
379 endhostent ();
380 return result;
383 struct addrinfo hint;
384 memset (&hint, '\0', sizeof (hint));
385 hint.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME
386 | idn_flags | xflags);
387 hint.ai_family = af;
389 for (i = 0; i < number; ++i)
391 struct addrinfo *res;
393 if (getaddrinfo (key[i], NULL, &hint, &res) != 0)
394 result = 2;
395 else
397 struct addrinfo *runp = res;
399 while (runp != NULL)
401 char sockbuf[20];
402 const char *sockstr;
403 if (runp->ai_socktype == SOCK_STREAM)
404 sockstr = "STREAM";
405 else if (runp->ai_socktype == SOCK_DGRAM)
406 sockstr = "DGRAM";
407 else if (runp->ai_socktype == SOCK_RAW)
408 sockstr = "RAW";
409 #ifdef SOCK_SEQPACKET
410 else if (runp->ai_socktype == SOCK_SEQPACKET)
411 sockstr = "SEQPACKET";
412 #endif
413 #ifdef SOCK_RDM
414 else if (runp->ai_socktype == SOCK_RDM)
415 sockstr = "RDM";
416 #endif
417 #ifdef SOCK_DCCP
418 else if (runp->ai_socktype == SOCK_DCCP)
419 sockstr = "DCCP";
420 #endif
421 #ifdef SOCK_PACKET
422 else if (runp->ai_socktype == SOCK_PACKET)
423 sockstr = "PACKET";
424 #endif
425 else
427 snprintf (sockbuf, sizeof (sockbuf), "%d",
428 runp->ai_socktype);
429 sockstr = sockbuf;
432 char buf[INET6_ADDRSTRLEN];
433 printf ("%-15s %-6s %s\n",
434 inet_ntop (runp->ai_family,
435 runp->ai_family == AF_INET
436 ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr
437 : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr,
438 buf, sizeof (buf)),
439 sockstr,
440 runp->ai_canonname ?: "");
442 runp = runp->ai_next;
445 freeaddrinfo (res);
449 return result;
452 static int
453 ahosts_keys (int number, char *key[])
455 return ahosts_keys_int (AF_UNSPEC, 0, number, key);
458 static int
459 ahostsv4_keys (int number, char *key[])
461 return ahosts_keys_int (AF_INET, 0, number, key);
464 static int
465 ahostsv6_keys (int number, char *key[])
467 return ahosts_keys_int (AF_INET6, AI_V4MAPPED, number, key);
470 /* This is for netgroup */
471 static int
472 netgroup_keys (int number, char *key[])
474 int result = 0;
476 if (number == 0)
478 fprintf (stderr, _("Enumeration not supported on %s\n"), "netgroup");
479 return 3;
482 if (number == 4)
484 char *host = strcmp (key[1], "*") == 0 ? NULL : key[1];
485 char *user = strcmp (key[2], "*") == 0 ? NULL : key[2];
486 char *domain = strcmp (key[3], "*") == 0 ? NULL : key[3];
488 printf ("%-21s (%s,%s,%s) = %d\n",
489 key[0], host ?: "", user ?: "", domain ?: "",
490 innetgr (key[0], host, user, domain));
492 else if (number == 1)
494 if (!setnetgrent (key[0]))
495 result = 2;
496 else
498 char *p[3];
500 printf ("%-21s", key[0]);
502 while (getnetgrent (p, p + 1, p + 2))
503 printf (" (%s,%s,%s)", p[0] ?: " ", p[1] ?: "", p[2] ?: "");
504 putchar_unlocked ('\n');
508 endnetgrent ();
510 return result;
513 /* This is for initgroups */
514 static int
515 initgroups_keys (int number, char *key[])
517 int ngrps = 100;
518 size_t grpslen = ngrps * sizeof (gid_t);
519 gid_t *grps = alloca (grpslen);
521 for (int i = 0; i < number; ++i)
523 int no = ngrps;
524 int n;
525 while ((n = getgrouplist (key[i], -1, grps, &no)) == -1
526 && no > ngrps)
528 grps = extend_alloca (grps, grpslen, no * sizeof (gid_t));
529 ngrps = no;
532 if (n == -1)
533 return 1;
535 printf ("%-21s", key[i]);
536 for (int j = 0; j < n; ++j)
537 if (grps[j] != -1)
538 printf (" %ld", (long int) grps[j]);
539 putchar_unlocked ('\n');
542 return 0;
545 /* This is for networks */
546 static void
547 print_networks (struct netent *net)
549 unsigned int i;
550 struct in_addr ip;
551 ip.s_addr = htonl (net->n_net);
553 printf ("%-21s %s", net->n_name, inet_ntoa (ip));
555 i = 0;
556 while (net->n_aliases[i] != NULL)
558 putchar_unlocked (' ');
559 fputs_unlocked (net->n_aliases[i], stdout);
560 ++i;
562 putchar_unlocked ('\n');
565 static int
566 networks_keys (int number, char *key[])
568 int result = 0;
569 int i;
570 struct netent *net;
572 if (number == 0)
574 setnetent (0);
575 while ((net = getnetent ()) != NULL)
576 print_networks (net);
577 endnetent ();
578 return result;
581 for (i = 0; i < number; ++i)
583 if (isdigit (key[i][0]))
584 net = getnetbyaddr (ntohl (inet_addr (key[i])), AF_UNSPEC);
585 else
586 net = getnetbyname (key[i]);
588 if (net == NULL)
589 result = 2;
590 else
591 print_networks (net);
594 return result;
597 /* Now is all for passwd */
598 static inline void
599 print_passwd (struct passwd *pwd)
601 printf ("%s:%s:%lu:%lu:%s:%s:%s\n",
602 pwd->pw_name ? pwd->pw_name : "",
603 pwd->pw_passwd ? pwd->pw_passwd : "",
604 (unsigned long int) pwd->pw_uid,
605 (unsigned long int) pwd->pw_gid,
606 pwd->pw_gecos ? pwd->pw_gecos : "",
607 pwd->pw_dir ? pwd->pw_dir : "",
608 pwd->pw_shell ? pwd->pw_shell : "");
611 static int
612 passwd_keys (int number, char *key[])
614 int result = 0;
615 int i;
616 struct passwd *pwd;
618 if (number == 0)
620 setpwent ();
621 while ((pwd = getpwent ()) != NULL)
622 print_passwd (pwd);
623 endpwent ();
624 return result;
627 for (i = 0; i < number; ++i)
629 errno = 0;
630 char *ep;
631 uid_t arg_uid = strtoul(key[i], &ep, 10);
633 if (errno != EINVAL && *key[i] != '\0' && *ep == '\0')
634 /* Valid numeric uid. */
635 pwd = getpwuid (arg_uid);
636 else
637 pwd = getpwnam (key[i]);
639 if (pwd == NULL)
640 result = 2;
641 else
642 print_passwd (pwd);
645 return result;
648 /* This is for protocols */
649 static inline void
650 print_protocols (struct protoent *proto)
652 unsigned int i;
654 printf ("%-21s %d", proto->p_name, proto->p_proto);
656 i = 0;
657 while (proto->p_aliases[i] != NULL)
659 putchar_unlocked (' ');
660 fputs_unlocked (proto->p_aliases[i], stdout);
661 ++i;
663 putchar_unlocked ('\n');
666 static int
667 protocols_keys (int number, char *key[])
669 int result = 0;
670 int i;
671 struct protoent *proto;
673 if (number == 0)
675 setprotoent (0);
676 while ((proto = getprotoent ()) != NULL)
677 print_protocols (proto);
678 endprotoent ();
679 return result;
682 for (i = 0; i < number; ++i)
684 if (isdigit (key[i][0]))
685 proto = getprotobynumber (atol (key[i]));
686 else
687 proto = getprotobyname (key[i]);
689 if (proto == NULL)
690 result = 2;
691 else
692 print_protocols (proto);
695 return result;
698 /* Now is all for rpc */
699 static inline void
700 print_rpc (struct rpcent *rpc)
702 int i;
704 printf ("%-15s %d%s",
705 rpc->r_name, rpc->r_number, rpc->r_aliases[0] ? " " : "");
707 for (i = 0; rpc->r_aliases[i]; ++i)
708 printf (" %s", rpc->r_aliases[i]);
709 putchar_unlocked ('\n');
712 static int
713 rpc_keys (int number, char *key[])
715 int result = 0;
716 int i;
717 struct rpcent *rpc;
719 if (number == 0)
721 setrpcent (0);
722 while ((rpc = getrpcent ()) != NULL)
723 print_rpc (rpc);
724 endrpcent ();
725 return result;
728 for (i = 0; i < number; ++i)
730 if (isdigit (key[i][0]))
731 rpc = getrpcbynumber (atol (key[i]));
732 else
733 rpc = getrpcbyname (key[i]);
735 if (rpc == NULL)
736 result = 2;
737 else
738 print_rpc (rpc);
741 return result;
744 /* for services */
745 static void
746 print_services (struct servent *serv)
748 unsigned int i;
750 printf ("%-21s %d/%s", serv->s_name, ntohs (serv->s_port), serv->s_proto);
752 i = 0;
753 while (serv->s_aliases[i] != NULL)
755 putchar_unlocked (' ');
756 fputs_unlocked (serv->s_aliases[i], stdout);
757 ++i;
759 putchar_unlocked ('\n');
762 static int
763 services_keys (int number, char *key[])
765 int result = 0;
766 int i;
767 struct servent *serv;
769 if (!number)
771 setservent (0);
772 while ((serv = getservent ()) != NULL)
773 print_services (serv);
774 endservent ();
775 return result;
778 for (i = 0; i < number; ++i)
780 struct servent *serv;
781 char *proto = strchr (key[i], '/');
783 if (proto != NULL)
784 *proto++ = '\0';
786 if (isdigit (key[i][0]))
787 serv = getservbyport (htons (atol (key[i])), proto);
788 else
789 serv = getservbyname (key[i], proto);
791 if (serv == NULL)
792 result = 2;
793 else
794 print_services (serv);
797 return result;
800 /* This is for shadow */
801 static void
802 print_shadow (struct spwd *sp)
804 printf ("%s:%s:",
805 sp->sp_namp ? sp->sp_namp : "",
806 sp->sp_pwdp ? sp->sp_pwdp : "");
808 #define SHADOW_FIELD(n) \
809 if (sp->n == -1) \
810 putchar_unlocked (':'); \
811 else \
812 printf ("%ld:", sp->n)
814 SHADOW_FIELD (sp_lstchg);
815 SHADOW_FIELD (sp_min);
816 SHADOW_FIELD (sp_max);
817 SHADOW_FIELD (sp_warn);
818 SHADOW_FIELD (sp_inact);
819 SHADOW_FIELD (sp_expire);
820 if (sp->sp_flag == ~0ul)
821 putchar_unlocked ('\n');
822 else
823 printf ("%lu\n", sp->sp_flag);
826 static int
827 shadow_keys (int number, char *key[])
829 int result = 0;
830 int i;
832 if (number == 0)
834 struct spwd *sp;
836 setspent ();
837 while ((sp = getspent ()) != NULL)
838 print_shadow (sp);
839 endpwent ();
840 return result;
843 for (i = 0; i < number; ++i)
845 struct spwd *sp;
847 sp = getspnam (key[i]);
849 if (sp == NULL)
850 result = 2;
851 else
852 print_shadow (sp);
855 return result;
858 struct
860 const char *name;
861 int (*func) (int number, char *key[]);
862 } databases[] =
864 #define D(name) { #name, name ## _keys },
865 D(ahosts)
866 D(ahostsv4)
867 D(ahostsv6)
868 D(aliases)
869 D(ethers)
870 D(group)
871 D(gshadow)
872 D(hosts)
873 D(initgroups)
874 D(netgroup)
875 D(networks)
876 D(passwd)
877 D(protocols)
878 D(rpc)
879 D(services)
880 D(shadow)
881 #undef D
882 { NULL, NULL }
885 /* Handle arguments found by argp. */
886 static error_t
887 parse_option (int key, char *arg, struct argp_state *state)
889 char *endp;
890 switch (key)
892 case 's':
893 endp = strchr (arg, ':');
894 if (endp == NULL)
895 /* No specific database, change them all. */
896 for (int i = 0; databases[i].name != NULL; ++i)
897 __nss_configure_lookup (databases[i].name, arg);
898 else
900 int i;
901 for (i = 0; databases[i].name != NULL; ++i)
902 if (strncmp (databases[i].name, arg, endp - arg) == 0)
904 __nss_configure_lookup (databases[i].name, endp + 1);
905 break;
907 if (databases[i].name == NULL)
908 error (EXIT_FAILURE, 0, gettext ("Unknown database name"));
910 break;
912 case 'i':
913 idn_flags = 0;
914 break;
916 default:
917 return ARGP_ERR_UNKNOWN;
920 return 0;
924 static char *
925 more_help (int key, const char *text, void *input)
927 switch (key)
929 size_t len;
930 char *doc;
931 FILE *fp;
933 case ARGP_KEY_HELP_EXTRA:
934 /* We print some extra information. */
935 fp = open_memstream (&doc, &len);
936 if (fp != NULL)
938 fputs_unlocked (_("Supported databases:\n"), fp);
940 for (int i = 0, col = 0; databases[i].name != NULL; ++i)
942 len = strlen (databases[i].name);
943 if (i != 0)
945 if (col + len > 72)
947 col = 0;
948 fputc_unlocked ('\n', fp);
950 else
951 fputc_unlocked (' ', fp);
954 fputs_unlocked (databases[i].name, fp);
955 col += len + 1;
958 fputs ("\n\n", fp);
960 fputs (gettext ("\
961 For bug reporting instructions, please see:\n\
962 <http://www.gnu.org/software/libc/bugs.html>.\n"), fp);
964 if (fclose (fp) == 0)
965 return doc;
967 break;
969 default:
970 break;
972 return (char *) text;
976 /* the main function */
978 main (int argc, char *argv[])
980 /* Debugging support. */
981 mtrace ();
983 /* Set locale via LC_ALL. */
984 setlocale (LC_ALL, "");
985 /* Set the text message domain. */
986 textdomain (PACKAGE);
988 /* Parse and process arguments. */
989 int remaining;
990 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
992 if ((argc - remaining) < 1)
994 error (0, 0, gettext ("wrong number of arguments"));
995 argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
996 return 1;
999 for (int i = 0; databases[i].name; ++i)
1000 if (argv[remaining][0] == databases[i].name[0]
1001 && !strcmp (argv[remaining], databases[i].name))
1002 return databases[i].func (argc - remaining - 1, &argv[remaining + 1]);
1004 fprintf (stderr, _("Unknown database: %s\n"), argv[remaining]);
1005 argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
1006 return 1;