[comp.sources.unix] v11i027: Copy modes/ownerships/times

rs@uunet.UUCP (09/02/87)

Submitted-by: psivax!sa@ttidca.tti.com (Steve Alter)
Posting-number: Volume 11, Issue 27
Archive-name: cpmod

Cpmod(1) is a simple inode-information copier.  It will copy modes
and/or ownerships and/or timestamps from an existing file to another
existing file without modifying the data.  A detailed introduction
is in the sharfile below in file "cpmod.intro".
-------------CUT---------------CUT----------------CUT-----------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	cpmod.intro
#	Makefile
#	cpmod.1
#	cpmod.c
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'cpmod.intro'" '(2087 characters)'
if test -f 'cpmod.intro'
then
	echo shar: "will not over-write existing file 'cpmod.intro'"
else
sed 's/^X//' << \SHAR_EOF > 'cpmod.intro'
XHere is a simple command called "cpmod" that fits in the same group as
Xchmod, chown and touch.
X
XWhat is "cpmod"?  Well, imagine these:
X
XSituation #1:
X     You've got two files with different data, different modes,
Xdifferent ownerships and different times, but you realize that the
Xmodes, ownerships and times (or maybe just the modes and times, or
Xmaybe just the ownerships for example) really should be the same
Xbetween the two files.  What do you do?  You could do "ls -lg file1"
Xthen do appropriate chmod, chown, chgrp and /usr/5bin/touch commands
Xon file2, but you'd like something easier.  (/usr/5bin/touch has the
Xoption to specify an explicit timestamp to place on the file.)
X
XSituation #2:
X     You've got a directory full of dozens or hundreds of programs
Xthat should all have the same ownerships and modes, but you notice
Xsome inconsistencies.  What do you do?  You could do "ls -lg program"
Xon one of the correct ones, then do appropriate chmod, chown and chgrp
Xcommands on all of the wrong ones, but that's a BIG hassle.
X
XSolution:
X     Cpmod is a program which copies modes, ownerships and times from
Xone existing file or directory to other existing files (or
Xdirectories) without modifying the data in any of the destination
Xfiles.  After this program is run, an "ls -lgd" command will show
Xidentical information for all of the files specified on the command
Xline, except for size and name.  All of this is, of course, subject to
Xaccess permissions on the files and pathnames.  There are options to
Xomit the modes and/or the ownerships and/or the times from the
Xtransfer, but if all three are omitted then there's nothing left to do
Xand the program complains.
X
XAnswer to Situation #1:
X     cpmod file1 file2
X
XAnswer to Situation #2:
X     cd directory ; cpmod -t correct_file *
XNote that this will copy modes and ownerships from correct_file to all
Xof the files in the whole directory, including correct_file, but that
Xlittle redundancy is harmless.
X
X-- Steve Alter
X...!{csun,trwrb,psivax}!ttidca!alter  or  alter@tti.com
XCiticorp/TTI, Santa Monica CA  (213) 452-9191 x2541
SHAR_EOF
if test 2087 -ne "`wc -c < 'cpmod.intro'`"
then
	echo shar: "error transmitting 'cpmod.intro'" '(should have been 2087 characters)'
fi
fi
echo shar: "extracting 'Makefile'" '(548 characters)'
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
XPROGRAM = cpmod
X
XOBJECTS = cpmod.o
X
XSOURCES = cpmod.c
X
XCFLAGS	= -O
X
XLFLAGS	= -abchx
X
XMANPAGE	= cpmod.1
X
XFILES	= cpmod.intro Makefile $(MANPAGE) $(SOURCES)
X
XPROGDIR	= /usr/local
X
XMANDIR	= /usr/man/man1
X
X$(PROGRAM): $(OBJECTS)
X	cc $(CFLAGS) -o $(PROGRAM) $(OBJECTS)
X
Xlint: lint.err
X
Xlint.err: $(SOURCES)
X	lint $(LFLAGS) $(SOURCES) > lint.err
X
Xinstall:
X	install -s $(PROGRAM) $(PROGDIR)
X	install -c $(MANPAGE) $(MANDIR)
X
Xdist shar: sharfile
X
Xsharfile: $(FILES)
X	shar -a -p X $(FILES) > sharfile
X
Xclean:
X	rm -f $(PROGRAM) $(OBJECTS) lint.err sharfile
X
SHAR_EOF
if test 548 -ne "`wc -c < 'Makefile'`"
then
	echo shar: "error transmitting 'Makefile'" '(should have been 548 characters)'
fi
fi
echo shar: "extracting 'cpmod.1'" '(1126 characters)'
if test -f 'cpmod.1'
then
	echo shar: "will not over-write existing file 'cpmod.1'"
