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 <[EMAIL PROTECTED]> * 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 <[EMAIL PROTECTED]>.")); + } + 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 _______________________________________________ Bug-hurd mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-hurd