Use sysdeps/x86/tininess.h for i386 and x86_64
[glibc.git] / nss / getent.c
blobe88356dd2b2ffb2cadc0fd1532a922dc7fc0e1c6
1 /* Copyright (c) 1998-2011, 2012 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, see
17 <http://www.gnu.org/licenses/>. */
19 /* getent: get entries from administrative database. */
21 #include <aliases.h>
22 #include <argp.h>
23 #include <ctype.h>
24 #include <error.h>
25 #include <grp.h>
26 #include <gshadow.h>
27 #include <libintl.h>
28 #include <locale.h>
29 #include <mcheck.h>
30 #include <netdb.h>
31 #include <pwd.h>
32 #include <shadow.h>
33 #include <stdbool.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <arpa/inet.h>
38 #include <arpa/nameser.h>
39 #include <netinet/ether.h>
40 #include <netinet/in.h>
41 #include <sys/socket.h>
43 /* Get libc version number. */
44 #include <version.h>
46 #define PACKAGE _libc_intl_domainname
48 /* Name and version of program. */
49 static void print_version (FILE *stream, struct argp_state *state);
50 void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
52 /* Short description of parameters. */
53 static const char args_doc[] = N_("database [key ...]");
55 /* Supported options. */
56 static const struct argp_option args_options[] =
58 { "service", 's', "CONFIG", 0, N_("Service configuration to be used") },
59 { "no-idn", 'i', NULL, 0, N_("disable IDN encoding") },
60 { NULL, 0, NULL, 0, NULL },
63 /* Short description of program. */
64 static const char doc[] = N_("Get entries from administrative database.");
66 /* Prototype for option handler. */
67 static error_t parse_option (int key, char *arg, struct argp_state *state);
69 /* Function to print some extra text in the help message. */
70 static char *more_help (int key, const char *text, void *input);
72 /* Data structure to communicate with argp functions. */
73 static struct argp argp =
75 args_options, parse_option, args_doc, doc, NULL, more_help
78 /* Additional getaddrinfo flags for IDN encoding. */
79 static int idn_flags = AI_IDN | AI_CANONIDN;
81 /* Print the version information. */
82 static void
83 print_version (FILE *stream, struct argp_state *state)
85 fprintf (stream, "getent (GNU %s) %s\n", PACKAGE, VERSION);
86 fprintf (stream, gettext ("\
87 Copyright (C) %s Free Software Foundation, Inc.\n\
88 This is free software; see the source for copying conditions. There is NO\n\
89 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
90 "), "2012");
91 fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk");
94 /* This is for aliases */
95 static inline void
96 print_aliases (struct aliasent *alias)
98 unsigned int i = 0;
100 printf ("%s: ", alias->alias_name);
101 for (i = strlen (alias->alias_name); i < 14; ++i)
102 fputs_unlocked (" ", stdout);
104 for (i = 0; i < alias->alias_members_len; ++i)
105 printf ("%s%s",
106 alias->alias_members [i],
107 i + 1 == alias->alias_members_len ? "\n" : ", ");
110 static int
111 aliases_keys (int number, char *key[])
113 int result = 0;
114 int i;
115 struct aliasent *alias;
117 if (number == 0)
119 setaliasent ();
120 while ((alias = getaliasent ()) != NULL)
121 print_aliases (alias);
122 endaliasent ();
123 return result;
126 for (i = 0; i < number; ++i)
128 alias = getaliasbyname (key[i]);
130 if (alias == NULL)
131 result = 2;
132 else
133 print_aliases (alias);
136 return result;
139 /* This is for ethers */
140 static int
141 ethers_keys (int number, char *key[])
143 int result = 0;
144 int i;
146 if (number == 0)
148 fprintf (stderr, _("Enumeration not supported on %s\n"), "ethers");
149 return 3;
152 for (i = 0; i < number; ++i)
154 struct ether_addr *ethp, eth;
155 char buffer [1024], *p;
157 ethp = ether_aton (key[i]);
158 if (ethp != NULL)
160 if (ether_ntohost (buffer, ethp))
162 result = 2;
163 continue;
165 p = buffer;
167 else
169 if (ether_hostton (key[i], &eth))
171 result = 2;
172 continue;
174 p = key[i];
175 ethp = &eth;
177 printf ("%s %s\n", ether_ntoa (ethp), p);
180 return result;
183 /* This is for group */
184 static inline void
185 print_group (struct group *grp)
187 unsigned int i = 0;
189 printf ("%s:%s:%lu:", grp->gr_name ? grp->gr_name : "",
190 grp->gr_passwd ? grp->gr_passwd : "",
191 (unsigned long int) grp->gr_gid);
193 while (grp->gr_mem[i] != NULL)
195 fputs_unlocked (grp->gr_mem[i], stdout);
196 ++i;
197 if (grp->gr_mem[i] != NULL)
198 putchar_unlocked (',');
200 putchar_unlocked ('\n');
203 static int
204 group_keys (int number, char *key[])
206 int result = 0;
207 int i;
208 struct group *grp;
210 if (number == 0)
212 setgrent ();
213 while ((grp = getgrent ()) != NULL)
214 print_group (grp);
215 endgrent ();
216 return result;
219 for (i = 0; i < number; ++i)
221 errno = 0;
222 char *ep;
223 gid_t arg_gid = strtoul(key[i], &ep, 10);
225 if (errno != EINVAL && *key[i] != '\0' && *ep == '\0')
226 /* Valid numeric gid. */
227 grp = getgrgid (arg_gid);
228 else
229 grp = getgrnam (key[i]);
231 if (grp == NULL)
232 result = 2;
233 else
234 print_group (grp);
237 return result;
240 /* This is for gshadow */
241 static void
242 print_gshadow (struct sgrp *sg)
244 unsigned int i = 0;
246 printf ("%s:%s:",
247 sg->sg_namp ? sg->sg_namp : "",
248 sg->sg_passwd ? sg->sg_passwd : "");
250 while (sg->sg_adm[i] != NULL)
252 fputs_unlocked (sg->sg_adm[i], stdout);
253 ++i;
254 if (sg->sg_adm[i] != NULL)
255 putchar_unlocked (',');
258 putchar_unlocked (':');
260 i = 0;
261 while (sg->sg_mem[i] != NULL)
263 fputs_unlocked (sg->sg_mem[i], stdout);
264 ++i;
265 if (sg->sg_mem[i] != NULL)
266 putchar_unlocked (',');
269 putchar_unlocked ('\n');
272 static int
273 gshadow_keys (int number, char *key[])
275 int result = 0;
276 int i;
278 if (number == 0)
280 struct sgrp *sg;
282 setsgent ();
283 while ((sg = getsgent ()) != NULL)
284 print_gshadow (sg);
285 endsgent ();
286 return result;
289 for (i = 0; i < number; ++i)
291 struct sgrp *sg;
293 sg = getsgnam (key[i]);
295 if (sg == NULL)
296 result = 2;
297 else
298 print_gshadow (sg);
301 return result;
304 /* This is for hosts */
305 static void
306 print_hosts (struct hostent *host)
308 unsigned int cnt;
310 for (cnt = 0; host->h_addr_list[cnt] != NULL; ++cnt)
312 char buf[INET6_ADDRSTRLEN];
313 const char *ip = inet_ntop (host->h_addrtype, host->h_addr_list[cnt],
314 buf, sizeof (buf));
316 printf ("%-15s %s", ip, host->h_name);
318 unsigned int i;
319 for (i = 0; host->h_aliases[i] != NULL; ++i)
321 putchar_unlocked (' ');
322 fputs_unlocked (host->h_aliases[i], stdout);
324 putchar_unlocked ('\n');
328 static int
329 hosts_keys (int number, char *key[])
331 int result = 0;
332 int i;
333 struct hostent *host;
335 if (number == 0)
337 sethostent (0);
338 while ((host = gethostent ()) != NULL)
339 print_hosts (host);
340 endhostent ();
341 return result;
344 for (i = 0; i < number; ++i)
346 struct hostent *host = NULL;
347 char addr[IN6ADDRSZ];
349 if (inet_pton (AF_INET6, key[i], &addr) > 0)
350 host = gethostbyaddr (addr, IN6ADDRSZ, AF_INET6);
351 else if (inet_pton (AF_INET, key[i], &addr) > 0)
352 host = gethostbyaddr (addr, INADDRSZ, AF_INET);
353 else if ((host = gethostbyname2 (key[i], AF_INET6)) == NULL)
354 host = gethostbyname2 (key[i], AF_INET);
356 if (host == NULL)
357 result = 2;
358 else
359 print_hosts (host);
362 return result;
365 /* This is for hosts, but using getaddrinfo */
366 static int
367 ahosts_keys_int (int af, int xflags, int number, char *key[])
369 int result = 0;
370 int i;
371 struct hostent *host;
373 if (number == 0)
375 sethostent (0);
376 while ((host = gethostent ()) != NULL)
377 print_hosts (host);
378 endhostent ();
379 return result;
382 struct addrinfo hint;
383 memset (&hint, '\0', sizeof (hint));
384 hint.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME
385 | idn_flags | xflags);
386 hint.ai_family = af;
388 for (i = 0; i < number; ++i)
390 struct addrinfo *res;
392 if (getaddrinfo (key[i], NULL, &hint, &res) != 0)
393 result = 2;
394 else
396 struct addrinfo *runp = res;
398 while (runp != NULL)
400 char sockbuf[20];
401 const char *sockstr;
402 if (runp->ai_socktype == SOCK_STREAM)
403 sockstr = "STREAM";
404 else if (runp->ai_socktype == SOCK_DGRAM)
405 sockstr = "DGRAM";
406 else if (runp->ai_socktype == SOCK_RAW)
407 sockstr = "RAW";
408 #ifdef SOCK_SEQPACKET
409 else if (runp->ai_socktype == SOCK_SEQPACKET)
410 sockstr = "SEQPACKET";
411 #endif
412 #ifdef SOCK_RDM
413 else if (runp->ai_socktype == SOCK_RDM)
414 sockstr = "RDM";
415 #endif
416 #ifdef SOCK_DCCP
417 else if (runp->ai_socktype == SOCK_DCCP)
418 sockstr = "DCCP";
419 #endif
420 #ifdef SOCK_PACKET
421 else if (runp->ai_socktype == SOCK_PACKET)
422 sockstr = "PACKET";
423 #endif
424 else
426 snprintf (sockbuf, sizeof (sockbuf), "%d",
427 runp->ai_socktype);
428 sockstr = sockbuf;
431 char buf[INET6_ADDRSTRLEN];
432 printf ("%-15s %-6s %s\n",
433 inet_ntop (runp->ai_family,
434 runp->ai_family == AF_INET
435 ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr
436 : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr,
437 buf, sizeof (buf)),
438 sockstr,
439 runp->ai_canonname ?: "");
441 runp = runp->ai_next;
444 freeaddrinfo (res);
448 return result;
451 static int
452 ahosts_keys (int number, char *key[])
454 return ahosts_keys_int (AF_UNSPEC, 0, number, key);
457 static int
458 ahostsv4_keys (int number, char *key[])
460 return ahosts_keys_int (AF_INET, 0, number, key);
463 static int
464 ahostsv6_keys (int number, char *key[])
466 return ahosts_keys_int (AF_INET6, AI_V4MAPPED, number, key);
469 /* This is for netgroup */
470 static int
471 netgroup_keys (int number, char *key[])
473 int result = 0;
475 if (number == 0)
477 fprintf (stderr, _("Enumeration not supported on %s\n"), "netgroup");
478 return 3;
481 if (number == 4)
483 char *host = strcmp (key[1], "*") == 0 ? NULL : key[1];
484 char *user = strcmp (key[2], "*") == 0 ? NULL : key[2];
485 char *domain = strcmp (key[3], "*") == 0 ? NULL : key[3];
487 printf ("%-21s (%s,%s,%s) = %d\n",
488 key[0], host ?: "", user ?: "", domain ?: "",
489 innetgr (key[0], host, user, domain));
491 else if (number == 1)
493 if (!setnetgrent (key[0]))
494 result = 2;
495 else
497 char *p[3];
499 printf ("%-21s", key[0]);
501 while (getnetgrent (p, p + 1, p + 2))
502 printf (" (%s,%s,%s)", p[0] ?: " ", p[1] ?: "", p[2] ?: "");
503 putchar_unlocked ('\n');
507 endnetgrent ();
509 return result;
512 /* This is for initgroups */
513 static int
514 initgroups_keys (int number, char *key[])
516 int ngrps = 100;
517 size_t grpslen = ngrps * sizeof (gid_t);
518 gid_t *grps = alloca (grpslen);
520 if (number == 0)
522 fprintf (stderr, _("Enumeration not supported on %s\n"), "initgroups");
523 return 3;
526 for (int i = 0; i < number; ++i)
528 int no = ngrps;
529 int n;
530 while ((n = getgrouplist (key[i], -1, grps, &no)) == -1
531 && no > ngrps)
533 grps = extend_alloca (grps, grpslen, no * sizeof (gid_t));
534 ngrps = no;
537 if (n == -1)
538 return 1;
540 printf ("%-21s", key[i]);
541 for (int j = 0; j < n; ++j)
542 if (grps[j] != -1)
543 printf (" %ld", (long int) grps[j]);
544 putchar_unlocked ('\n');
547 return 0;
550 /* This is for networks */
551 static void
552 print_networks (struct netent *net)
554 unsigned int i;
555 struct in_addr ip;
556 ip.s_addr = htonl (net->n_net);
558 printf ("%-21s %s", net->n_name, inet_ntoa (ip));
560 i = 0;
561 while (net->n_aliases[i] != NULL)
563 putchar_unlocked (' ');
564 fputs_unlocked (net->n_aliases[i], stdout);
565 ++i;
567 putchar_unlocked ('\n');
570 static int
571 networks_keys (int number, char *key[])
573 int result = 0;
574 int i;
575 struct netent *net;
577 if (number == 0)
579 setnetent (0);
580 while ((net = getnetent ()) != NULL)
581 print_networks (net);
582 endnetent ();
583 return result;
586 for (i = 0; i < number; ++i)
588 if (isdigit (key[i][0]))
589 net = getnetbyaddr (ntohl (inet_addr (key[i])), AF_UNSPEC);
590 else
591 net = getnetbyname (key[i]);
593 if (net == NULL)
594 result = 2;
595 else
596 print_networks (net);
599 return result;
602 /* Now is all for passwd */
603 static inline void
604 print_passwd (struct passwd *pwd)
606 printf ("%s:%s:%lu:%lu:%s:%s:%s\n",
607 pwd->pw_name ? pwd->pw_name : "",
608 pwd->pw_passwd ? pwd->pw_passwd : "",
609 (unsigned long int) pwd->pw_uid,
610 (unsigned long int) pwd->pw_gid,
611 pwd->pw_gecos ? pwd->pw_gecos : "",
612 pwd->pw_dir ? pwd->pw_dir : "",
613 pwd->pw_shell ? pwd->pw_shell : "");
616 static int
617 passwd_keys (int number, char *key[])
619 int result = 0;
620 int i;
621 struct passwd *pwd;
623 if (number == 0)
625 setpwent ();
626 while ((pwd = getpwent ()) != NULL)
627 print_passwd (pwd);
628 endpwent ();
629 return result;
632 for (i = 0; i < number; ++i)
634 errno = 0;
635 char *ep;
636 uid_t arg_uid = strtoul(key[i], &ep, 10);
638 if (errno != EINVAL && *key[i] != '\0' && *ep == '\0')
639 /* Valid numeric uid. */
640 pwd = getpwuid (arg_uid);
641 else
642 pwd = getpwnam (key[i]);
644 if (pwd == NULL)
645 result = 2;
646 else
647 print_passwd (pwd);
650 return result;
653 /* This is for protocols */
654 static inline void
655 print_protocols (struct protoent *proto)
657 unsigned int i;
659 printf ("%-21s %d", proto->p_name, proto->p_proto);
661 i = 0;
662 while (proto->p_aliases[i] != NULL)
664 putchar_unlocked (' ');
665 fputs_unlocked (proto->p_aliases[i], stdout);
666 ++i;
668 putchar_unlocked ('\n');
671 static int
672 protocols_keys (int number, char *key[])
674 int result = 0;
675 int i;
676 struct protoent *proto;
678 if (number == 0)
680 setprotoent (0);
681 while ((proto = getprotoent ()) != NULL)
682 print_protocols (proto);
683 endprotoent ();
684 return result;
687 for (i = 0; i < number; ++i)
689 if (isdigit (key[i][0]))
690 proto = getprotobynumber (atol (key[i]));
691 else
692 proto = getprotobyname (key[i]);
694 if (proto == NULL)
695 result = 2;
696 else
697 print_protocols (proto);
700 return result;
703 /* Now is all for rpc */
704 static inline void
705 print_rpc (struct rpcent *rpc)
707 int i;
709 printf ("%-15s %d%s",
710 rpc->r_name, rpc->r_number, rpc->r_aliases[0] ? " " : "");
712 for (i = 0; rpc->r_aliases[i]; ++i)
713 printf (" %s", rpc->r_aliases[i]);
714 putchar_unlocked ('\n');
717 static int
718 rpc_keys (int number, char *key[])
720 int result = 0;
721 int i;
722 struct rpcent *rpc;
724 if (number == 0)
726 setrpcent (0);
727 while ((rpc = getrpcent ()) != NULL)
728 print_rpc (rpc);
729 endrpcent ();
730 return result;
733 for (i = 0; i < number; ++i)
735 if (isdigit (key[i][0]))
736 rpc = getrpcbynumber (atol (key[i]));
737 else
738 rpc = getrpcbyname (key[i]);
740 if (rpc == NULL)
741 result = 2;
742 else
743 print_rpc (rpc);
746 return result;
749 /* for services */
750 static void
751 print_services (struct servent *serv)
753 unsigned int i;
755 printf ("%-21s %d/%s", serv->s_name, ntohs (serv->s_port), serv->s_proto);
757 i = 0;
758 while (serv->s_aliases[i] != NULL)
760 putchar_unlocked (' ');
761 fputs_unlocked (serv->s_aliases[i], stdout);
762 ++i;
764 putchar_unlocked ('\n');
767 static int
768 services_keys (int number, char *key[])
770 int result = 0;
771 int i;
772 struct servent *serv;
774 if (!number)
776 setservent (0);
777 while ((serv = getservent ()) != NULL)
778 print_services (serv);
779 endservent ();
780 return result;
783 for (i = 0; i < number; ++i)
785 struct servent *serv;
786 char *proto = strchr (key[i], '/');
788 if (proto != NULL)
789 *proto++ = '\0';
791 if (isdigit (key[i][0]))
792 serv = getservbyport (htons (atol (key[i])), proto);
793 else
794 serv = getservbyname (key[i], proto);
796 if (serv == NULL)
797 result = 2;
798 else
799 print_services (serv);
802 return result;
805 /* This is for shadow */
806 static void
807 print_shadow (struct spwd *sp)
809 printf ("%s:%s:",
810 sp->sp_namp ? sp->sp_namp : "",
811 sp->sp_pwdp ? sp->sp_pwdp : "");
813 #define SHADOW_FIELD(n) \
814 if (sp->n == -1) \
815 putchar_unlocked (':'); \
816 else \
817 printf ("%ld:", sp->n)
819 SHADOW_FIELD (sp_lstchg);
820 SHADOW_FIELD (sp_min);
821 SHADOW_FIELD (sp_max);
822 SHADOW_FIELD (sp_warn);
823 SHADOW_FIELD (sp_inact);
824 SHADOW_FIELD (sp_expire);
825 if (sp->sp_flag == ~0ul)
826 putchar_unlocked ('\n');
827 else
828 printf ("%lu\n", sp->sp_flag);
831 static int
832 shadow_keys (int number, char *key[])
834 int result = 0;
835 int i;
837 if (number == 0)
839 struct spwd *sp;
841 setspent ();
842 while ((sp = getspent ()) != NULL)
843 print_shadow (sp);
844 endpwent ();
845 return result;
848 for (i = 0; i < number; ++i)
850 struct spwd *sp;
852 sp = getspnam (key[i]);
854 if (sp == NULL)
855 result = 2;
856 else
857 print_shadow (sp);
860 return result;
863 struct
865 const char *name;
866 int (*func) (int number, char *key[]);
867 } databases[] =
869 #define D(name) { #name, name ## _keys },
870 D(ahosts)
871 D(ahostsv4)
872 D(ahostsv6)
873 D(aliases)
874 D(ethers)
875 D(group)
876 D(gshadow)
877 D(hosts)
878 D(initgroups)
879 D(netgroup)
880 D(networks)
881 D(passwd)
882 D(protocols)
883 D(rpc)
884 D(services)
885 D(shadow)
886 #undef D
887 { NULL, NULL }
890 /* Handle arguments found by argp. */
891 static error_t
892 parse_option (int key, char *arg, struct argp_state *state)
894 char *endp;
895 switch (key)
897 case 's':
898 endp = strchr (arg, ':');
899 if (endp == NULL)
900 /* No specific database, change them all. */
901 for (int i = 0; databases[i].name != NULL; ++i)
902 __nss_configure_lookup (databases[i].name, arg);
903 else
905 int i;
906 for (i = 0; databases[i].name != NULL; ++i)
907 if (strncmp (databases[i].name, arg, endp - arg) == 0)
909 __nss_configure_lookup (databases[i].name, endp + 1);
910 break;
912 if (databases[i].name == NULL)
913 error (EXIT_FAILURE, 0, gettext ("Unknown database name"));
915 break;
917 case 'i':
918 idn_flags = 0;
919 break;
921 default:
922 return ARGP_ERR_UNKNOWN;
925 return 0;
929 static char *
930 more_help (int key, const char *text, void *input)
932 switch (key)
934 size_t len;
935 char *doc;
936 FILE *fp;
938 case ARGP_KEY_HELP_EXTRA:
939 /* We print some extra information. */
940 fp = open_memstream (&doc, &len);
941 if (fp != NULL)
943 fputs_unlocked (_("Supported databases:\n"), fp);
945 for (int i = 0, col = 0; databases[i].name != NULL; ++i)
947 len = strlen (databases[i].name);
948 if (i != 0)
950 if (col + len > 72)
952 col = 0;
953 fputc_unlocked ('\n', fp);
955 else
956 fputc_unlocked (' ', fp);
959 fputs_unlocked (databases[i].name, fp);
960 col += len + 1;
963 fputs ("\n\n", fp);
965 fputs (gettext ("\
966 For bug reporting instructions, please see:\n\
967 <http://www.gnu.org/software/libc/bugs.html>.\n"), fp);
969 if (fclose (fp) == 0)
970 return doc;
972 break;
974 default:
975 break;
977 return (char *) text;
981 /* the main function */
983 main (int argc, char *argv[])
985 /* Debugging support. */
986 mtrace ();
988 /* Set locale via LC_ALL. */
989 setlocale (LC_ALL, "");
990 /* Set the text message domain. */
991 textdomain (PACKAGE);
993 /* Parse and process arguments. */
994 int remaining;
995 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
997 if ((argc - remaining) < 1)
999 error (0, 0, gettext ("wrong number of arguments"));
1000 argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
1001 return 1;
1004 for (int i = 0; databases[i].name; ++i)
1005 if (argv[remaining][0] == databases[i].name[0]
1006 && !strcmp (argv[remaining], databases[i].name))
1007 return databases[i].func (argc - remaining - 1, &argv[remaining + 1]);
1009 fprintf (stderr, _("Unknown database: %s\n"), argv[remaining]);
1010 argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
1011 return 1;