Print statistics for existing files.
Copyright (C) 1995, 1996, 1997, 2001, 2003, 2004, 2005, 2006, 2007,
- 2008 Free Software Foundation, Inc.
+ 2008, 2009 Free Software Foundation, Inc.
François Pinard <pinard@iro.umontreal.ca>, 1995.
Sergey Poznyakoff <gray@mirddin.farlep.net>, 2004, 2005, 2006, 2007, 2008.
#include <argmatch.h>
#include <argp.h>
#include <argcv.h>
-#include <getdate.h>
-#include <utimens.h>
+#include <parse-datetime.h>
#include <inttostr.h>
#include <fcntl.h>
#include <sys/stat.h>
/* Number of arguments and argument vector for mode == mode_exec */
int exec_argc;
char **exec_argv;
+char *checkpoint_option;
/* Time for --touch option */
struct timespec touch_time;
#define OPT_DATE 261
#define OPT_VERBOSE 262
#define OPT_SEEK 263
+#define OPT_UNLINK 264
static struct argp_option options[] = {
#define GRP 0
{NULL, 0, NULL, 0,
N_("Synchronous execution options:"), GRP},
- {"run", 'r', N_("COMMAND"), 0,
- N_("Execute given COMMAND. Useful with --checkpoint and one of --cut, --append, --touch"),
+ {"run", 'r', N_("OPTION"), OPTION_ARG_OPTIONAL,
+ N_("Execute ARGS. Useful with --checkpoint and one of --cut, --append, --touch, --unlink"),
GRP+1 },
{"checkpoint", OPT_CHECKPOINT, N_("NUMBER"), 0,
N_("Perform given action (see below) upon reaching checkpoint NUMBER"),
{"exec", OPT_EXEC, N_("COMMAND"), 0,
N_("Execute COMMAND"),
GRP+1 },
+ {"unlink", OPT_UNLINK, N_("FILE"), 0,
+ N_("Unlink FILE"),
+ GRP+1 },
#undef GRP
{ NULL, }
};
case 'r':
mode = mode_exec;
- argcv_get (arg, "", NULL, &exec_argc, &exec_argv);
+ if (arg)
+ {
+ argcv_get (arg, "", NULL, &exec_argc, &exec_argv);
+ checkpoint_option = "--checkpoint";
+ }
break;
case 'T':
break;
case OPT_DATE:
- if (!get_date (&touch_time, arg, NULL))
+ if (! parse_datetime (&touch_time, arg, NULL))
argp_error (state, _("Unknown date format"));
break;
case OPT_TRUNCATE:
case OPT_TOUCH:
case OPT_EXEC:
+ case OPT_UNLINK:
reg_action (key, arg);
break;
printf ("%lu", (unsigned long) st.st_ino);
else if (strncmp (p, "mode", 4) == 0)
{
- mode_t mask = ~0;
+ unsigned val = st.st_mode;
- if (ispunct (p[4]))
+ if (ispunct ((unsigned char) p[4]))
{
char *q;
- mask = strtoul (p + 5, &q, 8);
+ val &= strtoul (p + 5, &q, 8);
if (*q)
{
printf ("\n");
printf ("\n");
error (EXIT_FAILURE, 0, _("Unknown field `%s'"), p);
}
- printf ("%0o", st.st_mode & mask);
+ printf ("%0o", val);
}
else if (strcmp (p, "nlink") == 0)
printf ("%lu", (unsigned long) st.st_nlink);
struct timespec ts[2];
ts[0] = ts[1] = p->ts;
- if (utimens (p->name, ts) != 0)
+ if (utimensat (AT_FDCWD, p->name, ts, 0) != 0)
{
error (0, errno, _("cannot set time on `%s'"), p->name);
break;
system (p->name);
break;
+ case OPT_UNLINK:
+ if (unlink (p->name))
+ error (0, errno, _("cannot unlink `%s'"), p->name);
+ break;
+
default:
abort ();
}
/* Insert --checkpoint option.
FIXME: This assumes that exec_argv does not use traditional tar options
- (without dash) */
- exec_argc++;
- exec_argv = xrealloc (exec_argv, (exec_argc + 1) * sizeof (*exec_argv));
- memmove (exec_argv+2, exec_argv+1, (exec_argc - 1) * sizeof (*exec_argv));
- exec_argv[1] = "--checkpoint";
+ (without dash).
+ FIXME: There is no way to set checkpoint argument (granularity).
+ */
+ if (checkpoint_option)
+ {
+ exec_argc++;
+ exec_argv = xrealloc (exec_argv, (exec_argc + 1) * sizeof (*exec_argv));
+ memmove (exec_argv+2, exec_argv+1,
+ (exec_argc - 1) * sizeof (*exec_argv));
+ exec_argv[1] = checkpoint_option;
+ }
#ifdef SIGCHLD
/* System V fork+wait does not work if SIGCHLD is ignored. */
setenv ("LC_ALL", "POSIX", 1);
execvp (exec_argv[0], exec_argv);
- error (EXIT_FAILURE, errno, "execvp");
+ error (EXIT_FAILURE, errno, "execvp %s", exec_argv[0]);
}
/* Master */
while ((p = fgets (buf, sizeof buf, fp)))
{
- while (*p && !isspace (*p) && *p != ':')
+ while (*p && !isspace ((unsigned char) *p) && *p != ':')
p++;
if (*p == ':')
{
- for (p++; *p && isspace (*p); p++)
+ for (p++; *p && isspace ((unsigned char) *p); p++)
;
if (*p
{
char *end;
size_t n = strtoul (p + sizeof CHECKPOINT_TEXT - 1, &end, 10);
- if (!(*end && !isspace (*end)))
+ if (!(*end && !isspace ((unsigned char) *end)))
{
process_checkpoint (n);
continue;
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
- get_date (&touch_time, "now", NULL);
+ parse_datetime (&touch_time, "now", NULL);
/* Decode command options. */
break;
case mode_exec:
+ if (!checkpoint_option)
+ {
+ exec_argc = argc;
+ exec_argv = argv;
+ }
+ else if (argc)
+ error (EXIT_FAILURE, 0, _("too many arguments"));
exec_command ();
break;