else
sed 's/^X//' << \SHAR_EOF > 'cpmod.1'
X.TH CPMOD 1 "August 13, 1987"
X.UC 4
X.SH NAME
Xcpmod \- copy modes, ownerships and times
X.SH SYNOPSIS
X.B cpmod
X[
X.B \-m
X] [
X.B \-o
X] [
X.B \-t
X] file other-files ...
X.SH ORIGIN
X4.3BSD
X.SH DESCRIPTION
XThe modes, ownerships and times of
X.I file
Xare set into the inodes of all of the
X.IR other-files .
XIf the
X.BR \-m ,
X.B \-o
Xand/or
X.B \-t
Xoptions are given, then the modes, ownerships and/or times
Xrespectively do not participate in the transfer.
X.SH SEE ALSO
Xchmod(1), chown(1), utimes(2)
X.SH DIAGNOSTICS
XIf all three of the options are specified, then no work remains to be done
Xand an appropriate error-message is issued.
X.SH RESTRICTIONS
XEach file actually has three timestamps but this program can only set two
Xof them.  The third is the "last inode-modification" time and cannot be
Xexplicitly overwritten by any program.
X.SH AUTHOR
XSteve B. Alter (Citicorp/TTI, Santa Monica)
X.SH IDEAS
XA variation on this program called
X.B rcpmod
Xwould be the TCP/IP network brother to
X.B cpmod
Xwhich works strictly through the UNIX file hierarchy (including SUN NFS.)
X.B Rcpmod
Xwould relate to
X.B cpmod
Xjust like
X.B rcp
Xrelates to
X.BR cp .
SHAR_EOF
if test 1126 -ne "`wc -c < 'cpmod.1'`"
then
	echo shar: "error transmitting 'cpmod.1'" '(should have been 1126 characters)'
fi
fi
echo shar: "extracting 'cpmod.c'" '(1789 characters)'
if test -f 'cpmod.c'
then
	echo shar: "will not over-write existing file 'cpmod.c'"
else
sed 's/^X//' << \SHAR_EOF > 'cpmod.c'
X/*
X *  cpmod.c -- copy modes, ownerships and times from one file to others,
X *	       without affecting the data.
X *
X *  by Steve Alter (13-Aug-87, Citicorp/TTI, Santa Monica, CA)
X *
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/time.h>
X
Xmain (argc, argv)
X	int argc;
X	char **argv;
X{
X	char *prog_name, *rindex();
X	char *source_file;
X
X	short no_modes = 0;
X	short no_owner = 0;
X	short no_times = 0;
X	short error = 0;
X
X	struct stat source_buf, new_buf;
X	struct timeval tvp[2];
X
X	if (prog_name = rindex(argv[0], '/'))
X		prog_name++;
X	else
X		prog_name = argv[0];
X
X	for (argc--, argv++; (argc && **argv == '-'); argc--, argv++)
X		switch ((*argv)[1]) {
X			case 'm':
X				no_modes++;
X				break;
X			case 'o':
X				no_owner++;
X				break;
X			case 't':
X				no_times++;
X				break;
X			default:
X				fprintf(stderr,
X					"%s: invalid option \"%s\"\n",
X					prog_name, *argv);
X				error++;
X		}
X
X	if (argc < 2 || error) {
X		fprintf(stderr,
X			"usage: %s [-m] [-o] [-t] file other-files ...\n",
X			prog_name);
X		exit(1);
X	}
X
X	if (no_modes && no_owner && no_times) {
X		fprintf(stderr,
X		"%s: all three options disabled, no work left.\n",
X			prog_name);
X		exit(1);
X	}
X
X	source_file = *argv++;
X	argc--;
X
X	if (stat(source_file, &source_buf)) {
X		perror(source_file);
X		exit(1);
X	}
X
X	while (argc--) {
X		if (stat(*argv, &new_buf)) {
X			perror(*argv++);
X			continue;
X		}
X		if (!no_modes)
X			if (chmod(*argv, (int)source_buf.st_mode))
X				perror(*argv);
X		if (!no_owner)
X			if (chown(*argv, (int)source_buf.st_uid,
X					 (int)source_buf.st_gid))
X				perror(*argv);
X		if (!no_times) {
X			tvp[0].tv_sec = source_buf.st_atime;
X			tvp[1].tv_sec = source_buf.st_mtime;
X			tvp[0].tv_usec = tvp[1].tv_usec = 0L;
X			if (utimes(*argv, tvp))
X				perror(*argv);
X		}
X		argv++;
X	}
X}  /* main */
SHAR_EOF
if test 1789 -ne "`wc -c < 'cpmod.c'`"
then
	echo shar: "error transmitting 'cpmod.c'" '(should have been 1789 characters)'
fi
fi
exit 0
#	End of shell archive

-- 

Rich $alz
Cronus Project, BBN Labs			rsalz@bbn.com
Moderator, comp.sources.unix			sources@uunet.uu.net