Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

GNU file utilities release 1.0

69 views
Skip to first unread message

David J. MacKenzie

unread,
Feb 8, 1990, 7:46:33 AM2/8/90
to
A group of GNU file manipulation programs is now available for
anonymous ftp from prep.ai.mit.edu (18.71.0.38) in the file
pub/gnu/fileutils-1.0.tar.Z. They will be added to the GNU beta test
tape, as well.

The programs this package contains are:

cat chmod cmp cp dd dir du head ln ls mkdir mv rm rmdir tail vdir

(dir and vdir are ls with different default output formats)

Here is the README from the distribution:

This is the GNU file manipulation utilities package. Most of these
programs have significant advantages over their Unix counterparts,
such as greater speed or additional flexibility. The documentation
for these programs is not finished yet; it will be added in a later
release. Most of them accept descriptive long-named options in
addition to Unix-style short-named options, which should help you
figure out their additional features. Giving a `-h' option (or any
invalid option) will produce a usage message. Some of the programs
also have explanatory comments at the top of the source code.

The fileutils are intended to be POSIX compliant, like the rest of the
GNU system. They were mostly written on BSD Unix and later ported to
System V.

Known bugs:

* mv cannot rename directories on systems that lack the rename
system call, except when run by root. I think the System V
mv runs a setuid root program called /etc/mvdir to do this. No one
has bothered to hack that into the rename emulator in GNU mv.

* When copying sparse files that end in blocks of nulls, cp truncates
the trailing nulls on systems that lack the ftruncate system call.
ftruncate emulations have been written using the fcntl and chsize system
calls on System V release 3 and Xenix.

* On some versions of System V, du sometimes reports that it cannot
stat the last few entries in some directories. This is probably due
to bugs in those systems' portable directory libraries.

* tail has no -r option (print backwards). Printing the entire file,
as the Unix manual says, could run out of memory when tailing a pipe.
Reversing a file is really a different job from printing the end of a
file; the BSD tail can get away with kludging it in because of its
limited size buffer. A more versatile way than tail -r to reverse
files is the `tac' command which comes in the 4.3BSD user-contributed
code distribution. An enhanced GNU version of `tac' might be included
in a future distribution of the fileutils.

Bug reports and discussion about these programs should go to
bug-gn...@prep.ai.mit.edu.

David MacKenzie <d...@ai.mit.edu> <d...@eng.umd.edu>

i...@sibyl.eleceng.ua.oz.au

unread,
Feb 18, 1990, 4:45:15 AM2/18/90
to
In article <9002081246.AA06219@pogo> d...@AI.MIT.EDU (David J. MacKenzie) writes:
>Known bugs:
>
>* mv cannot rename directories on systems that lack the rename
>system call, except when run by root. I think the System V
>mv runs a setuid root program called /etc/mvdir to do this. No one
>has bothered to hack that into the rename emulator in GNU mv.

I did it this afternoon. There is a revised rename function as well as
a complete new file mv_dir.c The latter must run suid 0. I haven't
extensively tested it yet but it seems OK. It is a little more flexible
than the SysV version on this machine. It trys to prevent you unlinking
directories in such a way as to leave them unconnected to the root.
Eg it disallows "mv foo foo/bar/foo". I think I got it right but no
promises. I presume that the BSD rename system call does that as well
but it isn't mentioned in the man page. It should possibly prevent the
user from renaming "." and ".." which at thhe moment it doesn't do. I
am not quite sure what the conventional wisdom is as to whether users
should be prevented from f*cking themselves in that particular way.
Anyway, the FSF can have it if it wants it. i have already put the
GNU copyleft on top as I have included some (3 lines :-)) of FSF code.

Rename:
----------------------------------------------------------------------------
#ifdef USG
#ifndef MV_DIR
#define MV_DIR "/usr/local/lib/mv_dir"
#endif
int
rename (from, to)
char *from;
char *to;
{
if (access (from, 0) == 0)
{
if (isdir(from))
{
int pid;
/* Need suid 0 process to link/unlink directories */
if ((pid = fork()) < 0)
{
/* Could not fork */
error (0, errno, "cannot fork");
return (-1);
}
else if (!pid)
{
/* Child */
if (execl (MV_DIR, MV_DIR, from, to) == -1)
{
error (0, errno, "cannot exec %s" MV_DIR);
_exit(errno);
}
}
else
{
/* parent */
int ret_val, stat_loc;
while (((ret_val = wait(&stat_loc)) == -1) && (errno == EINTR));
if (ret_val == -1)
{
error(0, errno, "waiting for %s", MV_DIR);
return (-1);
}
else
{
if ((stat_loc & 0xff) == 0)
errno = (stat_loc >> 8) &0xff;
else
errno = stat_loc;
return (stat_loc != 0? -1: 0);
}
}
}
else
{
unlink (to);
if (link (from, to) == 0)
if (unlink (from) == 0)
return (0);
}
}
return (-1);
}
#endif
-----------------------------------------------------------------------------

mv_dir.c:
----------------------------------------------------------------------------

# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by on Sun Feb 18 20:39:28 CDT 1990
# Contents: mv_dir.c

echo x - mv_dir.c
sed 's/^@//' > "mv_dir.c" <<'@//E*O*F mv_dir.c//'
/* mk_dir: This is suid 0 program to allow mv'ing directories.
Copyright (C) 1986, 1989 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */

/* mk_dir: This is suid 0 program to allow mv'ing directories.
* It is called with two arguments, from and to. From must
* exist and be a directory, and to must not exist. It is the
* resonsibility of mv to get the arguments into this form.
*
* We exit with status = errno and without printing messages, on the
* assumtion that the parent process will print it out.
*
* Ian Dall
* 17-Feb-1990
*/

#ifdef USG /* No need for this whole file under BSD */
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include "system.h"

#define USAGE "mv_dir <old directory name> <new directory name>\n"

/* Return nonzero if FN is a directory, zero if not. */
int
isdir (fn)
char *fn;
{
struct stat stb;

return (stat (fn, &stb) >= 0 && (stb.st_mode & S_IFMT) == S_IFDIR);
}

/* mv_access checks the write permissions of the directory containing file */
int
mv_access(file, mode)
char *file;
int mode;
{
char *temp_p, *dir;

if ((temp_p = strrchr(file, '/')) == NULL)
dir = "./";
else
{
dir = (char *) alloca (temp_p - file + 2);
strncpy(dir, file, temp_p - file + 1);
dir[temp_p - file + 1] = '\0';
}
return access(dir, mode);
}

int
main (argc, argv)
int argc;
char **argv;
{
char *from, *to;
if (argc != 3)
{
fprintf(stderr, USAGE);
exit (-1);
}
from = argv[1];
to = argv[2];

/* Even with an effective uid of root, link will fail if the target exists.
* That is what we want so don't unlink from first.
* However, we do need to check that the directories which link and unlink
* will modify are write accessible by the user.
*/

if (access (from, 0) == 0) /* Validate the path */
if (isdir(from)) /* Check it is dir */
if(mv_access(from, W_OK) == 0 && mv_access(to, W_OK) == 0)
{
/* We can't make this atomic but we do our best. */
struct stat from_stat, to_stat;
int i;
for (i = NSIG; i > 0; i--)
signal(i, SIG_IGN);
setuid(0); /* Make real uid 0 so is is harder to kill */
nice(-1); /* Raise priority */
if (stat(from, &from_stat) == 0)
{
char *to_copy, *temp_p, temp;
int n = strlen(to);
to_copy = (char *) alloca(n);
strcpy (to_copy, to);
temp_p = to_copy;
while((temp_p = strchr(temp_p, '/')) != NULL)
{
temp = *++temp_p;
*temp_p = '\0';
if (stat(to_copy, &to_stat) != 0)
exit(errno);
*temp_p = temp;

if (to_stat.st_ino == from_stat.st_ino)
{
fprintf(stderr, "%s is in the path %s\n", from, to);
exit(-1);
}
}
}
if (link (from, to) == 0)
if (unlink (from) == 0)
exit (0);
}
exit (errno);
}
#endif
@//E*O*F mv_dir.c//
chmod u=rw,g=r,o=r mv_dir.c

exit 0
--
Ian Dall life (n). A sexually transmitted disease which afflicts
some people more severely than others.
---
Ian Dall life (n). A sexually transmitted disease which afflicts
some people more severely than others.

i...@sibyl.eleceng.ua.oz.au

unread,
Feb 21, 1990, 6:15:26 AM2/21/90
to
I sent this to bug-gnu-utils a few days ago, but it still haas not
appeared in gnu.utils.bug so I am resending it. Sorry if you get it
twice!

In article <9002081246.AA06219@pogo> d...@AI.MIT.EDU (David J. MacKenzie) writes:
>Known bugs:
>
>* mv cannot rename directories on systems that lack the rename
>system call, except when run by root. I think the System V
>mv runs a setuid root program called /etc/mvdir to do this. No one
>has bothered to hack that into the rename emulator in GNU mv.

I did it this afternoon. There is a revised rename function as well as
a complete new file mv_dir.c The latter must run suid 0. I haven't
extensively tested it yet but it seems OK. It is a little more flexible
than the SysV version on this machine. It trys to prevent you unlinking
directories in such a way as to leave them unconnected to the root.
Eg it disallows "mv foo foo/bar/foo". I think I got it right but no
promises. I presume that the BSD rename system call does that as well
but it isn't mentioned in the man page. It should possibly prevent the

user from renaming "." and ".." which at the moment it doesn't do. I

0 new messages