home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume19
/
shape
/
part19
< prev
next >
Wrap
Text File
|
1989-05-31
|
55KB
|
1,829 lines
Subject: v19i032: A software configuration management system, Part19/33
Newsgroups: comp.sources.unix
Sender: sources
Approved: rsalz@uunet.UU.NET
Submitted-by: Axel Mahler <unido!coma!axel>
Posting-number: Volume 19, Issue 32
Archive-name: shape/part19
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 19 (of 33)."
# Contents: src/afs/afdelta.c src/shape/rule.c src/vc/doretrv.c
# Wrapped by rsalz@papaya.bbn.com on Thu Jun 1 19:27:11 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/afs/afdelta.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/afs/afdelta.c'\"
else
echo shar: Extracting \"'src/afs/afdelta.c'\" \(17045 characters\)
sed "s/^X//" >'src/afs/afdelta.c' <<'END_OF_FILE'
X/*
X * Copyright (C) 1989, 1990 W. Koch, A. Lampen, A. Mahler, W. Obst,
X * and U. Pralle
X *
X * This software is published on an as-is basis. There is ABSOLUTELY NO
X * WARRANTY for any part of this software to work correctly or as described
X * in the manuals. We do not accept any liability for any kind of damage
X * caused by use of this software, such as loss of data, time, money, or
X * effort.
X *
X * Permission is granted to use, copy, modify, or distribute any part of
X * this software as long as this is done without asking for charge, and
X * provided that this copyright notice is retained as part of the source
X * files. You may charge a distribution fee for the physical act of
X * transferring a copy, and you may at your option offer warranty
X * protection in exchange for a fee.
X *
X * Direct questions to: Tech. Univ. Berlin
X * Wilfried Koch
X * Sekr. FR 5-6
X * Franklinstr. 28/29
X * D-1000 Berlin 10, West Germany
X *
X * Tel: +49-30-314-22972
X * E-mail: shape@coma.uucp or shape@db0tui62.bitnet
X */
X/*
X * Shape/AFS
X *
X * afdelta.c -- Delta processing
X *
X * Author: Andreas Lampen, TU-Berlin (andy@coma.UUCP
X * andy@db0tui62.BITNET)
X *
X * $Header: afdelta.c[1.4] Wed Feb 22 16:27:26 1989 andy@coma published $
X *
X * EXPORT:
X * af_nodelta -- save entire file
X * af_dodelta -- save delta
X * af_undodelta -- rebuild file
X * af_rmdelta -- remove delta from delta chain
X */
X
X#include <stdio.h>
X
X#include "typeconv.h"
X#include "afsys.h"
X#include "afs.h"
X
X/*====================================================================
X * af_nodelta
X *
X * Store the busy version (busykey) without building a delta.
X * "nodelta" is necessary for saving the initial version (1.0)
X * or for storing versions without delta technique.
X *
X *====================================================================*/
X
XEXPORT af_nodelta (busykey, savekey)
X
X Af_key *busykey;
X Af_key *savekey;
X{
X char *malloc();
X FILE *busyfile;
X
X VATTR(savekey).af_fsize = af_retfsize (busykey->af_ldes->af_busyfilename);
X VATTR(savekey).af_dsize = 0;
X VATTR(savekey).af_repr = AF_CHUNK;
X VATTR(savekey).af_data =
X af_malloc (savekey->af_ldes, (unsigned) VATTR(savekey).af_fsize);
X
X if ((busyfile = fopen (busykey->af_ldes->af_busyfilename, "r")) == (FILE *)0)
X FAIL ("nodelta", "fopen", AF_ESYSERR, ERROR);
X
X if (fread (VATTR(savekey).af_data, sizeof (char), (Size_t) VATTR(savekey).af_fsize, busyfile) != VATTR(savekey).af_fsize)
X FAIL ("nodelta", "fread", AF_ESYSERR, ERROR);
X
X (void) fclose (busyfile);
X savekey->af_ldes->af_datasize += VATTR(savekey).af_fsize;
X return (AF_OK);
X} /* af_nodelta */
X
X
X
X/*====================================================================
X * af_dodelta
X *
X * Build a delta between a busy version (busykey) and its preceeding
X * version (predkey) and store it as a new version (savekey).
X * If no busykey is given ((Af_key *)0), build a null delta and store
X * it as new version.
X * The latter case is needed, if a version shall be stored with different
X * attributes but unchanged contents.
X *
X *====================================================================*/
X
XEXPORT af_dodelta (busykey, predkey, savekey)
X
X Af_key *busykey;
X Af_key *predkey;
X Af_key *savekey;
X{
X char *delname, *malloc();
X FILE *busyfile, *delfile;
X
X if (busykey != (Af_key *)0 )
X {
X /* read in busyfile for delta processing */
X VATTR(savekey).af_fsize = af_retfsize(busykey->af_ldes->af_busyfilename);
X
X VATTR(savekey).af_data =
X af_malloc (savekey->af_ldes, (unsigned) VATTR(savekey).af_fsize);
X if ((busyfile = fopen (busykey->af_ldes->af_busyfilename,"r"))
X == (FILE *)0)
X FAIL ("dodelta", "fopen", AF_ESYSERR, ERROR);
X
X if (fread (VATTR(savekey).af_data, sizeof (char), (Size_t) VATTR(savekey).af_fsize, busyfile) != VATTR(savekey).af_fsize)
X FAIL ("dodelta", "fread", AF_ESYSERR, ERROR);
X
X (void) fclose (busyfile);
X savekey->af_ldes->af_datasize += VATTR(savekey).af_fsize;
X VATTR(savekey).af_dsize = 0;
X VATTR(savekey).af_repr = AF_CHUNK;
X }
X else
X /* produce null delta (new generation) */
X {
X VATTR(savekey).af_data = VATTR(predkey).af_data;
X VATTR(savekey).af_fsize = VATTR(predkey).af_fsize;
X VATTR(savekey).af_dsize = 0;
X VATTR(savekey).af_repr = AF_CHUNK;
X savekey->af_ldes->af_datasize += VATTR(savekey).af_fsize;
X }
X
X /* if version opens a new branch, no delta processing is necessary */
X if ((predkey->af_ldes == (Af_revlist *)0) ||
X (VATTR(predkey).af_repr == AF_DELTA))
X {
X VATTR(savekey).af_predgen = AF_NOVNUM;
X VATTR(savekey).af_predrev = AF_NOVNUM;
X return (AF_OK);
X }
X
X /* else do delta processing */
X
X /* create filename for delta */
X delname = af_gtmpname (CATTR(savekey).af_syspath, VATTR(savekey).af_name);
X af_regtmpfile (delname);
X
X if (lcs (VATTR(savekey).af_data, VATTR(predkey).af_data,
X VATTR(savekey).af_fsize, VATTR(predkey).af_fsize, delname) == ERROR)
X FAIL ("dodelta", "", AF_EDELTA, ERROR);
X
X /* update predversion */
X /* read deltafile */
X VATTR(predkey).af_dsize = af_retfsize (delname);
X if ((VATTR(predkey).af_dsize > VATTR(predkey).af_fsize) ||
X (busykey == (Af_key *)0 ))
X VATTR(predkey).af_data = af_malloc (predkey->af_ldes, (unsigned) VATTR(predkey).af_dsize);
X
X if ((delfile = fopen (delname, "r")) == (FILE *)0)
X FAIL ("dodelta", "fopen", AF_ESYSERR, ERROR);
X
X if ((fread (VATTR(predkey).af_data, sizeof (char), (Size_t) VATTR(predkey).af_dsize, delfile)) != VATTR(predkey).af_dsize)
X FAIL ("dodelta", "fread", AF_ESYSERR, ERROR);
X (void) fclose (delfile);
X
X /* remove tmp-file */
X (void) af_unlink (delname);
X af_unregtmpfile (delname);
X
X /* update list descriptor (file is replaced by delta) */
X savekey->af_ldes->af_datasize -= VATTR(predkey).af_fsize;
X savekey->af_ldes->af_datasize += VATTR(predkey).af_dsize;
X VATTR(predkey).af_repr = AF_DELTA;
X VATTR(predkey).af_succgen = VATTR(savekey).af_gen;
X VATTR(predkey).af_succrev = VATTR(savekey).af_rev;
X
X return (AF_OK);
X} /* af_dodelta */
X
X
X
X/*====================================================================
X * af_undodelta
X *
X * The version pointed to by deltakey is supposed to be a (at least)
X * saved version represented by a chunk (AF_CHUNK) or a delta (AF_DELTA).
X * Passing a busy version causes an error (AF_NOVERS).
X * Filename has to be the name of an accessible UNIX-file,
X * where the rebuilt version will be stored.
X * The version pointed to by deltakey remains unchanged.
X *
X *====================================================================*/
X
XEXPORT af_undodelta (deltakey, filename)
X Af_key *deltakey;
X char *filename;
X{
X Af_key *deltachain, *keyptr;
X char *tmpname, *data, *malloc(), *realloc();
X int i;
X off_t fsize;
X FILE *tmpfile;
X
X /* this error should never occur */
X if (VATTR(deltakey).af_repr == AF_FILE)
X FAIL ("undodelta", "wrong kind of representation", AF_EINTERNAL, ERROR);
X
X if ((deltachain = (Af_key *) malloc ((unsigned) (AF_SEGLEN * sizeof (Af_key)))) == (Af_key *)0)
X FAIL ("undodelta", "malloc", AF_ESYSERR, ERROR);
X
X /* collect deltachain */
X i = 0;
X deltachain[0] = *deltakey;
X keyptr = deltakey;
X while (VATTR(keyptr).af_repr == AF_DELTA)
X {
X i++;
X if ((i & AF_SEGLEN) == AF_SEGLEN) /* if segment is full */
X if ((deltachain = (Af_key *) realloc ((char *) deltachain, (unsigned) ((i + AF_SEGLEN) * sizeof (Af_key)))) == (Af_key *)0)
X FAIL ("undodelta", "realloc", AF_ESYSERR, ERROR);
X
X if (af_buildkey (deltakey->af_ldes, VATTR(keyptr).af_succgen,
X VATTR(keyptr).af_succrev, &(deltachain[i])) == ERROR)
X FAIL ("undodelta", "delta chain broken", AF_EINTERNAL, ERROR);
X keyptr = &(deltachain[i]);
X }
X
X fsize = VATTR(keyptr).af_fsize;
X if ((data = malloc ((unsigned) VATTR(keyptr).af_fsize)) == (char *)0)
X FAIL ("undodelta", "malloc", AF_ESYSERR, ERROR);
X bcopy (VATTR(keyptr).af_data, data, (Size_t) fsize);
X /* first step is done */
X i--;
X
X /* process delta chain */
X tmpname = af_gtmpname (CATTR(deltakey).af_syspath, VATTR(deltakey).af_name);
X af_regtmpfile (tmpname);
X
X if (i < 0) /* no delta chain */
X {
X if ((tmpfile = fopen (tmpname, "w")) == (FILE *)0)
X FAIL ("undodelta", "fopen", AF_ESYSERR, ERROR);
X (void) fwrite (data, (Size_t) fsize, sizeof (char), tmpfile);
X (void) fclose (tmpfile);
X }
X
X /* else */
X for (i; i >= 0; i--)
X {
X keyptr = &(deltachain[i]);
X if (bsfd (data, VATTR(keyptr).af_data, fsize, VATTR(keyptr).af_dsize,
X tmpname) == ERROR)
X FAIL ("undodelta", "", AF_EDELTA, ERROR);
X if (i == 0)
X continue; /* increase performance */
X fsize = af_retfsize (tmpname);
X if ((data = realloc (data, (unsigned) (fsize * sizeof (char)))) == (char *)0)
X FAIL ("undodelta", "realloc", AF_ESYSERR, ERROR);
X if ((tmpfile = fopen (tmpname, "r")) == (FILE *)0)
X FAIL ("undodelta", "fopen", AF_ESYSERR, ERROR);
X (void) fread (data, (Size_t) fsize, sizeof (char), tmpfile);
X (void) fclose (tmpfile);
X }
X free ((char *) deltachain);
X free (data);
X
X (void) af_unlink (filename);
X if (af_syslink (tmpname, filename) == ERROR)
X FAIL ("undodelta", "link", AF_ESYSERR, ERROR);
X (void) af_unlink (tmpname);
X af_unregtmpfile (tmpname);
X
X return (AF_OK);
X}
X
X/*====================================================================
X * af_rmdelta
X *
X *====================================================================*/
X
XEXPORT af_rmdelta (deltakey)
X Af_key *deltakey;
X{
X register i;
X int succsize, predsize;
X char *succdata, *preddata, *malloc(), *realloc(), *tmpname;
X FILE *tmpfile;
X Af_key *deltachain, *keyptr, *predptr;
X /* deltachain shall hold all keys from the physical
X * predecessor to the end of the physical line of
X * descent (chunk). That is:
X * deltachain[0] = predecessor
X * deltachain[1] = deltakey
X * deltachain[2] = successor ...
X * ... deltachain[n] = chunk
X */
X
X if ((deltachain = (Af_key *) malloc ((unsigned) (AF_SEGLEN * sizeof (Af_key)))) == (Af_key *)0)
X FAIL ("rmdelta", "malloc", AF_ESYSERR, ERROR);
X
X /* update predecessor attributes of successor version */
X if ((VATTR(deltakey).af_succgen != AF_NOVNUM) &&
X (VATTR(deltakey).af_succrev != AF_NOVNUM))
X {
X (void) af_buildkey (deltakey->af_ldes, VATTR(deltakey).af_succgen, VATTR(deltakey).af_succrev, &(deltachain[2]));
X VATTR((&(deltachain[2]))).af_predgen = VATTR(deltakey).af_predgen;
X VATTR((&(deltachain[2]))).af_predrev = VATTR(deltakey).af_predrev;
X }
X
X /* if deltakey points to the predecessor of the busy version, */
X /* update busy version (should be optimized) */
X /* works only, if busy version is at position 0 */
X if ((deltakey->af_ldes->af_list[0].af_predgen == VATTR(deltakey).af_gen) &&
X (deltakey->af_ldes->af_list[0].af_predrev == VATTR(deltakey).af_rev))
X {
X deltakey->af_ldes->af_list[0].af_predgen = AF_NOVNUM;
X deltakey->af_ldes->af_list[0].af_predrev = AF_NOVNUM;
X }
X
X /* if deltakey points to first element in delta chain */
X /* no delta processing is necessary */
X if ((VATTR(deltakey).af_predgen == AF_NOVNUM) &&
X (VATTR(deltakey).af_predrev == AF_NOVNUM))
X {
X return (AF_OK);
X }
X
X /* else collect delta chain */
X (void) af_buildkey (deltakey->af_ldes, VATTR(deltakey).af_predgen,
X VATTR(deltakey).af_predrev, &(deltachain[0]));
X predptr = &(deltachain[0]);
X deltachain[1] = *deltakey;
X /* if deltakey points to chunk do nothing else */
X if ((VATTR(deltakey).af_succgen == AF_NOVNUM) &&
X (VATTR(deltakey).af_succrev == AF_NOVNUM))
X {
X i = 1;
X }
X else
X {
X i = 2;
X keyptr = &(deltachain[2]);
X while (VATTR(keyptr).af_repr == AF_DELTA)
X {
X i++;
X if ((i & AF_SEGLEN) == AF_SEGLEN) /* if segment is full */
X if ((deltachain = (Af_key *) realloc ((char *) deltachain, (unsigned) ((i+AF_SEGLEN) * sizeof(Af_key)))) == (Af_key *)0)
X FAIL ("rmdelta", "realloc", AF_ESYSERR, ERROR);
X
X (void) af_buildkey (deltakey->af_ldes, VATTR(keyptr).af_succgen,
X VATTR(keyptr).af_succrev, &(deltachain[i]));
X keyptr = &(deltachain[i]);
X }
X }
X
X tmpname = af_gtmpname (CATTR(deltakey).af_syspath, VATTR(deltakey).af_name);
X af_regtmpfile (tmpname);
X
X /* if deltakey points to chunk, only the predecessor version has to */
X /* be rebuilt */
X if (i == 1)
X {
X /* generate chunk for predecessor */
X if (bsfd (VATTR(deltakey).af_data, VATTR(predptr).af_data,
X VATTR(deltakey).af_fsize, VATTR(predptr).af_dsize, tmpname)
X == ERROR)
X FAIL ("rmdelta", "", AF_EDELTA, ERROR);
X
X VATTR(predptr).af_repr = AF_CHUNK;
X /* update sizes in revision list descriptor and in attribute buffer */
X deltakey->af_ldes->af_datasize -= VATTR(predptr).af_dsize;
X VATTR(predptr).af_dsize = 0;
X VATTR(predptr).af_fsize = af_retfsize (tmpname);
X deltakey->af_ldes->af_datasize += VATTR(predptr).af_fsize;
X
X /* if VATTR(predptr).af_data points to memory allocated by an own
X * af_malloc (and not in af_readdata), this memory segment remains
X * "unfreed" (This is a BUG !).
X */
X if ((VATTR(predptr).af_data = af_malloc (predptr->af_ldes, (unsigned) (VATTR(predptr).af_fsize * sizeof(char)))) == (char *)0)
X FAIL ("rmdelta", "malloc", AF_ESYSERR, ERROR);
X
X tmpfile = fopen (tmpname, "r");
X (void) fread (VATTR(predptr).af_data, (Size_t) VATTR(predptr).af_fsize, sizeof (char), tmpfile);
X (void) fclose (tmpfile);
X (void) af_unlink (tmpname);
X af_unregtmpfile (tmpname);
X VATTR(predptr).af_succgen = AF_NOVNUM;
X VATTR(predptr).af_succrev = AF_NOVNUM;
X return (AF_OK);
X }
X
X /* else process delta chain and build pred and succ version */
X succsize = VATTR(keyptr).af_fsize;
X if ((succdata = malloc ((unsigned) (VATTR(keyptr).af_fsize * sizeof (char)))) == (char *)0)
X FAIL ("rmdelta", "malloc", AF_ESYSERR, ERROR);
X bcopy (VATTR(keyptr).af_data, succdata, succsize);
X /* first step is done */
X i--;
X
X /* first regenerate sucessor version and leave it in the buffer "succdata" */
X for (i; i >= 2; i--)
X {
X keyptr = &(deltachain[i]);
X if (bsfd (succdata, VATTR(keyptr).af_data, (long) succsize,
X VATTR(keyptr).af_dsize, tmpname) == ERROR)
X FAIL ("rmdelta", "", AF_EDELTA, ERROR);
X
X succsize = af_retfsize (tmpname);
X if ((succdata = realloc (succdata, (unsigned) (succsize * sizeof(char)))) == (char *)0)
X FAIL ("rmdelta", "realloc", AF_ESYSERR, ERROR);
X tmpfile = fopen (tmpname, "r");
X (void) fread (succdata, (Size_t)succsize, sizeof (char), tmpfile);
X (void) fclose (tmpfile);
X }
X /* regenerate predecessor version in buffer "preddata" */
X if (bsfd (succdata, VATTR(deltakey).af_data, (long) succsize,
X VATTR(deltakey).af_dsize, tmpname) == ERROR)
X FAIL ("rmdelta", "", AF_EDELTA, ERROR);
X
X predsize = af_retfsize (tmpname);
X if ((preddata = malloc ((unsigned) (predsize * sizeof (char)))) == (char *)0)
X FAIL ("rmdelta", "malloc", AF_ESYSERR, ERROR);
X tmpfile = fopen (tmpname, "r");
X (void) fread (preddata, predsize, sizeof (char), tmpfile);
X (void) fclose (tmpfile);
X if (bsfd (preddata, VATTR((&(deltachain[0]))).af_data, (long) predsize, VATTR((&(deltachain[0]))).af_dsize, tmpname) == ERROR)
X FAIL ("rmdelta", "", AF_EDELTA, ERROR);
X
X predsize = af_retfsize (tmpname);
X if ((preddata = realloc (preddata, (unsigned) (predsize * sizeof (char)))) == (char *)0)
X FAIL ("rmdelta", "realloc", AF_ESYSERR, ERROR);
X tmpfile = fopen (tmpname, "r");
X (void) fread (preddata, predsize, sizeof (char), tmpfile);
X (void) fclose (tmpfile);
X
X /* build new delta for predecessor version */
X if (lcs (succdata, preddata, (long) succsize, (long) predsize, tmpname) == ERROR)
X FAIL ("rmdelta", "", AF_EDELTA, ERROR);
X
X /* update sizes in revision list descriptor and in attribute buffer */
X deltakey->af_ldes->af_datasize -= VATTR(predptr).af_dsize;
X VATTR(predptr).af_dsize = af_retfsize (tmpname);
X deltakey->af_ldes->af_datasize += VATTR(predptr).af_dsize;
X
X /* if VATTR(predptr).af_data points to memory allocated by an own
X * af_malloc (and not in af_readdata), this memory segment remains
X * "unfreed" (This is a BUG !).
X */
X if ((VATTR(predptr).af_data = af_malloc (predptr->af_ldes, (unsigned) (VATTR(predptr).af_dsize*sizeof(char)))) == (char *)0)
X FAIL ("rmdelta", "malloc", AF_ESYSERR, ERROR);
X tmpfile = fopen (tmpname, "r");
X (void) fread (VATTR(predptr).af_data, (Size_t) VATTR(predptr).af_dsize, sizeof (char), tmpfile);
X (void) fclose (tmpfile);
X (void) af_unlink (tmpname);
X af_unregtmpfile (tmpname);
X free (succdata);
X free (preddata);
X VATTR(predptr).af_succgen = VATTR((&(deltachain[2]))).af_gen;
X VATTR(predptr).af_succrev = VATTR((&(deltachain[2]))).af_rev;
X free ((char *) deltachain);
X return (AF_OK);
X}
X
END_OF_FILE
if test 17045 -ne `wc -c <'src/afs/afdelta.c'`; then
echo shar: \"'src/afs/afdelta.c'\" unpacked with wrong size!
fi
# end of 'src/afs/afdelta.c'
fi
if test -f 'src/shape/rule.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/shape/rule.c'\"
else
echo shar: Extracting \"'src/shape/rule.c'\" \(17098 characters\)
sed "s/^X//" >'src/shape/rule.c' <<'END_OF_FILE'
X/*
X * Copyright (C) 1989, 1990 W. Koch, A. Lampen, A. Mahler, W. Obst,
X * and U. Pralle
X *
X * This software is published on an as-is basis. There is ABSOLUTELY NO
X * WARRANTY for any part of this software to work correctly or as described
X * in the manuals. We do not accept any liability for any kind of damage
X * caused by use of this software, such as loss of data, time, money, or
X * effort.
X *
X * Permission is granted to use, copy, modify, or distribute any part of
X * this software as long as this is done without asking for charge, and
X * provided that this copyright notice is retained as part of the source
X * files. You may charge a distribution fee for the physical act of
X * transferring a copy, and you may at your option offer warranty
X * protection in exchange for a fee.
X *
X * Direct questions to: Tech. Univ. Berlin
X * Wilfried Koch
X * Sekr. FR 5-6
X * Franklinstr. 28/29
X * D-1000 Berlin 10, West Germany
X *
X * Tel: +49-30-314-22972
X * E-mail: shape@coma.uucp or shape@db0tui62.bitnet
X */
X#ifndef lint
Xstatic char *RCSid = "$Header: rule.c,v 3.0 89/01/24 11:36:35 wolfgang Stable $";
X#endif
X#ifndef lint
Xstatic char *ConfFlg = CFFLGS; /* should be defined from within Makefile */
X#endif
X/*
X * $Log: rule.c,v $
X * Revision 3.0 89/01/24 11:36:35 wolfgang
X * New System Generation
X *
X * Revision 2.16 89/01/19 12:38:05 wolfgang
X * check for .IGNORE added
X *
X * Revision 2.15 89/01/03 13:13:00 wolfgang
X * changes done for lint
X *
X * Revision 2.14 88/12/21 15:11:59 wolfgang
X * changes done for lint
X *
X * Revision 2.13 88/12/19 13:24:06 wolfgang
X * things for special targets .BPOOL & .NOBPOOL added.
X *
X * Revision 2.12 88/12/12 13:16:40 wolfgang
X * bug fixed (something for sun).
X *
X * Revision 2.11 88/11/22 17:17:14 wolfgang
X * changes done for sun & bugs fixed.
X *
X * Revision 2.10 88/11/21 15:48:55 wolfgang
X * return code of all malloc's checked
X *
X * Revision 2.9 88/11/08 11:05:13 wolfgang
X * This version is part of a release
X *
X * Revision 2.8 88/09/16 12:59:29 wolfgang
X * overload_stdrules() added.
X *
X * Revision 2.7 88/09/14 10:52:06 wolfgang
X * undone last changes
X *
X * Revision 2.6 88/09/13 14:41:03 wolfgang
X * Because of bad performance: get_src_name deleted.
X *
X * Revision 2.5 88/09/09 11:57:33 wolfgang
X * Performance improved. get_src_name has been called to often.
X *
X * Revision 2.4 88/08/31 12:03:20 wolfgang
X * Standard dependent added to depency list.
X *
X * Revision 2.3 88/08/23 15:37:13 wolfgang
X * ruledump() has been changed. In dependncy lines the first dependent
X * is supressed if it is a name of a selection rule and we are generating
X * a confid.
X *
X * Revision 2.2 88/08/23 10:25:36 wolfgang
X * Changed ruledump; now it can be used both to generate confid's
X * and for the -d option.
X *
X * Revision 2.1 88/08/19 10:17:50 wolfgang
X * This version is part of a release
X *
X */
X
X/* allow a:b ?????? geht noch nicht ....
X a:c
X a:d etc. if only one action is defined !!!!! */
X
X/* :: still not yet implememnted */
X/* intermixing of implicit "." rules and normal targets is *not* allowed */
X
X#include "shape.h"
X#include "rule.h"
X
Xextern int hashval();
Xextern int errexit();
Xextern char *expandmacro();
Xextern char *get_src_name();
Xextern struct rules *stdruletab[];
Xextern int implicit_suffs[];
Xextern Bool is_old_rule();
Xstruct rules *ruletab[RULETABSIZE];
Xchar *firsttarget;
XBool oldrule;
X
Xint depnr;
Xint targnr;
Xint cmdnr;
Xint heritnr;
Xchar *targfield[MAXTARGS];
Xchar *depfield[MAXDEPS];
Xchar *cmdfield[MAXCMDS];
Xchar *heritfield[MAXHERIT];
X
X
Xruledef(string)
X char *string;
X{
Xint i = 0;
Xint k = 0;
Xchar klazu;
Xchar *t;
X
Xtargnr = 0;
Xdepnr = 0;
Xcmdnr = 0;
Xheritnr = 0;
X
Xif ((t = malloc( (unsigned) strlen(string) + 1)) == NIL)
X errexit(10,"malloc");
X
Xstring = expandmacro(string);
X
Xwhile(string[i] != ':')
X {
X while((string[i] != ' ') && (string[i] != '\t') && (string[i] != ':'))
X {
X t[k] = string[i];
X i++;
X k++;
X }
X t[k] = '\0';
X targnr++;
X if (targnr > MAXTARGS)
X errexit(27, "targets");
X if ((targfield[targnr] = malloc((unsigned) strlen(t) + 1)) == NIL)
X errexit(10,"malloc");
X (void) strcpy(targfield[targnr], t);
X#ifdef DEBUG_RULE
Xprintf("target no. %d = #%s#\n", targnr, targfield[targnr]);
X#endif DEBUG_RULE
X k = 0;
X while((string[i] == ' ') || (string[i] == '\t'))
X i++;
X }
Xif (string[i+1] == ':')
X {
X doublecolon = TRUE;
X i = i + 2;
X }
Xelse
X i++;
X
Xwhile((string[i] != '\0') && (string[i] != ';') && (string[i] != ':'))
X {
X while((string[i] == ' ') || (string[i] == '\t') ||
X (string[i] == '\\'))
X {
X if ((string[i] == '\\') && (string[i+1] == '\n'))
X i = i+2;
X else
X i++;
X }
X while((string[i] != ' ') && (string[i] != '\t') &&
X (string[i] != ';') && (string[i] != '\0') &&
X (string[i] != ':') && (string[i] != '\\'))
X {
X t[k] = string[i];
X i++;
X k++;
X }
X t[k] = '\0';
X if (k != 0)
X {
X depnr++;
X if (depnr > MAXDEPS)
X errexit(27, "dependents");
X if ((depfield[depnr] = malloc((unsigned) strlen(t) + 1)) == NIL)
X errexit(10,"malloc");
X (void) strcpy(depfield[depnr],t);
X#ifdef DEBUG_RULE
Xprintf("dependent no. %d=#%s#\n", depnr , depfield[depnr]);
X#endif DEBUG_RULE
X }
X k = 0;
X }
X
X
Xwhile((string[i] == ' ') || (string[i] == '\t'))
X i++;
X
X/* heritage */
X
Xk = 0;
Xif (string[i] == ':')
X {
X i++;
X while( (string[i] != '\0') )
X {
X while((string[i] == ' ') || (string[i] == '\t'))
X i++;
X if (string[i] != '+')
X errexit(26, &string[i]);
X if (string[i+1] == '(')
X klazu = ')';
X else
X {
X if (string[i+1] == '{')
X klazu = '}';
X else
X klazu = ' ';
X }
X
X while (string[i] != klazu)
X {
X t[k] = string[i];
X i++;
X k++;
X if (string[i] == '\0')
X errexit(26,&string[i]);
X }
X t[k] = string[i];
X k++;
X i++;
X t[k] = '\0';
X heritnr++;
X if (heritnr > MAXHERIT)
X errexit(27, "iherits");
X if ((heritfield[heritnr] = malloc((unsigned) strlen(t) + 1)) == NIL)
X errexit(10,"malloc");
X (void) strcpy(heritfield[heritnr],t);
X k = 0;
X }
X }
X
X/* commands on ruledef line */
Xif( string[i] == ';')
X {
X i++;
X while( (string[i] != '\0'))
X {
X t[k] = string[i];
X i++;
X k++;
X }
X t[k] = '\0';
X cmdnr++;
X if (cmdnr > MAXCMDS)
X errexit(27, "commands");
X if ((cmdfield[cmdnr] = malloc((unsigned) strlen(t) + 1)) == NIL)
X errexit(10,"malloc");
X if (t[strlen(t)-1] == '\n')
X t[strlen(t)-1] = '\0';
X (void) strcpy(cmdfield[cmdnr], t);
X#ifdef DEBUG_RULE
Xprintf("command[%d] = #%s#\n", cmdnr, cmdfield[cmdnr]);
X#endif DEBUG_RULE
X }
X}
X
Xrulecont(string)
X char *string;
X{
X/* only commands have been found */
Xcmdnr++;
Xif(cmdnr > MAXCMDS)
X errexit(27, "commands");
Xif ((cmdfield[cmdnr] = malloc ((unsigned) strlen(string) + 1)) == NIL)
X errexit(10,"malloc");
Xif (string[strlen(string)-1] == '\n')
X string[strlen(string)-1] = '\0';
X(void) strcpy(cmdfield[cmdnr], string);
X#ifdef DEBUG_RULE
Xprintf("command[%d] = #%s#\n", cmdnr, cmdfield[cmdnr]);
X#endif DEBUG_RULE
X}
X
Xruleend()
X{
X struct rules *current;
X struct cmds *curcmd;
X int i = 0;
X int j = 0;
X int jjj = 0;
X int kkk = 0;
X int xx = 0;
X int ss = 0;
X int minus = 0;
X Bool src_found = FALSE;
X int hasht = 0;
X char *p;
X char *srcname;
X Bool std_rule = FALSE;
X Bool found = FALSE;
X int targs = 0;
X
X if(targnr == 0)
X return;
X
X if(!strcmp(targfield[1],".BPOOL"))
X bpoolflg = TRUE;
X
X if(!strcmp(targfield[1],".NOBPOOL"))
X nobpoolflg = TRUE;
X
X if(!strcmp(targfield[1],".IGNORE"))
X ignoreflg = TRUE;
X
X if ((is_old_rule(targfield[1])) && (strcmp(targfield[1],".SUFFIXES") != 0))
X {
X oldrule = TRUE;
X targs = targnr;
X for(i = 1; i <= targs; i++)
X {
X if (is_old_rule(targfield[i]))
X {
X if (targfield[i] != NIL)
X convertrule(i);
X }
X ruleend();
X }
X oldrule = FALSE;
X return;
X }
X
X for(i = 1; i <= targnr; i++)
X {
X p = index(targfield[i],'%');
X if ((p != NIL) && ((*(p+1) == '\0') || (*(p+1) == '.')))
X {
X std_rule = TRUE;
X break;
X }
X }
X
X for(i = 1; i <= targnr; i++)
X {
X found = FALSE;
X if(!std_rule)
X {
X hasht = hashval(targfield[i]);
X#ifdef DEBUG_RULE
Xprintf("targfield[i] = %s; i = %d\n", targfield[i], i);
X#endif DEBUG_RULE
X if ( ruletab[hasht] == (struct rules *) NIL)
X {
X if((current = ruletab[hasht] = (struct rules *) malloc( sizeof(struct rules))) == (struct rules *)NIL)
X errexit(10,"malloc");
X }
X else
X {
X current = ruletab[hasht];
X if ((!strcmp(ruletab[hasht]->name, targfield[i])) &&
X (strcmp(ruletab[hasht]->name, ".SUFFIXES")) &&
X (current->doublecolon == FALSE) &&
X (doublecolon == FALSE) &&
X (ruletab[hasht]->cmdlist != (struct cmds *) NIL) &&
X (cmdfield[0] != NIL))
X errexit(1, targfield[i]);
X
X if((!strcmp(current->name,targfield[i])) &&
X ((cmdfield[0] == NIL) ||
X (current->cmdlist == (struct cmds *) NIL)))
X {
X found = TRUE;
X }
X
X while((current->nextrule != (struct rules *) NIL) && (!found))
X {
X if((strcmp(current->name,targfield[i]) == 0) &&
X ((cmdfield[0] == NIL) ||
X (current->cmdlist == (struct cmds *) NIL)))
X {
X found = TRUE;
X break;
X }
X else
X current = current->nextrule;
X if ((strcmp(current->name, targfield[i]) == 0) &&
X (strcmp(ruletab[hasht]->name, ".SUFFIXES") != 0) &&
X (ruletab[hasht]->cmdlist != (struct cmds *) NIL) &&
X (current->doublecolon == FALSE) &&
X (doublecolon == FALSE) &&
X (cmdfield[0] != NIL))
X errexit(1, targfield[i]);
X if ((strcmp(current->name, ".SUFFIXES")) == 0)
X {
X if (depnr == 0) /* delete suffix list */
X {
X current->deplist[0] = NIL;
X }
X else
X {
X while (current->deplist[jjj] != NIL)
X jjj++;
X for (kkk = 1; kkk <= depnr; kkk++)
X {
X if ((current->deplist[jjj + kkk - 1] =
X malloc((unsigned) (strlen(depfield[kkk]) + 1))) == NIL)
X errexit(10,"malloc");
X (void) strcpy(current->deplist[jjj + kkk - 1], depfield[kkk]);
X }
X }
X }
X }
X if (!found)
X {
X if((current = current->nextrule = (struct rules *) malloc( sizeof(struct rules))) == (struct rules *)NIL)
X errexit(10,"malloc");
X }
X }
X }
X else
X {
X if((current = stdruletab[lastrule] = (struct rules *) malloc( sizeof(struct rules))) == (struct rules *) NIL)
X errexit(10,"malloc");
X overload_stdrule();
X implicit_suffs[lastrule] = lastrule;
X lastrule++;
X implicit_suffs[lastrule] = -1;
X stdruletab[lastrule] = (struct rules *) NIL;
X }
X if (!found)
X {
X if((current->name = malloc( (unsigned) strlen( targfield[i] ) + 1)) == NIL)
X errexit(10,"malloc");
X (void) strcpy(current->name, targfield[i]);
X }
X current->done = FALSE;
X if (doublecolon)
X current->doublecolon = TRUE;
X else
X current->doublecolon = FALSE;
X if((i == 1) && (firsttarget == NIL) && (current->name[0] != '%') &&
X (current->name[0] != '.'))
X firsttarget = current->name;
X if(!found)
X {
X current->deplist[0] = NIL;
X current->cmdlist = (struct cmds *) NIL;
X current->nextrule = (struct rules *) NIL;
X }
X if ((depnr > 0) && (!found))
X {
X if ((current->firstdep = malloc((unsigned) (strlen(depfield[1]) + sizeof(char)))) == NIL)
X errexit(10,"malloc");
X (void) strcpy(current->firstdep, depfield[1]);
X }
X
X if (found)
X {
X for(xx = 0; current->deplist[xx] != NIL; xx++)
X ;
X }
X minus = 0;
X for(j = xx+1; j <= xx+depnr; j++)
X {
X for(ss = 0; current->deplist[ss] != NIL; ss++)
X {
X if (!strcmp(current->deplist[ss],depfield[j-xx]))
X {
X src_found = TRUE;
X minus = 1;
X break;
X }
X }
X if(!src_found)
X {
X if ((current->deplist[j-1-minus] =
X malloc((unsigned) (strlen(depfield[j-xx]) + sizeof(char)))) == NIL)
X errexit(10,"malloc");
X (void) strcpy(current->deplist[j-1-minus], depfield[j-xx]);
X }
X }
X current->deplist[j-1] = NIL;
X src_found = FALSE;
X
X /* get standard dependent */
X
X if(current->name[0] != '%')
X {
X if((srcname = get_src_name(current->name)) != NIL)
X {
X for(ss = 0; ss <= j-2; ss++)
X {
X if(!strcmp(srcname,current->deplist[ss]))
X {
X src_found = TRUE;
X break;
X }
X }
X if (!src_found)
X {
X if((current->deplist[j-1] =
X malloc((unsigned) (strlen(srcname) + 1))) == NIL)
X errexit(10,"malloc");
X (void) strcpy(current->deplist[j-1],srcname);
X current->deplist[j] = NIL;
X }
X src_found = FALSE;
X }
X }
X
X if (heritnr > 0)
X {
X for (j = 1; j <= heritnr; j++)
X {
X if((current->heritage[j-1] =
X malloc((unsigned) (strlen(heritfield[j]) + sizeof(char)))) == NIL)
X errexit(10,"malloc");
X (void) strcpy(current->heritage[j-1], heritfield[j]);
X }
X current->heritage[j-1] = NIL;
X }
X else
X current->heritage[0] = NIL;
X
X if(std_rule)
X {
X for (j = 1; j <= targnr; j++)
X {
X if((current->targetlist[j-1] =
X malloc((unsigned) (strlen(targfield[j]) + 1))) == NIL)
X errexit(10,"malloc");
X (void) strcpy(current->targetlist[j-1],targfield[j]);
X }
X current->targetlist[j-1] = NIL;
X }
X if (cmdnr > 0)
X {
X if ((curcmd = current->cmdlist = (struct cmds *) malloc( sizeof( struct cmds))) == (struct cmds *) NIL)
X errexit(10,"malloc");
X for (j = 1; j <= cmdnr; j++)
X {
X if((curcmd->command = malloc( (unsigned) strlen (cmdfield[j]) + 1)) == NIL)
X errexit(10,"malloc");
X (void) strcpy(curcmd->command, cmdfield[j]);
X if (j != cmdnr)
X {
X if((curcmd = curcmd->nextcmd = (struct cmds *) malloc( sizeof( struct cmds))) == (struct cmds *) NIL)
X errexit(10,"malloc");
X }
X else
X curcmd->nextcmd = (struct cmds *) NIL;
X }
X }
X }
X
Xdoublecolon = FALSE;
X
Xif (!oldrule)
X {
X targnr = 0;
X targfield[1] = NIL;
X depnr = 0;
X depfield[1] = NIL;
X cmdnr = 0;
X cmdfield[1] = NIL;
X heritnr = 0;
X heritfield[1] = NIL;
X }
X} /* end ruleend */
X
Xconvertrule(i)
X int i;
X{
X char *p;
X p = rindex(targfield[i],'.');
X *p = '\0';
X p++;
X if ((depfield[1] = malloc((unsigned) (strlen(targfield[i]) + 3))) == NIL)
X errexit(10,"malloc");
X (void) strcpy(depfield[1],"%");
X (void) strcat(depfield[1],targfield[i]);
X if((targfield[1] = malloc((unsigned) (strlen(p) + 3))) == NIL)
X errexit(10,"malloc");
X (void) strcpy(targfield[1],"%.");
X (void) strcat(targfield[1],p);
X targnr = 1;
X depnr = 1;
X}
X
Xruledump(fd)
X FILE *fd;
X{
Xstruct rules *cur;
Xstruct cmds *ccmd;
Xint i;
Xint k = 0;
Xfor(i = 0; i< RULETABSIZE; i++)
X {
X if (ruletab[i] != (struct rules *) NIL)
X {
X k = 0;
X cur = ruletab[i];
X while( cur != (struct rules *) NIL)
X {
X if(fd == stdout)
X fprintf(fd,"%s\n", cur->name);
X else
X fprintf(fd,"%s", cur->name);
X
X if (fd == stdout)
X fprintf(fd," depends on:");
X else
X fprintf(fd,":");
X
X while (cur->deplist[k] != NIL)
X {
X if (fd != stdout)
X {
X if(!is_selrule_name(cur->deplist[k]))
X fprintf(fd," %s",cur->deplist[k]);
X k++;
X }
X else
X {
X fprintf(fd," %s",cur->deplist[k]);
X k++;
X }
X }
X fprintf(fd,"\n");
X
X ccmd = cur->cmdlist;
X
X if(fd == stdout)
X fprintf(fd," commands:\n");
X
X while (ccmd != (struct cmds *) NIL)
X {
X fprintf(fd,"%s\n", ccmd->command);
X ccmd = ccmd->nextcmd;
X }
X fprintf(fd,"\n");
X cur = cur->nextrule;
X }
X }
X }
X
X
Xfor(i = 0; i < lastrule; i++)
X {
X k = 0;
X cur = stdruletab[i];
X
X if(fd == stdout)
X fprintf(fd,"%s\n", cur->name);
X else
X fprintf(fd,"%s", cur->name);
X
X if (fd == stdout)
X fprintf(fd," depends on:");
X else
X fprintf(fd," :");
X
X while (cur->deplist[k] != NIL)
X {
X fprintf(fd," %s",cur->deplist[k]);
X k++;
X }
X
X if (fd == stdout)
X fprintf(fd,"\n");
X
X k = 0;
X
X if (fd == stdout)
X fprintf(fd," inherits:");
X else
X fprintf(fd," :");
X
X while (cur->heritage[k] != NIL)
X {
X fprintf(fd," %s", cur->heritage[k]);
X k++;
X }
X fprintf(fd,"\n");
X
X ccmd = cur->cmdlist;
X
X if (fd == stdout)
X fprintf(fd," commands:\n");
X
X while (ccmd != (struct cmds *) NIL)
X {
X fprintf(fd,"%s\n", ccmd->command);
X ccmd = ccmd->nextcmd;
X if (ccmd->command == NIL)
X break;
X }
X fprintf(fd,"\n");
X }
X
X(void) fflush(fd);
X
X} /* end ruledump */
X
X
Xadjust_stdrules(suffs)
X /*ARGSUSED*/
X char *suffs;
X{
X
X;
X}
X
XBool is_old_rule(string)
X char *string;
X{
X char *p1,*p2;
X if (index(string,'/') != NIL)
X return(FALSE);
X if (((p1 = index(string,'.')) != NIL) &&
X ((p2 = index(string+2,'.')) != NIL) &&
X (p1 < p2))
X return(TRUE);
X else
X return(FALSE);
X}
X
X
Xoverload_stdrule()
X{
X int i;
X
X for(i = 0; i < lastrule; i++)
X {
X if((strcmp(stdruletab[implicit_suffs[i]]->name,targfield[1]) == 0) &&
X (strcmp(stdruletab[implicit_suffs[i]]->deplist[0], depfield[1]) == 0))
X {
X implicit_suffs[i] = lastrule;
X return;
X }
X }
X}
X
X
X
Xinit_ruletab()
X{
X bzero((char *) ruletab, 257 * sizeof(struct rules *));
X}
X
END_OF_FILE
if test 17098 -ne `wc -c <'src/shape/rule.c'`; then
echo shar: \"'src/shape/rule.c'\" unpacked with wrong size!
fi
# end of 'src/shape/rule.c'
fi
if test -f 'src/vc/doretrv.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/vc/doretrv.c'\"
else
echo shar: Extracting \"'src/vc/doretrv.c'\" \(17013 characters\)
sed "s/^X//" >'src/vc/doretrv.c' <<'END_OF_FILE'
X/*
X * Copyright (C) 1989, 1990 W. Koch, A. Lampen, A. Mahler, W. Obst,
X * and U. Pralle
X *
X * This software is published on an as-is basis. There is ABSOLUTELY NO
X * WARRANTY for any part of this software to work correctly or as described
X * in the manuals. We do not accept any liability for any kind of damage
X * caused by use of this software, such as loss of data, time, money, or
X * effort.
X *
X * Permission is granted to use, copy, modify, or distribute any part of
X * this software as long as this is done without asking for charge, and
X * provided that this copyright notice is retained as part of the source
X * files. You may charge a distribution fee for the physical act of
X * transferring a copy, and you may at your option offer warranty
X * protection in exchange for a fee.
X *
X * Direct questions to: Tech. Univ. Berlin
X * Wilfried Koch
X * Sekr. FR 5-6
X * Franklinstr. 28/29
X * D-1000 Berlin 10, West Germany
X *
X * Tel: +49-30-314-22972
X * E-mail: shape@coma.uucp or shape@db0tui62.bitnet
X */
X#ifndef lint
Xstatic char *AFSid = "$Header: doretrv.c[3.12] Thu Feb 23 18:13:27 1989 axel@coma published $";
X#ifdef CFFLGS
Xstatic char *ConfFlg = CFFLGS;
X /* should be defined from within Makefile */
X#endif
X#endif
X/*
X * Log for /u/shape/dist-tape/src/vc/doretrv.c[3.6]
X * Thu Feb 23 18:13:27 1989 axel@coma published $
X * --- empty log message ---
X * doretrv.c[3.8] Thu Feb 23 18:13:27 1989 axel@coma published $
X * --- empty log message ---
X * doretrv.c[3.9] Thu Feb 23 18:13:27 1989 axel@coma save $
X * --- empty log message ---
X * doretrv.c[3.10] Thu Feb 23 18:13:27 1989 axel@coma save $
X * --- empty log message ---
X * doretrv.c[3.11] Thu Feb 23 18:13:27 1989 axel@coma published $
X * --- empty log message ---
X * doretrv.c[3.12] Thu Feb 23 18:13:27 1989 axel@coma published $
X * --- empty log message ---
X */
X
X#include <sys/file.h>
X#include <pwd.h>
X#include <stdio.h>
X#include <strings.h>
X#include "afs.h"
X#include "retrv.h"
X#include "project.h"
X#include "locks.h"
X
Xextern struct Transaction ThisTransaction;
Xextern unsigned int options;
X
X#ifndef ERROR
X#define ERROR -1
X#endif
X
XRetrieveAFile (fname, vdesc, proj, destpath)
X char *fname, *destpath;
X struct Vdesc *vdesc;
X Project *proj; {
X /*
X * NOTE: use of variant attribute in af_getkey is not yet functional.
X * The parameter, however, is necessary to occupy the slot.
X * Implementation of variant selection may make it necessary
X * to add another parameter to this procedure.
X */
X char spath[MAXNAMLEN], origpath[MAXNAMLEN], name[MAXNAMLEN], *afname,
X *aftype, *afvariant = NULL, messg[80], vsymname[80], *lbuf, *busyloc,
X tname[MAXNAMLEN], *getattr(), *vnum(), *mktemp(), *malloc(),
X destname[256], lockdir[256], lockfn[256], *intent, *getintent(),
X *lockerid();
X FILE *vfil, *bfile, *tfil;
X Af_attrs reqattrs, fattrs;
X Af_set hits;
X Af_key busy, tkey, tmpkey, *busykey, *thiskey = &tkey;
X Af_user *locker;
X int nudattr = 0, nhits, nbytes;
X unsigned int pstat = 0;
X register int i;
X
X if (!fname) return;
X af_initattrs (&reqattrs);
X busykey = &busy;
X getsyspath (fname, proj, spath, origpath, name);
X afname = af_afname (name);
X aftype = af_aftype (name);
X /* start fill out the warrant -- first 3 items may differ */
X (void)strcpy (reqattrs.af_name, afname);
X (void)strcpy (reqattrs.af_type, aftype);
X (void)strcpy (reqattrs.af_syspath, spath);
X
X /* ... the following settings will remain constant */
X if (options & VSPECSET) {
X if (vdesc->v_vno) {
X reqattrs.af_gen = gen(vdesc->v_vno);
X reqattrs.af_rev = rev(vdesc->v_vno);
X }
X else {
X (void)sprintf (vsymname, "%s=%s", SYMNAME, vdesc->v_spec);
X reqattrs.af_udattrs[nudattr] = vsymname;
X nudattr++;
X }
X }
X if (options & ATTRDEF) {
X reqattrs.af_udattrs[nudattr] =
X getattr (vdesc->v_attrf, proj, aftype, REWIND);
X if (reqattrs.af_udattrs[nudattr]) nudattr++;
X while (reqattrs.af_udattrs[nudattr] = getattr (vdesc->v_attrf,
X proj, aftype, NEXT))
X nudattr++;
X }
X if ((options & GENSET) && (!(options & VSPECSET))) {
X reqattrs.af_gen = vdesc->v_genno;
X }
X if (options & AUNSET) {
X (void)strcpy (reqattrs.af_author.af_username, vdesc->v_aunam);
X (void)strcpy (reqattrs.af_author.af_userhost, vdesc->v_auhost);
X }
X if (options & STATSET) {
X reqattrs.af_state = vdesc->v_state;
X }
X /* descriptive attributes are filled in now.
X * lets try to find something
X */
X if (fail(af_find(&reqattrs, &hits))) {
X af_perror (fname);
X abort_this(TRUE);
X }
X Register ((char *)&hits, AFSET);
X
X /* Now lets see what kind of deed needs to be done */
X nhits = af_nrofkeys (&hits);
X if (nhits == 0) {
X (void)sprintf (messg, "No appropriate version of %s.", fname);
X logmsg (messg);
X (void)sprintf (messg, NORESTORE, fname);
X logmsg (messg);
X abort_this(FALSE);
X }
X if (nhits == 1) {
X if (af_setgkey (&hits, 0, &tkey) == ERROR) {
X af_perror ("af_setgkey");
X abort_this (TRUE);
X }
X }
X else if (nhits > 1) {
X if (fail(af_sortset(&hits, AF_ATTSTIME))) {
X af_perror ("af_sortset");
X abort_this (TRUE);
X }
X if (!(options & DATESET)) {
X if (af_setgkey (&hits, nhits-1, &tkey) == ERROR) {
X af_perror ("af_setgkey");
X abort_this (TRUE);
X }
X }
X else { /* some cutoff-date was specified */
X /* Don't consider busy version here */
X af_setgkey (&hits, 0, &tmpkey);
X if (af_rstate (&tmpkey) == AF_BUSY) {
X af_setrmkey (&hits, &tmpkey);
X nhits--;
X }
X for (i = nhits; i > 0; i--) {
X if (af_setgkey (&hits, i-1, &tkey) == ERROR) {
X af_perror ("af_setgkey");
X abort_this (TRUE);
X }
X if (fail(af_gattrs(thiskey, &fattrs))) {
X af_perror ("af_gattrs");
X abort_this (FALSE);
X }
X if (fattrs.af_stime >= vdesc->v_time) {
X af_setrmkey (&hits, thiskey);
X udafree (&fattrs);
X }
X else {
X udafree (&fattrs);
X break;
X }
X } /* end loop */
X if ((nhits = af_nrofkeys (&hits)) == 0) {
X (void)sprintf (messg, "No appropriate version of %s.", fname);
X logmsg (messg);
X abort_this (FALSE);
X }
X } /* end of else (some cut-off date) */
X if ((options & XACT) && (nhits > 1)) {
X (void)sprintf (messg, "No exact hit for %s. (got %d)", fname, nhits);
X logmsg (messg);
X (void)sprintf (messg, NORESTORE, fname);
X logmsg (messg);
X abort_this (FALSE);
X }
X }
X else {
X (void)sprintf (messg, "%d is an unreasonble number of hits.", nhits);
X logerr (messg);
X abort_this (TRUE);
X }
X
X if (fail(af_gattrs(thiskey, &fattrs))) {
X af_perror ("af_gattrs");
X abort_this (FALSE);
X }
X Register ((char *)&fattrs, AFATTRS);
X /* at this point we do have a single af_key and 'thiskey' points
X * at it. now decide what
X * to do with it. fattrs contains its attributes.
X */
X switch (options & (TYPEOUT | COPY | LOCKIT)) {
X case TYPEOUT:
X if (!(vfil = af_open (thiskey, "r"))) {
X af_perror ("af_open");
X abort_this (TRUE);
X }
X mkvstring (messg, thiskey);
X logdiag (messg);
X lbuf = malloc ((unsigned)fattrs.af_size);
X nbytes=fread (lbuf, sizeof (*lbuf), (Size_t)fattrs.af_size, vfil);
X WriteXPand (lbuf, nbytes, stdout, thiskey);
X free (lbuf);
X af_close (vfil);
X UnRegister ((char *)&hits, AFSET);
X af_dropset (&hits);
X UnRegister ((char *)&fattrs, AFATTRS);
X udafree (&fattrs);
X return;
X break;
X case COPY:
X /* This option creates a plain UNIX file from the specified
X * AFS file. The created copy is - in general - an object without
X * history. If, however, the copy happens to go into the
X * history-directory (the one containing the archive) it will
X * 'automatically' be considered the busy-version.
X * If - in this case - a copy replaces a formerly locked busy-version,
X * the lock will be released.
X */
X busyloc = destpath ? destpath : ".";
X (void)sprintf (destname, "%s%s%s", destpath ? busyloc : "",
X destpath ? "/" : "", name);
X if ((tfil = fopen (destname, "r")) == NULL) {
X /* take this as test for presence */
X if (access (busyloc, W_OK) == 0) { /* may we create ? */
X pstat |= DOIT; /* No scruples if no busyvers current */
X }
X else {
X (void)sprintf (messg, "write permission for directory %s denied.",
X busyloc);
X logerr (messg);
X pstat |= DENIED;
X }
X }
X else { /* file exists */
X (void)fclose (tfil);
X if (access (destname, W_OK) < 0) {
X if (access (busyloc, W_OK) == 0) {
X (void)sprintf (messg, "%s write-protected, re-create it ?",
X destname);
X if (options & QUIETPLEASE) {
X pstat |= (options & FORCE) ? (RECREATE | DOIT) : DENIED;
X }
X else {
X if (ask_confirm (messg, "no")) {
X pstat |= DENIED;
X }
X else {
X pstat |= (RECREATE | DOIT);
X }
X }
X }
X else {
X (void)sprintf (messg, "no write permission for %s", destname);
X logmsg (messg);
X pstat |= DENIED;
X }
X }
X else { /* write access on destfile */
X if (strcmp (busyloc, ".")) {
X (void)sprintf (messg, "%s exists and is writable. Overwrite it ?",
X destname);
X if (options & QUIETPLEASE) {
X pstat |= (options & FORCE) ? DOIT : 0;
X }
X else {
X if (!ask_confirm (messg, "no")) {
X pstat |= DOIT;
X }
X }
X }
X else { /* current dir! - test for lock */
X if (fail (af_getkey (spath, afname, aftype, AF_BUSYVERS,
X AF_BUSYVERS, afvariant, &busy)))
X { /* No busy-key -- no lock, this is impossible here */
X pstat |= DOIT;
X }
X else {
X if (lockeruid (vc_testlock_g(&busy)) == getuid ()) {
X (void)sprintf (messg, "Give up lock on %s and overwrite it ?",
X destname);
X if (options & QUIETPLEASE) {
X pstat |= (options & FORCE) ? DOIT : 0;
X }
X else {
X if (!ask_confirm (messg, "no")) {
X pstat |= DOIT;
X (void)vc_unlock_g(&busy);
X }
X else {
X pstat |= DENIED;
X }
X }
X }
X else {
X pstat |= DOIT;
X }
X }
X }
X }
X }
X if (pstat & DOIT) {
X if ((vfil=af_open(thiskey, "r")) == NULL) {
X af_perror ("af_open");
X abort_this (TRUE);
X }
X (void)sprintf (tname, "%s%s%s", destpath ? destpath : "",
X destpath ? "/" : "", mktemp("retrvXXXXXX"));
X if ((bfile = fopen (tname, "w")) == NULL) {
X (void)sprintf (messg, "cannot create tmp-file (%s) for writing.",
X tname);
X logerr (messg);
X abort_this (TRUE);
X }
X Register (tname, TYPEF);
X (void)sprintf (messg, "%s%s%s[%s] -> %s", spath[0] ? spath : "",
X spath[0] ? "/" : "", name, vnum (thiskey), destname);
X logdiag (messg);
X lbuf = malloc ((unsigned)fattrs.af_size);
X nbytes=fread (lbuf, sizeof (*lbuf), (Size_t)fattrs.af_size, vfil);
X WriteXPand (lbuf, nbytes, bfile, thiskey);
X free (lbuf);
X (void)fclose (bfile); (void)fclose (vfil);
X (void)unlink (destname);
X if (link (tname, destname) < 0) {
X perror (destname);
X abort_this (TRUE);
X }
X (void)chmod (destname, 0444);
X UnRegister (tname, TYPEF);
X (void)unlink (tname);
X }
X else {
X (void)sprintf (messg, "%s not retrieved", fname);
X logmsg (messg);
X }
X UnRegister ((char *)&hits, AFSET);
X af_dropset (&hits);
X UnRegister ((char *)&fattrs, AFATTRS);
X udafree (&fattrs);
X return;
X break;
X case LOCKIT:
X /*
X * Before a version is retrieved, set-busy, and locked, the
X * following preconditions must be fulfilled:
X * - the retrieve must go to the directory containing the
X * archive directory. -> current directory
X * - the retrieved version must not be locked by anybody but
X * the calling user.
X * - the current directory must grant write access to the
X * calling user.
X * - if some busy-version would be overwritten by the retrieve,
X * the user is asked if she wants that
X */
X if ((destpath) && (destpath[0])) {
X (void)sprintf (messg, "can't checkout (with lock) to %s.", destpath);
X logmsg (messg);
X abort_this (FALSE);
X }
X (void)sprintf (lockfn, "%s%s%s", spath[0] ? spath : "",
X spath[0] ? "/" : "", name);
X (void)sprintf (lockdir, "%s", spath[0] ? spath : ".");
X /*
X * The following checks are based on the permission information
X * stored in the archive files. It is unclear how
X * to properly handle vanilla filesystem related inquiries.
X */
X if (fail (af_getkey (spath, afname, aftype, AF_LASTVERS,
X AF_LASTVERS, afvariant, &busy))) {
X /* well, this case seems to be impossible. If we get here, */
X /* at least _*some*_ version should be present */
X
X af_perror ("RetrieveAFile -- no version in sight.");
X abort_this (TRUE);
X }
X else { /* there is a version */
X if (((lockeruid (locker = af_testlock (&busy, AF_GLOBALLOCK)))
X == getuid ()) || !(locked (locker))) {
X#ifdef AFACCOK
X if (af_access (spath[0] ? spath : ".", afname,
X aftype, W_OK) == 0) {
X#else
X if (access (fname, W_OK) == 0) {
X#endif
X (void)sprintf (messg, "Writable %s exists, overwrite it ?", lockfn);
X if (options & QUIETPLEASE) {
X pstat |= (options & FORCE) ? DOIT : DENIED;
X }
X else {
X pstat |= (ask_confirm (messg, "no")) ? DENIED : DOIT;
X }
X }
X else if (access (lockdir, W_OK) == 0) {
X if (access (lockfn, F_OK) == 0) {
X (void)sprintf (messg,
X "Write access on %s denied. Overwrite it anyway ?",
X lockfn);
X if (options & QUIETPLEASE) {
X pstat |= (options & FORCE) ? DOIT : DENIED;
X }
X else {
X pstat |= (ask_confirm (messg, "no")) ? DENIED : DOIT;
X }
X }
X else pstat |= DOIT;
X }
X else { /* no write access on current dir */
X (void)sprintf (messg, "Can't create in %s.", lockdir);
X abort_this (TRUE);
X }
X if (!locked(locker)) {
X if (!vc_lock_g(&busy, getuid())) {
X af_perror ("af_lock");
X abort_this (TRUE);
X }
X }
X }
X else { /* busy version locked by someone else */
X pstat |= DENIED;
X (void)sprintf (messg, "%s already locked by %s.", lockfn,
X lockerid(locker));
X logmsg (messg);
X }
X }
X /* now all the checks are done. set retrieved version busy and
X * create it in lockdir.
X */
X if ((pstat & DOIT) && (!(pstat & DENIED))) {
X if (! ((options & QUIETPLEASE) || (options & FORCE)))
X intent = getintent ("Describe intended changes ?", (char *)NULL);
X else intent = (char *)NULL;
X /* setbusy sets just the attributes. data must be moved manually */
X if ((vfil=af_open(thiskey, "r")) == NULL) {
X af_perror ("af_open");
X abort_this (TRUE);
X }
X (void)sprintf (tname, "%s/%s", lockdir, mktemp("retrvXXXXXX"));
X if ((bfile = fopen (tname, "w")) == NULL) {
X (void)sprintf (messg, "cannot create tmp-file (%s) for writing.",
X tname);
X logerr (messg);
X af_close (vfil);
X abort_this (TRUE);
X }
X Register (tname, TYPEF);
X (void)sprintf (messg, "%s%s%s[%s] -> %s%s%s", spath[0] ? spath : "",
X spath[0] ? "/" : "", name,
X vnum (thiskey), spath[0] ? spath : "",
X spath[0] ? "/" : "",
X name);
X logdiag (messg);
X
X /* there's no attribute citation for locked busy versions .... */
X lbuf = malloc ((unsigned)fattrs.af_size);
X nbytes=fread (lbuf, sizeof (*lbuf), (Size_t)fattrs.af_size, vfil);
X if (fwrite (lbuf, sizeof (*lbuf), nbytes, bfile) != nbytes) {
X logerr ("fatal: couldn't write busy file.");
X abort_this (TRUE);
X }
X free (lbuf);
X (void)fclose (bfile);
X (void)chmod (tname, 0644);
X af_close (vfil);
X /* if no busyversion was present, busykey contains garbage */
X /* this might be responsible for trouble here */
X (void)unlink (fname);
X (void)link (tname, fname);
X ThisTransaction.tr_done = TRUE;
X UnRegister (tname, TYPEF);
X (void)unlink (tname);
X if (af_crkey (spath, afname, aftype, busykey) < 0) {
X af_perror ("af_crkey");
X abort_this (TRUE);
X }
X if (fail(af_setbusy(busykey, thiskey))) {
X af_perror ("af_setbusy");
X abort_this (TRUE); /* check out what happens in abort_this */
X }
X (void)vc_lock_g(busykey, getuid());
X if (intent) {
X char *intattr;
X intattr = malloc ((unsigned)(strlen (intent)+strlen (INTENT)+ 1));
X (void)sprintf (intattr, "%s%s", INTENT, intent);
X if (fail(af_sudattr (busykey, AF_REPLACE, intattr)))
X af_sudattr (busykey, AF_ADD, intattr);
X free (intattr);
X }
X }
X else { /* denied or not doit */
X (void)sprintf (messg, NORESTORE, ThisTransaction.tr_fname);
X logmsg (messg);
X }
X UnRegister ((char *)&fattrs, AFATTRS);
X udafree (&fattrs);
X UnRegister ((char *)&hits, AFSET);
X af_dropset (&hits);
X break;
X default:
X logerr ("fatal: illegal action switch in doretrv.c");
X break;
X }
X }
END_OF_FILE
if test 17013 -ne `wc -c <'src/vc/doretrv.c'`; then
echo shar: \"'src/vc/doretrv.c'\" unpacked with wrong size!
fi
# end of 'src/vc/doretrv.c'
fi
echo shar: End of archive 19 \(of 33\).
cp /dev/null ark19isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 33 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0