bug-fileutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

GNU Fileutils - chauthor.


From: Alfred M. Szmidt
Subject: GNU Fileutils - chauthor.
Date: 10 Apr 2002 15:52:58 +0200
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2.50

Hi,

And here I go again.  This time it's a whole new program, that will
allow you to change the st_author field on GNU/Hurd.

As I haven't received any comments on the last patch for fileutils, I will
assume that it is OK. :)

The only thing that is left I think is for chmod/chown to be able to change
the permissions of the underlying node and for ls to be able to list those
permissions.. Unless someone has more ideas for fileutils.

2002-04-10  Alfred M. Szmidt <address@hidden>
        * src/chauthor.c: New file.
        * src/Makefile.am: Add rules for chauthor.
        * configure.ac: Check for hurd.h.

diff -urpN fileutils-4.1.7.orig/chauthor.c fileutils-4.1.7-chauthor/chauthor.c
--- fileutils-4.1.7.orig/chauthor.c     Wed Dec 31 19:00:00 1969
+++ fileutils-4.1.7-chauthor/chauthor.c Wed Apr 10 09:33:32 2002
@@ -0,0 +1,338 @@
+/* chauthor -- Change authorship of files
+   Copyright (C) 89, 90, 91, 1995-2002 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* Written by David MacKenzie and Alfred M. Szmidt */
+
+#include <config.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <getopt.h>
+#include <pwd.h>
+#include <hurd.h>
+
+#include "system.h"
+#include "error.h"
+#include "savedir.h"
+#include "quote.h"
+#include "chown-core.h"
+#include "xstrtol.h"
+
+/* The official name of this program (e.g., no `g' prefix).  */
+#define PROGRAM_NAME "chauthor"
+
+#define AUTHORS \
+  "David MacKenzie and Alfred M. Szmidt"
+
+#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
+
+static int change_dir_authorship PARAMS ((uid_t author, const char *dir));
+
+/* Name this program was run with. */
+char *program_name;
+
+/* For long options that have no equivalent short option, use a
+   non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
+enum
+{
+  VERBOSE_OPTION = CHAR_MAX + 1,
+  DEREFERENCE_OPTION
+};
+
+/* Level of verbosity.  */
+enum Verbosity verbosity = V_off;
+
+/* If nonzero, change the authorship of directories recursively. */
+static int recurse = 0;
+
+/* If nonzero, change the author ship of the symbolic link.  */
+static int deref_symlink = DEREF_NEVER;;
+
+/* If nonzero, force silence (no error messages). */
+static int force_silent = 0;
+
+static struct option const long_options[] = {
+  {"changes", no_argument, 0, 'c'},
+  {"dereference", no_argument, NULL, DEREFERENCE_OPTION},
+  {"no-dereference", no_argument, NULL, 'h'},
+  {"verbose", no_argument, NULL, VERBOSE_OPTION},
+  {"recursive", no_argument, NULL, 'R'},
+  {"quiet", no_argument, NULL, 'f'}, 
+  {"silent", no_argument, NULL, 'f'}, /* alias */
+  {GETOPT_HELP_OPTION_DECL},
+  {GETOPT_VERSION_OPTION_DECL},
+  {NULL, 0, NULL, 0}
+};
+
+void
+usage (int status)
+{
+  if (status != 0)
+    fprintf (stderr, _("Try `%s --help' for more information.\n"),
+            program_name);
+  else
+    {
+      printf (_("Usage: %s [OPTION]... AUTHOR FILES...\n"), program_name);
+      fputs (_("\
+Change the authorship of FILE.\n\
+\n\
+"), stdout);
+      fputs (_("\
+Change the authorship of each FILE to AUTHOR.\n\
+"), stdout);
+      fputs (_("\
+  -c, --changes          like verbose but report only when a change is made\n\
+      --dereference      affect the referent of each symbolic link, rather\n\
+                         than the symbolic link itself\n\
+  -h, --no-dereference   affect symbolic links instead of any referenced 
file\n\
+"), stdout);
+      fputs (_("\
+  -f, --silent, --quiet  suppress most error messages\n\
+  -R, --recursive        change files and directories recursively\n\
+      --verbose          output a diagnostic for every file processed\n\
+"), stdout);
+      fputs (HELP_OPTION_DESCRIPTION, stdout);
+      fputs (VERSION_OPTION_DESCRIPTION, stdout);
+      puts (_("\nReport bugs to <address@hidden>."));
+    }
+  exit (status);
+}
+
+/* Return nonzero if STR represents an unsigned decimal integer,
+   otherwise return 0. */
+static int
+is_number (const char *str)
+{
+  for (; *str; str++)
+    if (!ISDIGIT (*str))
+      return 0;
+  return 1;
+}
+
+/* Tell the user how/if the AUTHOR of FILE has been changed.
+   CHANGED describes what (if anything) has happened. */
+
+static void
+describe_change (const char *file, char const *author,
+                enum Change_status changed)
+{
+  const char *fmt;
+
+  switch (changed)
+    {
+    case CH_SUCCEEDED:
+      fmt = _("authorship of %s changed to %s\n");
+      break;
+    case CH_FAILED:
+      fmt = _("failed to change authorship of %s to %s\n");
+      break;
+    case CH_NO_CHANGE_REQUESTED:
+      fmt = _("authorship of %s retained as %s\n");
+      break;
+    default:
+      abort ();
+    }
+  printf (fmt, quote (file), author);
+}
+
+/* Change the authorship of FILE.
+   If DEREF_SYMLINK is nonzero and FILE is a symbolic link, change the
+   mode of the referenced file.  If DEREF_SYMLINK is zero, ignore symbolic
+   links.  Return 0 if successful, 1 if errors occurred. */
+
+static int
+change_file_authorship (uid_t author, const char *file)
+{
+  struct stat file_stats;
+  uid_t new_author;
+  int errors = 0;
+  int fail;
+  int saved_errno;
+  file_t port;
+
+  if (deref_symlink ? stat (file, &file_stats) : lstat (file, &file_stats))
+    {
+      if (force_silent == 0)
+       error (0, errno, _("failed to get attributes of %s"), quote (file));
+      return 1;
+    }
+
+  if (file_stats.st_author != author)
+    {
+      if (S_ISLNK (file_stats.st_mode))
+       port = file_name_lookup (file, 0, O_NOFOLLOW);
+      else
+       port = file_name_lookup (file, 0, 0);
+
+      if (port == MACH_PORT_NULL)
+       error (0, errno, "%s", file);
+
+      fail = file_chauthor (port, author);
+      mach_port_deallocate (mach_task_self (), port);
+      saved_errno = errno;
+
+      if (verbosity == V_high || verbosity == V_changes_only && !fail)
+       describe_change (file, uid_to_name (author),
+                        (fail ? CH_FAILED : CH_SUCCEEDED));
+
+      if (fail)
+       {
+         if (force_silent == 0)
+           error (0, saved_errno, (_("changing authorship of %s")),
+                  quote (file));
+         errors = 1;
+       }
+    }
+  else if (verbosity == V_high)
+    {
+      describe_change (file, uid_to_name (author), CH_NO_CHANGE_REQUESTED);
+    }
+
+  if (recurse && S_ISDIR (file_stats.st_mode))
+    errors |= change_dir_authorship (author, file);
+  return errors;
+}
+
+/* Recursively change the authorship of the files in directory DIR.
+   Return 0 if successful, 1 if errors occurred. */
+static int
+change_dir_authorship (const uid_t author, const char *dir)
+{
+  char *name_space, *namep;
+  char *path;                  /* Full path of each entry to process. */
+  unsigned dirlength;          /* Length of DIR and '\0'. */
+  unsigned filelength;         /* Length of each pathname to process. */
+  unsigned pathlength;         /* Bytes allocated for `path'. */
+  int errors = 0;
+
+  name_space = savedir (dir);
+  if (name_space == NULL)
+    {
+      if (force_silent == 0)
+       error (0, errno, "%s", quote (dir));
+      return 1;
+    }
+
+  dirlength = strlen (dir) + 1;        /* + 1 is for the trailing '/'. */
+  pathlength = dirlength + 1;
+  /* Give `path' a dummy value; it will be reallocated before first use. */
+  path = xmalloc (pathlength);
+  strcpy (path, dir);
+  path[dirlength - 1] = '/';
+
+  for (namep = name_space; *namep; namep += filelength - dirlength)
+    {
+      filelength = dirlength + strlen (namep) + 1;
+      if (filelength > pathlength)
+       {
+         pathlength = filelength * 2;
+         path = xrealloc (path, pathlength);
+       }
+      strcpy (path + dirlength, namep);
+      errors |= change_file_authorship (author, path);
+    }
+  free (path);
+  free (name_space);
+  return errors;
+}
+
+int
+main (int argc, char **argv)
+{
+  uid_t author;
+  int authorind = 0;           /* Index of the AUTHOR argument in `argv'. */
+  int errors = 0;
+  int c;
+
+  program_name = argv[0];
+  setlocale (LC_ALL, "");
+  bindtextdomain (PACKAGE, LOCALEDIR);
+  textdomain (PACKAGE);
+
+  atexit (close_stdout);
+
+  while ((c = getopt_long (argc, argv, "Rchf", long_options, NULL)) != -1)
+    {
+      switch (c)
+       {
+       case 0:         /* Long option. */
+         break;
+
+       case 'h':
+         deref_symlink = 0;
+
+       case 'R':
+         recurse = 1;
+         break;
+
+       case 'c':
+         verbosity = V_changes_only;
+         break;
+
+       case 'f':
+         force_silent = 1;
+         break;
+
+       case DEREFERENCE_OPTION:
+         deref_symlink = 1;
+         break;
+
+       case VERBOSE_OPTION:
+         verbosity = V_high;
+         break;
+
+         case_GETOPT_HELP_CHAR;
+         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+
+       default:
+         usage (1);
+       }
+    }
+
+  authorind = optind++;
+
+  if (optind >= argc)
+    {
+      error (0, 0, _("too few arguments"));
+      usage (1);
+    }
+
+  if (!is_number (argv[authorind]))
+    {
+      struct passwd *pw = getpwnam (argv[authorind]);
+      if (pw == NULL)
+       error (1, 0, _("invalid user: %s"), quote (argv[authorind]));
+      author = pw->pw_uid;
+    }
+  else
+    {
+      strtol_error s_err;
+      unsigned long int tmp_long;
+
+      s_err = xstrtoul (argv[authorind], NULL, 0, &tmp_long, NULL);
+      if (s_err != LONGINT_OK)
+       STRTOL_FATAL_ERROR (argv[authorind], _("user number"), s_err);
+
+      if (tmp_long > UID_T_MAX)
+       error (1, 0, _("invalid user number %s"), quote (argv[authorind]));
+      author = tmp_long;
+    }
+
+  for (; optind < argc; ++optind)
+    errors |= change_file_authorship (author, argv[optind]);
+
+  exit (errors);
+}
diff -urpN fileutils-4.1.7.orig/configure.ac 
fileutils-4.1.7-chauthor/configure.ac
--- fileutils-4.1.7.orig/configure.ac   Sun Mar 10 13:38:26 2002
+++ fileutils-4.1.7-chauthor/configure.ac       Sun Apr  7 09:38:40 2002
@@ -45,6 +45,9 @@ if test $fu_cv_sys_truncating_statfs = y
 fi
 AC_MSG_RESULT($fu_cv_sys_truncating_statfs)
 
+AC_CHECK_HEADERS(hurd.h, have_hurd_h=yes)
+AM_CONDITIONAL(HURD, test x$have_hurd_h = xyes)
+
 jm_LIB_CHECK
 
 AM_GNU_GETTEXT
diff -urpN fileutils-4.1.7.orig/src/Makefile.am 
fileutils-4.1.7-chauthor/src/Makefile.am
--- fileutils-4.1.7.orig/src/Makefile.am        Sun Feb 17 12:00:25 2002
+++ fileutils-4.1.7-chauthor/src/Makefile.am    Sun Apr  7 10:03:35 2002
@@ -3,9 +3,15 @@ AUTOMAKE_OPTIONS = ansi2knr
 
 EXTRA_PROGRAMS = df
 
+if HURD
+CHAUTHOR = chauthor
+else
+CHAUTHOR =
+endif
+
 bin_PROGRAMS = chgrp chown chmod cp dd dircolors du \
 ginstall ln dir vdir ls mkdir \
-mkfifo mknod mv rm rmdir shred sync touch @DF_PROG@
+mkfifo mknod mv rm rmdir shred sync touch $(CHAUTHOR) @DF_PROG@
 
 datadir = $(prefix)/share
 localedir = $(datadir)/locale
@@ -39,6 +45,7 @@ vdir_SOURCES = ls.c ls-vdir.c
 ls_SOURCES = ls.c ls-ls.c
 chown_SOURCES = chown.c chown-core.c
 chgrp_SOURCES = chgrp.c chown-core.c
+chauthor_SOURCES = chauthor.c chown-core.c
 
 mv_SOURCES = mv.c copy.c cp-hash.c remove.c
 rm_SOURCES = rm.c remove.c

-- 
Alfred M. Szmidt



reply via email to

[Prev in Thread] Current Thread [Next in Thread]