diff options
Diffstat (limited to 'src/ar.c')
-rw-r--r-- | src/ar.c | 74 |
1 files changed, 47 insertions, 27 deletions
@@ -1,5 +1,5 @@ /* Create, modify, and extract from archives. - Copyright (C) 2005, 2007 Red Hat, Inc. + Copyright (C) 2005-2010 Red Hat, Inc. Written by Ulrich Drepper <drepper@redhat.com>, 2005. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -45,7 +45,7 @@ #include <time.h> #include <unistd.h> #include <sys/mman.h> -#include <sys/statfs.h> +#include <sys/stat.h> #include <sys/time.h> #include <system.h> @@ -55,7 +55,8 @@ /* Name and version of program. */ static void print_version (FILE *stream, struct argp_state *state); -void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version; +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; + /* Prototypes for local functions. */ static int do_oper_extract (int oper, const char *arfname, char **argv, int argc, long int instance); @@ -66,7 +67,7 @@ static int do_oper_insert (int oper, const char *arfname, char **argv, /* Bug report address. */ -const char *argp_program_bug_address = PACKAGE_BUGREPORT; +ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; /* Definitions of arguments for argp functions. */ @@ -187,14 +188,16 @@ main (int argc, char *argv[]) if (ipos != ipos_none) { /* Only valid for certain operations. */ - if (operation == oper_extract && operation == oper_delete) + if (operation != oper_move && operation != oper_replace) error (1, 0, gettext ("\ 'a', 'b', and 'i' are only allowed with the 'm' and 'r' options")); if (remaining == argc) { - error (0, 0, gettext ("MEMBER parameter required")); - argp_help (&argp, stderr, ARGP_HELP_SEE, AR); + error (0, 0, gettext ("\ +MEMBER parameter required for 'a', 'b', and 'i' modifiers")); + argp_help (&argp, stderr, ARGP_HELP_USAGE | ARGP_HELP_SEE, + program_invocation_short_name); exit (EXIT_FAILURE); } @@ -213,7 +216,8 @@ main (int argc, char *argv[]) if (remaining == argc) { error (0, 0, gettext ("COUNT parameter required")); - argp_help (&argp, stderr, ARGP_HELP_SEE, AR); + argp_help (&argp, stderr, ARGP_HELP_SEE, + program_invocation_short_name); exit (EXIT_FAILURE); } @@ -230,14 +234,14 @@ main (int argc, char *argv[]) if ((dont_replace_existing || allow_truncate_fname) && unlikely (operation != oper_extract)) - error (1, 0, gettext ("'%' is only meaningful with the 'x' option"), + error (1, 0, gettext ("'%c' is only meaningful with the 'x' option"), dont_replace_existing ? 'C' : 'T'); /* There must at least be one more parameter specifying the archive. */ if (remaining == argc) { - error (0, 0, gettext ("Archive name required")); - argp_help (&argp, stderr, ARGP_HELP_SEE, AR); + error (0, 0, gettext ("archive name required")); + argp_help (&argp, stderr, ARGP_HELP_SEE, program_invocation_short_name); exit (EXIT_FAILURE); } @@ -286,7 +290,7 @@ print_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) Copyright (C) %s Red Hat, 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\ -"), "2007"); +"), "2009"); fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); } @@ -308,7 +312,8 @@ parse_opt (int key, char *arg __attribute__ ((unused)), if (operation != oper_none) { error (0, 0, gettext ("More than one operation specified")); - argp_help (&argp, stderr, ARGP_HELP_SEE, AR); + argp_help (&argp, stderr, ARGP_HELP_SEE, + program_invocation_short_name); exit (EXIT_FAILURE); } @@ -454,8 +459,21 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc, bool found[argc]; memset (found, '\0', sizeof (found)); - struct statfs f; - f.f_namelen = 0; + size_t name_max = 0; + inline bool should_truncate_fname (void) + { + if (errno == ENAMETOOLONG && allow_truncate_fname) + { + if (name_max == 0) + { + long int len = pathconf (".", _PC_NAME_MAX); + if (len > 0) + name_max = len; + } + return name_max != 0; + } + return false; + } off_t index_off = -1; size_t index_size = 0; @@ -606,15 +624,14 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc, { int printlen = INT_MAX; - if (errno == ENAMETOOLONG && allow_truncate_fname - && (f.f_namelen != 0 || statfs (".", &f) == 0)) + if (should_truncate_fname ()) { /* Try to truncate the name. First find out by how much. */ - printlen = f.f_namelen; - char truncfname[f.f_namelen + 1]; + printlen = name_max; + char truncfname[name_max + 1]; *((char *) mempcpy (truncfname, arhdr->ar_name, - f.f_namelen)) = '\0'; + name_max)) = '\0'; xfd = open (truncfname, flags, 0600); } @@ -696,15 +713,14 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc, { int printlen = INT_MAX; - if (errno == ENAMETOOLONG && allow_truncate_fname - && (f.f_namelen != 0 || statfs (".", &f) == 0)) + if (should_truncate_fname ()) { /* Try to truncate the name. First find out by how much. */ - printlen = f.f_namelen; - char truncfname[f.f_namelen + 1]; + printlen = name_max; + char truncfname[name_max + 1]; *((char *) mempcpy (truncfname, arhdr->ar_name, - f.f_namelen)) = '\0'; + name_max)) = '\0'; if (dont_replace_existing) { @@ -1097,7 +1113,8 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc, if (fd == -1) { if (!suppress_create_msg) - fprintf (stderr, "%s: creating %s\n", AR, arfname); + fprintf (stderr, "%s: creating %s\n", + program_invocation_short_name, arfname); goto no_old; } @@ -1211,7 +1228,7 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc, if (found[cnt] == NULL) { fprintf (stderr, gettext ("%s: no entry %s in archive!\n"), - AR, argv[cnt]); + program_invocation_short_name, argv[cnt]); status = 1; } @@ -1513,3 +1530,6 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc, return status; } + + +#include "debugpred.h" |