home *** CD-ROM | disk | FTP | other *** search
- 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
-