home *** CD-ROM | disk | FTP | other *** search
- Subject: v13i041: Derez, remove stale files from system, Part02/02
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: A. Nonymous
- Posting-number: Volume 13, Issue 41
- Archive-name: derez3/part02
-
- The author will deny being the author of this program.
-
- : Run this shell script with "sh" not "csh"
- PATH=:/bin:/usr/bin:/usr/ucb
- export PATH
- all=FALSE
- if [ x$1 = x-a ]; then
- all=TRUE
- fi
- /bin/echo 'Extracting derez.c'
- sed 's/^X//' <<'//go.sysin dd *' >derez.c
- X/* Derez, the great stale file archiver. It stages stale files
- into a MORGUE directory for later removal with tar or rerez.
- */
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/file.h>
- #include <strings.h>
- #include <errno.h>
- extern int errno;
-
- #define MAXLEN 10240
- #define USAGE "derez [-t days] [dir1 dir2 dir3 ...]\n"
-
- #include <stdio.h>
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- FILE *fptr;
- struct stat statbuf;
- char filename[MAXLEN];
- char cmd[MAXLEN];
- char dirlist[MAXLEN];
- int since;
- int teflag = 0;
-
- dirlist[0] = NULL;
- since = 180;
-
-
- /* Check for the existence and access permissions on the MORGUE.
- */
- if(stat("MORGUE", &statbuf)) {
- perror("derez: MORGUE");
- exit(1);
- }
- if(!(statbuf.st_mode & S_IFDIR)) {
- fprintf(stderr, "derez: MORGUE is not a directory\n");
- exit(1);
- }
- if(access("MORGUE", R_OK | W_OK | X_OK)) {
- fprintf(stderr, "derez: The MORGUE must have read, write and execute perms\n");
- exit(1);
- }
-
- if(argc > 1) {
- if(strcmp(argv[1], "-t") == 0) {
- if(argc < 3) {
- fprintf(stderr, USAGE);
- exit(1);
- }
- if(sscanf(argv[2], "%d", &since) != 1) {
- fprintf(stderr, "derez: bad arg for -t option %s\n", argv[2]);
- exit(1);
- }
- if(since < 0 || since > 10000) {
- fprintf(stderr, "derez: bad value for -t argument\n");
- exit(1);
- }
- argv += 2;
- argc -= 2;
- }
- else if(strcmp(argv[1], "-te") == 0) {
- if(argc < 3) {
- fprintf(stderr, USAGE);
- exit(1);
- }
- if(sscanf(argv[2], "%d", &since) != 1) {
- fprintf(stderr, "derez: bad arg for -t option %s\n", argv[2]);
- exit(1);
- }
- if(since < 0 || since > 10000) {
- fprintf(stderr, "derez: bad value for -te argument\n");
- exit(1);
- }
- teflag = 1;
- argv += 2;
- argc -= 2;
- }
- while(argc > 1) {
- if((strncmp(argv[1], "/", strlen("/")) == 0) || (strncmp(argv[1], "../", strlen("../")) == 0)) {
- fprintf(stderr, "derez: Directories must be relative to .\n");
- exit(1);
- }
- if(lstat(argv[1], &statbuf)) {
- fprintf(stderr, "The directory %s must exist\n", argv[1]);
- exit(1);
- }
- if(statbuf.st_mode & S_IFDIR) {
- if(dirlist[0] != NULL)
- strcat(dirlist, " ");
- strcat(dirlist, argv[1]);
- argv += 1;
- argc -= 1;
- }
- else {
- fprintf(stderr, "derez: %s is not a directory\n", argv[1]);
- exit(1);
- }
- }
- }
- if(teflag) {
- sprintf(cmd, "find %s -type f -atime %d -print > MORGUE/DEREZ",
- (dirlist[0] == NULL ? "." : dirlist), since);
- }
- else {
- sprintf(cmd, "find %s -type f -atime +%d -print > MORGUE/DEREZ",
- (dirlist[0] == NULL ? "." : dirlist), since);
- }
-
- printf("%s\n", cmd);
- if(system(cmd) != 0) {
- fprintf(stderr, "derez: The attempt to create MORGUE/DEREZ failed\n");
- exit(1);
- }
- if((fptr = fopen("MORGUE/DEREZ", "r")) == NULL) {
- fprintf(stderr, "Open of MORGUE/DEREZ for reading failed\n");
- exit(1);
- }
- while(fgets(filename, MAXLEN, fptr) != NULL) {
- char *rightslash;
- /* Kill off the newline. */
- if(filename[strlen(filename) - 1] != '\n') {
- fprintf(stderr, "missing \\n on %s\n", filename);
- continue;
- }
- filename[strlen(filename) - 1] = NULL;
-
- /* If the path name is too long we want to leave the file
- alone so that the enmorgued tree can be archived using tar.
- */
- if(strlen(filename) > 99)
- continue;
-
- /* If the file basename is of the form .* we want to
- leave it alone to prevent removal of someones login
- directory or setup files. Of course if you take this
- code out you get automatic removal of directories
- associated with inactive accounts.
- */
- if((rightslash = rindex(filename, '/')) != NULL) {
- if(rightslash[1] == '.')
- continue;
- }
-
- if(
- /* We don't want to mess with files already in the MORGUE.
- */
- (strncmp(filename, "./MORGUE/", strlen("./MORGUE/")) != 0)
- && (strncmp(filename, "MORGUE/", strlen("MORGUE/")) != 0)
- /* The lost+found directory is a sacred system item.
- */
- && (strncmp(filename, "./lost+found/", strlen("./lost+found/")) != 0)
- && (strncmp(filename, "lost+found/", strlen("lost+found/")) != 0)
- /* Some systems have a directory local that needs to
- be left alone.
- */
- && (strncmp(filename, "./local/", strlen("./local/")) != 0)
- && (strncmp(filename, "local/", strlen("local/")) != 0)
- /* If we were to enmorgue a file named DEREZ, we
- would overwrite the list of files to move.
- */
- && (strcmp(filename, "./DEREZ") != 0)
- && (strcmp(filename, "DEREZ") != 0)
- ){
- /* We get to move the bugger. We first create any fix up
- the modes and ownership of any needed directories and then
- link the file over.
- */
- char target[MAXLEN];
- char *source = filename;
- char *dest;
-
- strcpy(target, "MORGUE");
- dest = target;
- while(*dest != NULL) dest += 1;
- while(*source == '.' || *source == '/') source += 1;
- while(1) {
- /* Peel off the next name in the chain.
- */
- *dest++ = '/';
- *dest = NULL;
- while(*source != '/' && *source != NULL) *dest++ = *source++;
- *dest = NULL;
- source += 1;
- if(stat(target + strlen("MORGUE/"), &statbuf)) {
- fprintf(stderr, "derez: stat on %s failed\n", target + strlen("MORGUE/"));
- perror("stat");
- exit(1);
- }
- if(statbuf.st_mode & S_IFDIR) {
- int owner = statbuf.st_uid;
- int group = statbuf.st_gid;
- int mode = statbuf.st_mode;
- if(mkdir(target, 0x777)) {
- if(errno != EEXIST) {
- fprintf(stderr, "derez: %s does not exist, but attempt to make it failed\n", target);
- perror("derez: mkdir");
- exit(1);
- }
- if(stat(target, &statbuf)) {
- perror("derez: stat");
- exit(1);
- }
- if(statbuf.st_uid != owner) {
- fprintf(stderr, "derez: Inconsistent owner for %s\n", target);
- exit(1);
- }
- if(statbuf.st_gid != group) {
- fprintf(stderr, "derez: Inconsistent group for %s\n", target);
- exit(1);
- }
- if(statbuf.st_mode != mode) {
- fprintf(stderr, "derez: Inconsistent mode for %s\n", target);
- exit(1);
- }
- }
- else {
- if(geteuid() == 0) {
- if(chown(target, owner, group)) {
- fprintf(stderr, "derez: chown of newly created directory %s failed\n", target);
- exit(1);
- }
- }
- else {
- sprintf(cmd, "/bin/chgrp %d %s", group, target);
- if(system(cmd)) {
- fprintf(stderr, "%s failed\n", cmd);
- exit(1);
- }
- }
- if(chmod(target, mode)) {
- fprintf(stderr, "derez: chmod of newly created directory %s failed\n", target);
- exit(1);
- }
- }
- }
- else {
- if(*(source - 1) != NULL) {
- fprintf(stderr, "derez: sanity check failed\n");
- exit(1);
- }
- if(!(statbuf.st_mode & S_IFREG)) {
- fprintf(stderr, "derez: %s is not a regular file\n", target + strlen("MORGUE/"));
- exit(1);
- }
- if(link(target + strlen("MORGUE/"), target)) {
- fprintf(stderr, "derez: link for %s failed\n", target);
- exit(1);
- }
- break;
- }
- }
-
- fprintf(stderr, "enmorgue of %s succeeded\n", filename);
- #define RIPEM
- #ifdef RIPEM
- unlink(filename);
- #else
- fprintf(stderr, "Would have unlinked %s\n", filename);
- #endif
- /* If it was the last file in the directory
- we also want to remove the directory.
- */
- while(1) {
- while(strlen(filename) > 0 && filename[strlen(filename) - 1] != '/') {
- filename[strlen(filename) - 1] = NULL;
- }
- if(strlen(filename) == 0 || strcmp(filename, "./") == 0)
- break;
-
- filename[strlen(filename) - 1] = NULL;
- #ifdef RIPEM
- rmdir(filename);
- #else
- fprintf(stderr, "would have rmdir'ed %s if empty\n", filename);
- #endif
- }
- }
- }
- fclose(fptr);
- }
- //go.sysin dd *
- if [ `wc -c < derez.c` != 7617 ]; then
- made=FALSE
- /bin/echo 'error transmitting "derez.c" --'
- /bin/echo 'length should be 7617, not' `wc -c < derez.c`
- else
- made=TRUE
- fi
- if [ $made = TRUE ]; then
- /bin/chmod 644 derez.c
- /bin/echo -n ' '; /bin/ls -ld derez.c
- fi
- /bin/echo 'Extracting readbyte.c'
- sed 's/^X//' <<'//go.sysin dd *' >readbyte.c
- #include <stdio.h>
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int fd;
- char cbuffer[512];
-
- if(argc != 2) {
- fprintf(stderr,"usage: readbyte file\n");
- exit(1);
- }
- if((fd=open(argv[1],0)) < 0) {
- fprintf(stderr,"cant open %s\n",argv[1]);
- exit(1);
- }
- if(read(fd,cbuffer,1) != 1) {
- fprintf(stderr,"cant read byte from file %s\n",argv[1]);
- exit(1);
- }
- }
- //go.sysin dd *
- if [ `wc -c < readbyte.c` != 363 ]; then
- made=FALSE
- /bin/echo 'error transmitting "readbyte.c" --'
- /bin/echo 'length should be 363, not' `wc -c < readbyte.c`
- else
- made=TRUE
- fi
- if [ $made = TRUE ]; then
- /bin/chmod 644 readbyte.c
- /bin/echo -n ' '; /bin/ls -ld readbyte.c
- fi
- /bin/echo 'Extracting agehist.c'
- sed 's/^X//' <<'//go.sysin dd *' >agehist.c
- X/* Agehist prints out file age histograms for the listed directories.
- */
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- FILE *popen();
-
- #define MAXLEN 1024
-
- #define MAXDAYS 180
-
- int data[MAXDAYS];
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int dir;
- int i;
- int ageindays;
- FILE *list;
- char filename[MAXLEN];
- char cmd[MAXLEN];
- struct stat statbuf;
- time_t time();
- time_t marker;
-
- marker = time((time_t *)0);
-
- for(dir = 1; dir < argc; dir += 1) {
-
- for(i = 0; i < MAXDAYS; i += 1) data[i] = 0;
-
- fprintf(stdout, "directory %s\n", argv[dir]);
- sprintf(cmd, "find %s -type f -print", argv[dir]);
- if((list = popen(cmd, "r")) == NULL) {
- fprintf(stderr, "Failed to open pipe\n");
- exit(1);
- }
- while(fgets(filename, MAXLEN, list) != NULL) {
- if(strlen(filename) >= MAXLEN-1) {
- fprintf(stderr, "path name too long\n");
- exit(1);
- }
- filename[strlen(filename)-1] = NULL;
- if(stat(filename, &statbuf)) {
- perror("agehist: stat");
- exit(1);
- }
- ageindays = (marker - statbuf.st_atime) / (24 * 60 * 60);
- /* fprintf(stdout, "%d %s\n", ageindays, filename);*/
- if(ageindays > MAXDAYS-1) ageindays = MAXDAYS-1;
- if(ageindays < 0) ageindays = 0;
- data[ageindays] += 1;
- }
- for(i = 0; i < MAXDAYS; i += 1) {
- if(i % 10 == 0) fprintf(stdout, "%4d |", i);
- fprintf(stdout, "%4d", data[i]);
- if(i % 10 == 9) fprintf(stdout, "\n");
- }
- fprintf(stdout, "\n");
- pclose(list);
- }
- }
- //go.sysin dd *
- if [ `wc -c < agehist.c` != 1411 ]; then
- made=FALSE
- /bin/echo 'error transmitting "agehist.c" --'
- /bin/echo 'length should be 1411, not' `wc -c < agehist.c`
- else
- made=TRUE
- fi
- if [ $made = TRUE ]; then
- /bin/chmod 644 agehist.c
- /bin/echo -n ' '; /bin/ls -ld agehist.c
- fi
- /bin/echo 'Extracting derez.1'
- sed 's/^X//' <<'//go.sysin dd *' >derez.1
- X.TH DEREZ LOCAL "2 February 1987"
- X.UC 4
- X.SH NAME
- derez \- find stale files, and move them into a MORGUE directory
- X.SH SYNOPSIS
- X.br
- \fBderez [-t[e] days] [dir1 dir2 dir3 ...]\fP
- X.SH DESCRIPTION
- X.I Derez
- is a program which is used to enmorgue stale files.
- Most if not \fIall\fP UNIX systems suffer from the finite disk size problem.
- If this problem is aggravated by users which have stale files that have not
- been read for some time,
- derez offers a solution.
- It moves the stale files to a \fIMORGUE\fP directory so that they can
- later be archived using \fItar\fP.
- Derez finds the stale files and moves them to the \fIMORGUE\fP directory,
- creating directories as needed.
- The files are moved using \fIlink()\fP,
- so the process is fast and preserves modification times of the files.
- As target directories are created,
- their ownership and modes are adjusted to be identical to those of the
- source directories.
- X.sp
- \fIDerez\fP uses the access times,
- time last \fIread\fP not time last \fIwritten\fP,
- of the files to determine their staleness.
- The default number of days since last access is 180 days,
- but this can be changed using the \fB-t\fP option.
- Normally,
- derez considers the files not accessed in the specified number of days or more
- to be stale.
- If the optional \fBe\fP appears,
- derez attacks only those files whose access dates are exactly the specified
- number of days in the past.
- If no directory list is given to derez it searches current directory,
- except the subdirectory \fIMORGUE\fP.
- The \fB-t\fP option and a directory list can be used to give special handling to
- antisocial users.
- See the man page for \fIagehist\fP for useful tool in this regard.
- Using agehist and the -te option,
- unreasonable peaks in the age spectrum of the files can be specifically attacked.
- This is done ruthlessly for any user which destroys the access date information
- in his files,
- whether intentionally or accidentally.
- Your files will be removed first,
- and then questions will be asked later.
- X.sp
- One can attempt to defeat derez by using \fIfind\fP and \fIreadbyte\fP to find and read all
- of the files in a directory tree.
- Using \fIfind\fP and \fIreadbyte\fP to update the access dates of files
- is reasonable for some \fIsmall\fP directory that you haven't
- looked at in some time, but will be using in a \fIfew days\fP.
- Doing this to a large fraction of your files will cause those files to
- be archived onto tape and removed from disk.
- Updating the staleness date of a directory tree using find and readbyte is not
- guaranteed to save the files from derez in any event.
- The derez daemon actively uses \fIagehist\fP to find such cases and tends to
- have a rather small staleness limit for these files.
- The more abnormal the age distribution of a user's files,
- the shorter the cutoff date gets.
- The system simply does not have enough disk capacity for
- archival store and user's are expected to use tape for such purposes.
- X.sp
- The best way to avoid getting derez'ed is to actively archive your stale files
- onto tape using \fItar\fP or \fIrerez\fP and keep them off line.
- \fIRerez\fP has the advantage that it remembers access dates,
- \fItar\fP does not and assumes the worst possibility.
- The current limits used by the derez daemon are 90 days,
- with reasonable peaks in the age spectrum being tolerated for 30 days
- and antisocial behavior being dealt with instantly and ruthlessly.
- The above limits are subject to change,
- on a per user basis,
- without notice.
- We will try to be reasonable.
- If you,
- however,
- are unreasonable and attempt to mung the access date information in your files
- we can be more unreasonable than you might imagine.
- X.sp
- Users should do a clean up of their stale files on a monthly basis
- and should actively move files associated with their various projects off line
- when these projects become inactive for more than a month or so.
- Derez itself is the recommended tool for this work as it does not
- modify the access dates of files you want to keep on the disk.
- If you don't keep your stale files off line,
- the derez daemon will do it for you automatically.
- Two copies of each derez tape archive are made and carefully
- checked for quality.
- This data is probably safer than the data left on the disk.
- The second tape archive is kept in a repository.
- If some of your files get archived,
- and you really need to use them in the next week or so,
- simply spool the \fIneeded\fP files back onto disk using \fIrerez\fP,
- or \fItar\fP(for the older derez archives).
- You should be very careful in doing this it might overwrite any existing files
- on the disk.
- \fITar\fP sets the access dates to the creation time of the file,
- \fIrerez\fP preserves access dates properly on it's archives.
- Don't be surprised if the files you spool back onto the disk,
- and do not actually use before the next run of \fIderez\fP,
- go right back out on tape.
- Did they need to be on disk if you didn't use them?
- X.sp
- The derez daemon is quite young and,
- like any newborn,
- wakes up whenever it gets hungry.
- The derez daemon is implemented using the latest 6'th generation AI technology
- and will learn appropriate algorithms to keep the required amount of disk
- space free.
- Abusive users will be handled on a case by case basis,
- with suitable ruthless application of rules which are changed by the
- daemon at will.
- Abuse of the disk space will not be tolerated.
- Large usage is acceptable,
- provided that no efforts are made that defeat the operation of derez.
- We have enough disk space for everyone to get their work done,
- but not a single byte for users to use as archival store.
- X.sp
- Although derez was written for the derez daemon's use,
- an individual user can use it to find and archive his stale files.
- This is done by making a subdirectory with the name \fIMORGUE\fP in any directory
- you would like to archive the descendant stale files.
- You then run \fIderez\fP.
- Derez will create a list of stale files,
- with the name \fIMORGUE/DEREZ\fP and then move the stale files into the directory
- MORGUE.
- If a file that is removed is the last file in it's parent directory,
- the parent directory is removed.
- The contents of the morgue directory can be archived using tar and then removed from the disk.
- The use of \fIderez\fP for stale file control is the only foolproof
- way to stay ahead of the derez daemon as it leaves the age distribution of
- the remaining files on disk unmodified.
- Scratch tapes can be found next to the system console.
- X.sp
- Files that have been derez'ed by the derez daemon can be recovered from the archive tape using
- \fIrerez\fP or \fItar\fP as noted on the tape.
- You should recover only those files that you are going to use.
- Files which you recover and don't use will be archived again at the next
- time the derez daemon wakes up.
- X.SH SEE ALSO
- find, readbyte, agehist, rerez, tar
- X.ta 3.0i
- X.SH FILES
- X/usr/local/morgue/u#.mm.dd.yy Lists of files derez'ed by the derez daemon.
- X.br
- MORGUE/DEREZ The files derez will enmorgue.
- X.br
- MORGUE/* The enmorgued files.
- X.SH "ARCHIVE TAPES"
- The archive tapes with dates matching the above file names are located
- next to the dump tapes in the machine room.
- These tapes should never be write enabled or removed from the machine room.
- A second copy of every archive tape is kept in a repository so any archived
- files are secure.
- X.SH "Attempts to defeat Derez"
- Will NOT be tolerated.
- You might save a small handful of files using \fIreadbyte\fP
- but that is about it.
- It is not recommended to attempt to save a large number of files from
- \fIderez\fP.
- The \fIderez\fP daemon will detect such attempts and archive the affected
- files.
- Attempting to save a large number of files using \fIfind\fP and \fIreadbyte\fP
- only produces a nice highly visible target for the the derez daemon.
- If you want to beat the derez daemon effectively, use derez yourself to clean
- your stale files off of the disk.
- This should be done monthly with a cutoff date less that that used by
- the derez daemon.
- X.SH BUGS
- DEREZ shares tar's limits on path name lengths.
- X.br
- MORGUE and DEREZ are reserved names.
- X.br
- In an ideal world \fIderez\fP would eventually archive itself onto tape.
- We don't live in an ideal world.
- X.br
- Using the recursive (-r) option of cp can get you in serious
- trouble as it will caused peaks in the age distribution of your files.
- These peaks will be excised at each run of derez.
- Use \fItar\fP or \fIrerez\fP to duplicate directory trees.
- //go.sysin dd *
- if [ `wc -c < derez.1` != 8340 ]; then
- made=FALSE
- /bin/echo 'error transmitting "derez.1" --'
- /bin/echo 'length should be 8340, not' `wc -c < derez.1`
- else
- made=TRUE
- fi
- if [ $made = TRUE ]; then
- /bin/chmod 644 derez.1
- /bin/echo -n ' '; /bin/ls -ld derez.1
- fi
- /bin/echo 'Extracting readbyte.1'
- sed 's/^X//' <<'//go.sysin dd *' >readbyte.1
- X.TH READBYTE LOCAL "2 February 1987"
- X.UC 4
- X.SH NAME
- readbyte \- Read the first byte of a file, removing its staleness
- X.SH SYNOPSIS
- X.br
- \fBreadbyte filename\fP
- X.SH DESCRIPTION
- X.I Readbyte
- reads the first byte of the specified file,
- changing its access date.
- It is used to remove staleness of a file to prevent derez from
- putting the file in the morgue for archival onto tape.
- Excessive use of \fIreadbyte\fP, or any other means of updating
- the access date of a file to defeat \fIderez\fP,
- is interpreted as antisocial by root.
- Antisocial behavior is dealt with as described in the man page for \fIderez\fP.
- X.SH SEE ALSO
- find, derez, agehist
- //go.sysin dd *
- if [ `wc -c < readbyte.1` != 640 ]; then
- made=FALSE
- /bin/echo 'error transmitting "readbyte.1" --'
- /bin/echo 'length should be 640, not' `wc -c < readbyte.1`
- else
- made=TRUE
- fi
- if [ $made = TRUE ]; then
- /bin/chmod 444 readbyte.1
- /bin/echo -n ' '; /bin/ls -ld readbyte.1
- fi
- /bin/echo 'Extracting agehist.1'
- sed 's/^X//' <<'//go.sysin dd *' >agehist.1
- X.TH AGEHIST LOCAL "3 April 1987"
- X.UC 4
- X.SH NAME
- agehist \- Display a histogram of file ages
- X.SH SYNOPSIS
- X.br
- \fBagehist dir [dir2 dir3 ...]\fP
- X.SH DESCRIPTION
- X.I Agehist
- prints a histogram of the age distribution, in days,
- of the files in the specified directory trees.
- Agehist is the latest in high technology tooling to detect users
- that insist on mass use of \fIreadbyte\fP to defeat \fIderez\fP.
- The derez daemon,
- which is based on the latest 6'th generation AI technology,
- enmorgues files which form unreasonable peaks in the age distribution
- even though the access date is less than the usual cutoff.
- X.SH SEE ALSO
- find, derez, readbyte
- //go.sysin dd *
- if [ `wc -c < agehist.1` != 642 ]; then
- made=FALSE
- /bin/echo 'error transmitting "agehist.1" --'
- /bin/echo 'length should be 642, not' `wc -c < agehist.1`
- else
- made=TRUE
- fi
- if [ $made = TRUE ]; then
- /bin/chmod 444 agehist.1
- /bin/echo -n ' '; /bin/ls -ld agehist.1
- fi
- /bin/echo 'Extracting rerez.1'
- sed 's/^X//' <<'//go.sysin dd *' >rerez.1
- X.TH REREZ 1 "10 March 1987"
- X.SH NAME
- rerez \- tape archiver, that remembers access dates
- X.SH SYNOPSIS
- X.B rerez
- [ key ] [ name ... ]
- X.SH DESCRIPTION
- X.PP
- X.I Rerez
- saves and restores multiple files on a single file (usually a magnetic
- tape, but it can be any file).
- Rerez is a munged version of \fItar\fP that remembers access dates.
- X.IR Rerez 's
- actions are controlled by the
- X.I key
- argument. The
- X.I key
- is a string of characters containing at most one function letter and possibly
- one or more function modifiers. Other arguments to
- X.I rerez
- are file or directory names specifying which files to dump or restore.
- In all cases, appearance of a directory name refers to
- the files and (recursively) subdirectories of that directory.
- X.PP
- The function portion of the key is specified by one of the following letters:
- X.TP 8
- X.B r
- The named files are written on the end of the tape. The
- X.B c
- function implies this.
- X.TP 8
- X.B x
- The named files are extracted from the tape. If the named file
- matches a directory whose contents had been written onto the tape, this
- directory is (recursively) extracted. The owner, modification time, and mode
- are restored (if possible). If no file argument is given, the entire content
- of the tape is extracted. Note that if multiple entries specifying the same
- file are on the tape, the last one overwrites all earlier.
- X.TP 8
- X.B t
- The names of the specified files are listed each time they occur on
- the tape. If no file argument is given, all of the names on the tape
- are listed.
- X.TP 8
- X.B u
- The named files are added to the tape if either they are not
- already there or have been modified since last put on the tape.
- X.TP 8
- X.B c
- Create a new tape; writing begins on the beginning of the tape
- instead of after the last file. This command implies
- X.BR r .
- X.TP 8
- X.B o
- On output, rerez normally places information specifying owner and modes
- of directories in the archive. Former versions of rerez, when encountering
- this information will give error message of the form
- X.br
- "<name>/: cannot create".
- X.br
- This option will suppress the directory information.
- X.TP 8
- X.B p
- This option says to restore files to their original modes,
- ignoring the present
- X.IR umask (2).
- Setuid and sticky information
- will also be restored to the super-user.
- X.PP
- The following characters may be used in addition to the letter
- which selects the function desired.
- X.TP 10
- X.B 0, ..., 9
- This modifier selects an alternate drive on which the tape is mounted.
- The default is drive 0 at 1600 bpi, which is normally /dev/rmt8.
- X.TP 10
- X.B v
- Normally
- X.I rerez
- does its work silently. The
- X.B v
- (verbose) option makes
- X.I rerez
- type the name of each file it treats preceded by the function
- letter. With the
- X.B t
- function, the verbose option
- gives more information about the tape entries than just their names.
- X.TP 10
- X.B w
- X.I Rerez
- prints the action to be taken followed by file name, then
- wait for user confirmation. If a word beginning with `y'
- is given, the action is done. Any other input means don't do it.
- X.TP 10
- X.B f
- X.I Rerez
- uses the next argument as the name of the archive instead of
- X/dev/rmt?.
- X.sp
- If the file name has the form
- X.IR system [. user ]:/dev/???
- X.I rerez
- will use the tape drive /dev/??? on the remote system
- X.IR system ,
- via
- X.IR rsh (1),
- and
- X.IR rmt (8).
- The optional
- X.I user
- portion of the pathname specifies the login name to use on the
- remote system.
- If it is not supplied, the current user's login name will be used.
- In all the cases, the user must have the appropriate
- permissions on the remote machine, in order to use this facility.
- X.sp
- If the name of the file is `\-', rerez writes to standard output or
- reads from standard input, whichever is appropriate. Thus,
- X.I rerez
- can be used as the head or tail of a filter chain.
- X.I Rerez
- can also be used to move hierarchies with the command
- X.ce 1
- cd fromdir; rerez cf - . | (cd todir; rerez xf -)
- X.TP 10
- X.B b
- X.I Rerez
- uses the next argument as the blocking factor for tape records. The
- default is 20 (the maximum). This option should only be used with raw magnetic
- tape archives (See
- X.B f
- above). The block size is determined automatically
- when reading tapes (key letters `x' and `t').
- X.TP 10
- X.B l
- tells
- X.I rerez
- to complain if it cannot resolve all of the links to the
- files dumped. If this is not specified, no error messages are printed.
- X.TP 10
- X.B m
- tells
- X.I rerez
- to print the message ``\fBYou must be joking!\fP'' and exit.
- X.TP 10
- X.B h
- Force
- X.I rerez
- to follow symbolic links as if they were normal files or
- directories. Normally,
- X.I rerez
- does not follow symbolic links.
- X.TP 10
- X.B B
- Forces input and output blocking to 20 blocks per record. This option
- was added so that
- X.I rerez
- can work across a communications channel where the blocking may not
- be maintained.
- X.PP
- If a file name is preceded by
- X.BR \-C ,
- then
- X.I rerez
- will perform a
- X.IR chdir (2)
- to that file name. This allows multiple directories not
- related by a close common parent to be archived using short
- relative path names. For example, to archive files from /usr/include
- and from /etc, one might use
- X.ti +0.5i
- rerez c -C /usr include -C / etc
- X.PP
- Previous restrictions dealing with
- X.IR rerez 's
- inability to properly handle blocked archives have been lifted.
- X.PP
- X.SH FILES
- X/dev/rmt?
- X.br
- X/tmp/tar*
- X.SH DIAGNOSTICS
- Complaints about bad key characters and tape read/write errors.
- X.br
- Complaints if enough memory is not available to hold the link tables.
- X.SH BUGS
- There is no way to ask for the
- X.IR n -th
- occurrence of a file.
- X.br
- Tape errors are handled ungracefully.
- X.br
- The
- X.B u
- option can be slow.
- X.br
- The current limit on file name length is 100 characters.
- X.br
- There is no way to selectively follow symbolic links.
- X.br
- Using a remote system's tape drive can be slow.
- X.SH NOTE
- \fIRerez\fP was created in order to have a means of archiving files
- on tape in a way that restored their access dates upon extraction.
- When \fIrerez\fP is used to extract these files the creation and
- access dates are restored to their original values.
- If the user does not actually use the files by the next run of \fIderez\fP
- the files did not need to be on disk and will be archived again.
- \fITar\fP was used for these archives in the past,
- but the loss of access dates caused peaks in the age spectrum and
- resulted in a rather aggressive derez daemon.
- Rerez has been modified to set access dates to be the same as the
- creation dates of a files to avoid future problems.
- As the creation date of a file may be substantially older than
- the date of last access,
- users of tar are at somewhat of a disadvantage.
- A \fIrerez\fP archive is unfortunately not compatible with tar,
- and therefore not portable to other machines.
- //go.sysin dd *
- if [ `wc -c < rerez.1` != 6645 ]; then
- made=FALSE
- /bin/echo 'error transmitting "rerez.1" --'
- /bin/echo 'length should be 6645, not' `wc -c < rerez.1`
- else
- made=TRUE
- fi
- if [ $made = TRUE ]; then
- /bin/chmod 644 rerez.1
- /bin/echo -n ' '; /bin/ls -ld rerez.1
- fi
-
-