rsalz@uunet.uu.net (Rich Salz) (06/05/89)
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 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.