[Top][All Lists]
[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
- GNU Fileutils - chauthor.,
Alfred M. Szmidt <=