summaryrefslogtreecommitdiff
path: root/src/ar.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ar.c')
-rw-r--r--src/ar.c74
1 files changed, 47 insertions, 27 deletions
diff --git a/src/ar.c b/src/ar.c
index a9102a55..149d116d 100644
--- a/src/ar.c
+++ b/src/ar.c
@@ -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"