rsalz@uunet.uu.net (Rich Salz) (06/05/89)
Submitted-by: Axel Mahler <unido!coma!axel> Posting-number: Volume 19, Issue 34 Archive-name: shape/part21 #! /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 21 (of 33)." # Contents: src/afs/afsets.c src/vc/vldovl.c # Wrapped by rsalz@papaya.bbn.com on Thu Jun 1 19:27:13 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'src/afs/afsets.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/afs/afsets.c'\" else echo shar: Extracting \"'src/afs/afsets.c'\" \(19377 characters\) sed "s/^X//" >'src/afs/afsets.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/*LINTLIBRARY*/ X/* X * Shape/AFS X * X * afsets.c -- Operations on keysets X * X * Author: Andreas Lampen, TU-Berlin (andy@coma.UUCP) X * (andy@db0tui62.BITNET) X * X * $Header: afsets.c[1.3] Wed Feb 22 16:27:56 1989 andy@coma published $ X * X * EXPORT: X * af_initset -- initialize set descriptor X * af_copyset -- copy sets X * af_nrofkeys -- return number of keys in set X * af_sortset -- sort set by attribute X * af_dropset -- drop set X * af_setgkey -- get key from set X * af_setaddkey -- add key to set X * af_setrmkey -- remove key from set X * af_setposrmkey -- remove key (identified by position) from set X * af_subset -- build subset X * af_intersect -- build intersection of two sets X * af_union -- build union of two sets X * af_diff -- build difference between two sets X */ X X#include <stdio.h> X#include <string.h> X#ifdef SUNOS_4_0 X#include <strings.h> X#endif X X#include "typeconv.h" X#include "afsys.h" X#include "afs.h" X Xchar *malloc(), *realloc(); X X/*================================================================ X * af_settest -- test plausibility of set descriptor X * returnes TRUE (ERROR) if set descr. is invalid, X * otherwise FALSE (AF_OK). X * X *================================================================*/ X XLOCAL af_settest (set) X Af_set *set; X{ X if ((set->af_nkeys < 0) || (set->af_setlen < 0)) X return (ERROR); X /* if set is not empty, test if first key is valid */ X if (set->af_nkeys >= 1) X if (af_keytest (&(set->af_klist[0]))) X return (ERROR); X X return (AF_OK); X} X X/*================================================================ X * af_initset -- initialize set descriptor X * X *================================================================*/ X XEXPORT af_initset (set) X Af_set *set; X{ X set->af_nkeys = 0; X set->af_setlen = 0; X set->af_klist = (Af_key *)0; X} X X/*================================================================ X * af_copyset -- copy sets X * X *================================================================*/ X XEXPORT af_copyset (set1, set2) X Af_set *set1, *set2; X{ X int i; X X if (af_settest (set1) || af_settest (set2)) X SFAIL ("copyset", "", AF_EINVSET, ERROR); X X /* allocate memory for new set (incl. space for additional element) */ X set2->af_setlen = set1->af_nkeys + 1; X if ((set2->af_klist = (Af_key *)malloc ((unsigned) (set2->af_setlen * sizeof(Af_key)))) == (Af_key *)0) X FAIL ("copyset", "malloc", AF_ESYSERR, ERROR); X X /* do copying */ X for (i=0; i<set1->af_nkeys; i++) X { X set2->af_klist[i] = set1->af_klist[i]; X /* increase refcount in list descriptor */ X VATTR((&(set2->af_klist[i]))).af_nlinks++; X (set2->af_klist[i].af_ldes)->af_refcount++; X } X set2->af_nkeys = set1->af_nkeys; X return (set2->af_nkeys); X} X X/*================================================================ X * af_nrofkeys -- return number of keys in set X * X *================================================================*/ X XEXPORT af_nrofkeys (set) X Af_set *set; X{ X if (af_settest (set)) X SFAIL ("nrofkeys", "", AF_EINVSET, ERROR); X return (set->af_nkeys); X} X X/*================================================================ X * af_sortset -- sort set by attribute X * X *================================================================*/ X Xextern struct cmpfun { int (*func) (); }; X Xextern struct cmpfun af_cmpfuncts[]; X Xextern char *af_attrlist[], af_udaname[]; X XEXPORT af_sortset (set, attr) X Af_set *set; X char *attr; X{ X int hi = AF_ATTNUM-1, lo=0, anum, res, af_cmpuda(); X X if (af_settest (set)) X SFAIL ("sortset", "", AF_EINVSET, ERROR); X if (!attr) X SFAIL ("sortset", "invalid attribute name", AF_EMISC, ERROR); X X /* get attribute number (binary search) */ X anum = (hi+lo)/2; X while (hi >= lo) X { X res = strcmp (attr, af_attrlist[anum]); X if (res == 0) X break; X if (res < 0) X hi = anum - 1; X else lo = anum + 1; X anum = (hi+lo)/2; X } X /* attribute names, that are not in the list of standard attributes */ X /* are assumed to be "user defined attributes" */ X if (res != 0) X { X (void) strcpy (af_udaname, attr); X qsort ((char *)set->af_klist, set->af_nkeys, sizeof(Af_key), af_cmpuda); X } X else X { X (void) strcpy (af_udaname, attr); X qsort ((char *)set->af_klist, set->af_nkeys, sizeof(Af_key), af_cmpfuncts[anum].func); X } X return (AF_OK); X} X X/*================================================================ X * af_dropset -- drop set X * X *================================================================*/ X XEXPORT af_dropset (set) X Af_set *set; X{ X register i; X X if (af_settest (set)) X SFAIL ("dropset", "", AF_EINVSET, ERROR); X X for (i=0; i<set->af_nkeys; i++) X { X /* decrease reference count in corresponding archive */ X VATTR((&(set->af_klist[i]))).af_nlinks--; X if (--(set->af_klist[i].af_ldes)->af_refcount <= 0) X (void) af_detlist (set->af_klist[i].af_ldes); X } X if (set->af_setlen > 0) X free ((char *)set->af_klist); X return (AF_OK); X} X X/*================================================================ X * af_setgkey -- return key from set X * X *================================================================*/ X XEXPORT af_setgkey (set, pos, key) X Af_set *set; X int pos; X Af_key *key; /* out */ X{ X if (af_settest (set)) X SFAIL ("setgkey", "", AF_EINVSET, ERROR); X X if ((pos >= set->af_nkeys) || (pos < 0)) X SFAIL ("setgkey", "", AF_ENOPOS, ERROR); X X VATTR((&(set->af_klist[pos]))).af_nlinks++; X (set->af_klist[pos].af_ldes)->af_refcount++; X X key->af_ldes = set->af_klist[pos].af_ldes; X key->af_lpos = set->af_klist[pos].af_lpos; X return (AF_OK); X} X X/*================================================================ X * af_setaddkey -- add key to set X * X *================================================================*/ X XEXPORT af_setaddkey (set, pos, key) X Af_set *set; X int pos; X Af_key *key; X{ X register i; X X if (af_settest (set)) X SFAIL ("setaddkey", "", AF_EINVSET, ERROR); X if (af_keytest (key)) X SFAIL ("setaddkey", "", AF_EINVKEY, ERROR); X if (((pos > set->af_nkeys) || (pos < 0)) && (pos != AF_LASTPOS)) X SFAIL ("setaddkey", "", AF_ENOPOS, ERROR); X X if (pos == AF_LASTPOS) X pos = set->af_nkeys; X X /* if set is full, enlarge it */ X if (set->af_nkeys == set->af_setlen) X { X if (set->af_setlen == 0) X { X if ((set->af_klist = (Af_key *)malloc ((unsigned) (sizeof(Af_key) * AF_SEGLEN))) == (Af_key *)0) X FAIL ("setaddkey", "malloc", AF_ESYSERR, ERROR); X } X else X { X if ((set->af_klist = (Af_key *)realloc ((char *)set->af_klist, (unsigned) (sizeof(Af_key) * (set->af_setlen + AF_SEGLEN)))) == (Af_key *)0) X FAIL ("setaddkey", "realloc", AF_ESYSERR, ERROR); X } X set->af_setlen += AF_SEGLEN; X } X X for ( i=set->af_nkeys; i>pos; i--) X set->af_klist[i] = set->af_klist[i-1]; X set->af_klist[pos] = *key; X set->af_nkeys++; X X /* increase refcount */ X key->af_ldes->af_refcount++; X VATTR(key).af_nlinks++; X X return (AF_OK); X} X X/*================================================================ X * af_setrmkey -- remove key from set X * X *================================================================*/ X XEXPORT af_setrmkey (set, key) X Af_set *set; X Af_key *key; X{ X register i; X bool found = FALSE; X X if (af_settest (set)) X SFAIL ("setrmkey", "", AF_EINVSET, ERROR); X if (af_keytest (key)) X SFAIL ("setrmkey", "", AF_EINVKEY, ERROR); X X for (i=0; i<set->af_nkeys; i++) X { X if (!found) X { X if (!af_keycmp (&(set->af_klist[i]), key)) X found = TRUE; X } X else /* compress list */ X set->af_klist[i-1] = set->af_klist[i]; X } X if (!found) X SFAIL ("setrmkey", "", AF_ENOKEY, ERROR); X set->af_nkeys--; X VATTR(key).af_nlinks--; X if (--key->af_ldes->af_refcount <= 0) X (void) af_detlist (key->af_ldes); X X return (AF_OK); X} X X/*================================================================ X * af_setposrmkey -- remove key (identified by position) from set X * X *================================================================*/ X XEXPORT af_setposrmkey (set, pos) X Af_set *set; X int pos; X{ X register i; X X if (af_settest (set)) X SFAIL ("setposrmkey", "", AF_EINVSET, ERROR); X if ((pos >= set->af_nkeys) || (pos < 0)) X SFAIL ("setposrmkey", "", AF_ENOPOS, ERROR); X X VATTR((&(set->af_klist[pos]))).af_nlinks--; X if (--(set->af_klist[pos].af_ldes)->af_refcount <= 0) X (void) af_detlist (set->af_klist[pos].af_ldes); X X for (i=pos; i<set->af_nkeys-1; i++) X set->af_klist[i] = set->af_klist[i+1]; X X set->af_nkeys--; X X return (AF_OK); X} X X/*================================================================ X * af_subset -- build subset X * X *================================================================*/ X XEXPORT af_subset (set, attrbuf, newset) X Af_set *set, *newset; X Af_attrs *attrbuf; X{ X register i, j=0, k=0; X int match; X Af_set tmpset; X X if (af_settest (set)) X SFAIL ("subset", "", AF_EINVSET, ERROR); X X /* allocate memory for new set */ X tmpset.af_setlen = set->af_nkeys; X if ((tmpset.af_klist = (Af_key *)malloc ((unsigned) (tmpset.af_setlen * sizeof(Af_key)))) == (Af_key *)0) X FAIL ("subset", "malloc", AF_ESYSERR, ERROR); X X /* if there are no disqualifying attributes, add key to new set */ X for (i = 0; i < set->af_nkeys; i++) X { X /* if an attribute is set an does not match, continue with next key */ X /*** name ***/ X if ( (attrbuf->af_name[0] != '\0') && X (strcmp (attrbuf->af_name, VATTR((&(set->af_klist[i]))).af_name)) ) X continue; X X /*** type ***/ X if ( (attrbuf->af_type[0] != '\0') && X (strcmp (attrbuf->af_type, NOTNIL(VATTR((&(set->af_klist[i]))).af_type))) ) X continue; X X /*** syspath ***/ X if ( (attrbuf->af_syspath[0] != '\0') && X (strcmp (attrbuf->af_syspath, CATTR((&(set->af_klist[i]))).af_syspath)) ) X continue; X X /*** generation number ***/ X if ( (attrbuf->af_gen != AF_NOVNUM) && X (attrbuf->af_gen != VATTR((&(set->af_klist[i]))).af_gen) ) X continue; X X /*** revision number ***/ X if ( (attrbuf->af_rev != AF_NOVNUM) && X (attrbuf->af_rev != VATTR((&(set->af_klist[i]))).af_rev) ) X continue; X X /*** variant attribute ***/ X if ( (attrbuf->af_variant[0]) && X (strcmp (attrbuf->af_variant, NOTNIL(VATTR((&(set->af_klist[i]))).af_variant))) ) X continue; X X /*** state ***/ X if ( (attrbuf->af_state != AF_NOSTATE) && X (attrbuf->af_state != VATTR((&(set->af_klist[i]))).af_state) ) X continue; X X /*** owner ***/ X if ( (attrbuf->af_owner.af_username[0]) && X (strcmp (attrbuf->af_owner.af_username, CATTR((&(set->af_klist[i]))).af_ownname)) ) X continue; X if ( (attrbuf->af_owner.af_userhost[0]) && X (strcmp (attrbuf->af_owner.af_userhost, CATTR((&(set->af_klist[i]))).af_ownhost)) ) X continue; X X /*** author ***/ X if ( (attrbuf->af_author.af_username[0]) && X (strcmp (attrbuf->af_author.af_username, VATTR((&(set->af_klist[i]))).af_auname)) ) X continue; X if ( (attrbuf->af_author.af_userhost[0]) && X (strcmp (attrbuf->af_author.af_userhost, VATTR((&(set->af_klist[i]))).af_auhost)) ) X continue; X X /*** size ***/ X if ( (attrbuf->af_size != AF_NOSIZE) && X (attrbuf->af_size != VATTR((&(set->af_klist[i]))).af_fsize) ) X continue; X X /*** mode ***/ X if ( (attrbuf->af_mode != AF_NOMODE) && X (attrbuf->af_mode != VATTR((&(set->af_klist[i]))).af_mode) ) X continue; X X /*** locker ***/ X if ( (attrbuf->af_locker.af_username[0]) && X (strcmp (attrbuf->af_locker.af_username, NOTNIL(VATTR((&(set->af_klist[i]))).af_lckname))) ) X continue; X if ( (attrbuf->af_locker.af_userhost[0]) && X (strcmp (attrbuf->af_locker.af_userhost, NOTNIL(VATTR((&(set->af_klist[i]))).af_lckhost))) ) X continue; X X /*** date of last modification ***/ X if ( (attrbuf->af_mtime != AF_NOTIME) && X (attrbuf->af_mtime != VATTR((&(set->af_klist[i]))).af_mtime) ) X continue; X X /*** date of last access ***/ X if ( (attrbuf->af_atime != AF_NOTIME) && X (attrbuf->af_atime != VATTR((&(set->af_klist[i]))).af_atime) ) X continue; X X /*** date of last status change ***/ X if ( (attrbuf->af_ctime != AF_NOTIME) && X (attrbuf->af_ctime != VATTR((&(set->af_klist[i]))).af_ctime) ) X continue; X X /*** saving date ***/ X if ( (attrbuf->af_stime != AF_NOTIME) && X (attrbuf->af_stime != VATTR((&(set->af_klist[i]))).af_stime) ) X continue; X X /*** date of last lock change ***/ X if ( (attrbuf->af_ltime != AF_NOTIME) && X (attrbuf->af_ltime != VATTR((&(set->af_klist[i]))).af_ltime) ) X continue; X X /*** user defined attributes ***/ X if (attrbuf->af_udattrs[0] != (char *)0) X { X /* if list of user defined attributes is not empty or there are */ X /* attributes */ X match = TRUE; X if ((attrbuf->af_udattrs[0][0] != '\0') || X (VATTR((&(set->af_klist[i]))).af_udanum != 0)) X { X /* test all given entries */ X j=0; X while ((attrbuf->af_udattrs[j] != (char *)0) X && (match = !af_match (attrbuf->af_udattrs[j], X &(VATTR((&(set->af_klist[i]))).af_uhtab)))) X { X j++; X } X } /* if */ X if (match == FALSE) X continue; X } /* if */ X X X /* add key to new set */ X tmpset.af_klist[k] = set->af_klist[i]; X /* increase number of links in list descriptor */ X (tmpset.af_klist[k].af_ldes)->af_refcount++; X VATTR((&(tmpset.af_klist[k]))).af_nlinks++; X k++; X X } /* for */ X X tmpset.af_nkeys = k; X X /* if the resulting set shall be stored in the old set */ X if (set == newset) X { X (void) af_dropset (set); X *set = tmpset; X } X else X *newset = tmpset; X X return (k); X} X X X/*================================================================ X * af_intersect -- build intersection of two sets X * X *================================================================*/ X XEXPORT af_intersect (set1, set2, newset) X Af_set *set1, *set2; X Af_set *newset; X{ X register i, j, k; X Af_set tmpset; X X if (af_settest (set1) || af_settest (set2)) X SFAIL ("intersect", "", AF_EINVSET, ERROR); X X /* allocate enough memory */ X if (set1->af_nkeys >= set2->af_nkeys) X tmpset.af_setlen = set1->af_nkeys; X else X tmpset.af_setlen = set2->af_nkeys; X if ((tmpset.af_klist = (Af_key *)malloc ((unsigned) (tmpset.af_setlen * sizeof(Af_key)))) == (Af_key *)0) X FAIL ("intersect", "malloc", AF_ESYSERR, ERROR); X X /* build new set */ X k=0; X for (i=0; i<set1->af_nkeys; i++) X for (j=0; j<set2->af_nkeys; j++) X { X if (!af_keycmp (&(set1->af_klist[i]), &(set2->af_klist[j]))) X { X tmpset.af_klist[k] = set1->af_klist[i]; X /* increase number of links in list descriptor */ X (tmpset.af_klist[k].af_ldes)->af_refcount++; X VATTR((&(tmpset.af_klist[k]))).af_nlinks++; X k++; X } X } X tmpset.af_nkeys = k; X X /* if the new set shall be stored in one of the old ones */ X if (newset == set1) X { X (void) af_dropset (set1); X *set1 = tmpset; X } X else X { X if (newset == set2) X { X (void) af_dropset (set2); X *set2 = tmpset; X } X else X *newset = tmpset; X } X X return (k); X} X X/*================================================================ X * af_union -- build union of two sets X * X *================================================================*/ X XEXPORT af_union (set1, set2, newset) X Af_set *set1, *set2; X Af_set *newset; X{ X register i, j, k; X bool dbl=FALSE; X Af_set tmpset; X X if (af_settest (set1) || af_settest (set2)) X SFAIL ("union", "", AF_EINVSET, ERROR); X X /* allocate enough memory */ X tmpset.af_setlen = set1->af_nkeys+set2->af_nkeys; X if ((tmpset.af_klist = (Af_key *)malloc ((unsigned) (tmpset.af_setlen * sizeof(Af_key)))) == (Af_key *)0) X FAIL ("union", "malloc", AF_ESYSERR, ERROR); X X /* build new set */ X k=0; X for (i=0; i<set1->af_nkeys; i++) X { X tmpset.af_klist[k] = set1->af_klist[i]; X /* increase number of links in list descriptor */ X (tmpset.af_klist[k].af_ldes)->af_refcount++; X VATTR((&(tmpset.af_klist[k]))).af_nlinks++; X k++; X } X for (j=0; j<set2->af_nkeys; j++) X { X for (i=0; i<set1->af_nkeys; i++) X { X if (!af_keycmp (&(tmpset.af_klist[i]), &(set2->af_klist[j]))) X dbl = TRUE; X } X if (dbl) X dbl = FALSE; X else X { X tmpset.af_klist[k] = set2->af_klist[j]; X /* increase number of links in list descriptor */ X (tmpset.af_klist[k].af_ldes)->af_refcount++; X VATTR((&(tmpset.af_klist[k]))).af_nlinks++; X k++; X } X } X tmpset.af_nkeys = k; X X /* if the new set shall be stored in one of the old ones */ X if (newset == set1) X { X (void) af_dropset (set1); X *set1 = tmpset; X } X else X { X if (newset == set2) X { X (void) af_dropset (set2); X *set2 = tmpset; X } X else X *newset = tmpset; X } X X return (k); X} X X/*================================================================ X * af_diff -- build difference between two sets X * X *================================================================*/ X XEXPORT af_diff (set1, set2, newset) X Af_set *set1, *set2; X Af_set *newset; X{ X register i, j, k; X bool found = FALSE; X Af_set tmpset; X X if (af_settest (set1) || af_settest (set2)) X SFAIL ("diff", "", AF_EINVSET, ERROR); X X /* allocate enough memory */ X tmpset.af_setlen = set1->af_nkeys; X if ((tmpset.af_klist = (Af_key *)malloc ((unsigned) (tmpset.af_setlen * sizeof(Af_key)))) == (Af_key *)0) X FAIL ("diff", "malloc", AF_ESYSERR, ERROR); X X /* build new set */ X k=0; X for (i=0; i<set1->af_nkeys; i++) X { X for (j=0; j<set2->af_nkeys; j++) X { X if (!af_keycmp (&(set1->af_klist[i]), &(set2->af_klist[j]))) X found = TRUE; X } X if (found) X found = FALSE; X else X { X tmpset.af_klist[k] = set1->af_klist[i]; X /* increase number of links in list descriptor */ X (tmpset.af_klist[k].af_ldes)->af_refcount++; X VATTR((&(tmpset.af_klist[k]))).af_nlinks++; X k++; X } X } X tmpset.af_nkeys = k; X X /* if the new set shall be stored in one of the old ones */ X if (newset == set1) X { X (void) af_dropset (set1); X *set1 = tmpset; X } X else X { X if (newset == set2) X { X (void) af_dropset (set2); X *set2 = tmpset; X } X else X *newset = tmpset; X } X X return (k); X} END_OF_FILE if test 19377 -ne `wc -c <'src/afs/afsets.c'`; then echo shar: \"'src/afs/afsets.c'\" unpacked with wrong size! fi # end of 'src/afs/afsets.c' fi if test -f 'src/vc/vldovl.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/vc/vldovl.c'\" else echo shar: Extracting \"'src/vc/vldovl.c'\" \(18709 characters\) sed "s/^X//" >'src/vc/vldovl.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: vldovl.c[3.10] Thu Feb 23 18:14:47 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/vldovl.c[3.4] X * Thu Feb 23 18:14:48 1989 axel@coma published $ X * --- empty log message --- X * vldovl.c[3.6] Thu Feb 23 18:14:48 1989 uli@coma published $ X * --- empty log message --- X * vldovl.c[3.8] Thu Feb 23 18:14:48 1989 axel@coma published $ X * --- empty log message --- X * vldovl.c[3.9] Thu Feb 23 18:14:48 1989 axel@coma save $ X * --- empty log message --- X * vldovl.c[3.10] Thu Feb 23 18:14:48 1989 axel@coma published $ X * --- empty log message --- X */ X X#include <stdio.h> X#include <strings.h> X#include <afs.h> X#include "vl.h" X Xextern int immediate_output; Xextern int version_number; X X/* X * Global variables X */ X Xchar pathname_required = 0; Xextern char vl_cwd[]; Xchar buf[1000]; Xchar *pending_name; /* Holds the name of a dir */ Xint dir_pending = 0; X XAf_attrs AF_attrbuf; XAf_set AF_fileset; Xchar error_string[80]; X Xvoid InitAttrs (AF_attrbuf, name) X Af_attrs *AF_attrbuf; X char *name; X /* X * Initializes the attribute buffer. X */ X X{ X register int i; X int vno; X register char **udattrs; X extern char *GetAuthoridFromAuthor(), *GetOwneridFromOwner(), X *GetAuthorhostFromAuthor(), *GetOwnerhostFromOwner(); X char cstring[MAXNAMLEN], vstring[16]; X X af_initattrs (AF_attrbuf); X X if (name && name[0] != '\0') { X if (BoundVersion (name, cstring, vstring)) { X /* This code kind of assumes, that directory names are not of */ X /* the kind 'dirname[2.9]' -- good luck! */ X vno = mkvno (vstring); X AF_attrbuf->af_gen = gen(vno); X AF_attrbuf->af_rev = rev(vno); X (void)strcpy (AF_attrbuf->af_syspath, af_afpath (cstring)); X (void)strcpy (AF_attrbuf->af_name, af_afname (cstring)); X (void)strcpy (AF_attrbuf->af_type, af_aftype (cstring)); X /* No further options are considered in this case */ X } X else { /* no bound version notation (e.g. foo.c[4.3]) for 'name' */ X if (IsDirectory (name)) { X (void)strcpy (AF_attrbuf->af_syspath, name); X } X else { /* 'name' is not a directory */ X (void)strcpy (AF_attrbuf->af_syspath, af_afpath (name)); X (void)strcpy (AF_attrbuf->af_name, af_afname (name)); X (void)strcpy (AF_attrbuf->af_type, af_aftype (name)); X } X } X } X /* Invariant: syspath, name and type fields of AF_attrbuf initialized */ X X if (IsOptionSet(VL_O_UDAGIVEN)) { X udattrs = GetUdattrs (); X for (i = 0 ; udattrs[i] ; i++) { X AF_attrbuf->af_udattrs[i] = udattrs[i]; X } X } X X if (IsOptionSet(VL_O_VERSIONNUM)) { X if (! (IsOptionSet(VL_O_HISTLOG) || IsOptionSet(VL_O_LOGMSG))) { X if ((i = gen(version_number)) >= 0) { X AF_attrbuf->af_gen = i; X } X if ((i = rev(version_number)) >= 0) { X AF_attrbuf->af_rev = i; X } X } X } X X if (IsOptionSet(VL_O_AUTHOR)) { X (void)strcpy (AF_attrbuf->af_author.af_username, GetAuthoridFromAuthor()); X (void)strcpy (AF_attrbuf->af_author.af_userhost, GetAuthorhostFromAuthor()); X } X X if (IsOptionSet(VL_O_OWNER)) { X (void)strcpy (AF_attrbuf->af_owner.af_username, GetOwneridFromOwner()); X (void)strcpy (AF_attrbuf->af_owner.af_userhost, GetOwnerhostFromOwner()); X } X return; X} X Xint PrintUDA (attrbuf) X Af_attrs *attrbuf; X{ X register char *cp; X register int i; X register char Checkbyte; X register first_uda_printed; X X if ( (attrbuf->af_udattrs == NULL) || (attrbuf->af_udattrs[0] == '\0')) X return 0; /* no user defined attributes */ X X X if (IsOptionSet(VL_O_LONGOUTPUT)) { X PrintLongVinfo (attrbuf); printf (":\n"); X } X else { X PrintShortVinfo (attrbuf); printf (":"); X } X X if (IsOptionSet(VL_O_LISTUDALONG)) { X Checkbyte = '\0'; X } X else { X Checkbyte = '='; X } X X first_uda_printed = 0; /* nothing yet printed */ X X for (i = 0; attrbuf->af_udattrs[i]; i++){ X cp = attrbuf->af_udattrs[i]; X X if (!IsOptionSet(VL_O_LISTHIDDENUDAS) && IsHiddenUda (cp)) X continue; X if (first_uda_printed) { X (void)putchar (';'); /* seperate udas by ';' */ X } X else { X (void)putchar (' '); X first_uda_printed = 1; X } X X while (cp && *cp && *cp != Checkbyte) { X if (*cp == AF_UDAVALDEL) { X (void)putchar (','); /* seperate values of uda by ',' X */ X } X else { X (void)putchar (*cp); X } X cp++; X } X } X (void)putchar ('\n'); X (void)fflush (stdout); X return 1; X} X XPrintVinfo (attrbuf) X Af_attrs *attrbuf; X{ X if (IsOptionSet(VL_O_LISTUDA|VL_O_LISTUDALONG)) { X return PrintUDA (attrbuf); X } X X if (IsOptionSet(VL_O_LONGOUTPUT)) { X PrintLongVinfo (attrbuf); X return 1; X } X X PrintShortVinfo (attrbuf); X return 1; X} X XPrintShortVinfo (attrbuf) X Af_attrs *attrbuf; X{ X if (immediate_output) { /* set during option scanning */ X if (dir_pending) { /* now we can print the pending dir name */ X printf ("\n%s:\n", pending_name ? pending_name : ""); X dir_pending = 0; X } X X printf ("%s%s%s%s%s%s%s%s", X (pathname_required) ? attrbuf->af_syspath : "", X (pathname_required) ? "/" : "", X attrbuf->af_name, X (attrbuf->af_type && (attrbuf->af_type[0] != '\0') ? "." : ""), X attrbuf->af_type, X GetVersionId (attrbuf->af_gen, attrbuf->af_rev), X (IsOptionSet(VL_O_VERSIONSTATE)) ? " -> " : "", X (IsOptionSet(VL_O_VERSIONSTATE)) ? GetVersionState (attrbuf->af_state) X : ""); X } X else { X (void)sprintf (buf, "%s%s%s%s%s%s%s%s", X (pathname_required) ? attrbuf->af_syspath : "", X (pathname_required) ? "/" : "", X attrbuf->af_name, X (attrbuf->af_type && (attrbuf->af_type[0] != '\0') ? "." : ""), X attrbuf->af_type, X GetVersionId (attrbuf->af_gen, attrbuf->af_rev), X (IsOptionSet(VL_O_VERSIONSTATE)) ? " -> " : "", X (IsOptionSet(VL_O_VERSIONSTATE)) ? GetVersionState (attrbuf->af_state) X : ""); X X AddEntry (buf); X } X} X XPrintLongVinfo (attrbuf) X Af_attrs *attrbuf; X{ X if (immediate_output) { /* set during option scanning */ X char *p1 = NULL, *p2 = NULL; X if (dir_pending) { /* now we can print the pending dir name */ X printf ("\n%s:\n", pending_name ? pending_name : ""); X dir_pending = 0; X } X/* This is the place to put out the name of eventual lockholders */ X printf ("%s %s %s %s %8d %s %s%s%s%s%s%s", X GetMode (attrbuf->af_mode), X GetVersionState (attrbuf->af_state), X p1=GetUserInfo (&(attrbuf->af_owner)), X (IsOptionSet(VL_O_AUTHOR)) X ? p2=GetUserInfo (&(attrbuf->af_author)) : "", X attrbuf->af_size, X (attrbuf->af_state > AF_BUSY) ? GetDate (attrbuf->af_stime) X : GetDate (attrbuf->af_mtime), X (pathname_required) ? attrbuf->af_syspath : "", X (pathname_required) ? "/" : "", X attrbuf->af_name, X (attrbuf->af_type && (attrbuf->af_type[0] != '\0')) ? "." X : "", X attrbuf->af_type, X GetVersionId (attrbuf->af_gen, attrbuf->af_rev)); X if (p1) free (p1); X if (p2) free (p2); X } X else { X (void)sprintf (buf, "%s %s %s %s %8d %s %s%s%s%s%s%s", X GetMode (attrbuf->af_mode), X GetVersionState (attrbuf->af_state), X GetUserInfo (&(attrbuf->af_owner)), X (IsOptionSet(VL_O_AUTHOR)) X ? GetUserInfo (&(attrbuf->af_author)) : "", X attrbuf->af_size, X (attrbuf->af_state > AF_BUSY) ? GetDate (attrbuf->af_stime) X : GetDate (attrbuf->af_mtime), X (pathname_required) ? attrbuf->af_syspath : "", X (pathname_required) ? "/" : "", X attrbuf->af_name, X (attrbuf->af_type && (attrbuf->af_type[0] != '\0')) ? "." X : "", X attrbuf->af_type, X GetVersionId (attrbuf->af_gen, attrbuf->af_rev)); X AddEntry (buf); X } X} X XReportVersionInfo (name) X char *name; X X /* X * Returns 0 if no info for name found, otherwise 1; X */ X{ X register int i; X int numhits, Bnumhits=0; X int retcode = 1, rc; /* assume failure */ X char *cp; X Af_set AF_sfileset, AF_bfileset; X Af_key fkey; X X af_initset (&AF_sfileset); X af_initset (&AF_bfileset); X if (name && *name) { X cp = af_afpath(name); X if ( (! IsDirectory (name)) X && *cp X && strcmp (cp, vl_cwd)) { X /* X * name is a normal file and is not in current working dir X * require pathname on output X */ X pathname_required = 1; X } X else { X pathname_required = 0; X } X } X if (IsOptionSet(VL_O_LASTVERS)) { X rc=af_getkey (af_afpath (name), af_afname (name), af_aftype (name), X AF_LASTVERS, AF_LASTVERS, "", &fkey); X if (rc < 0) { X numhits = 0; X } X else { X af_setaddkey (&AF_sfileset, 0, &fkey); X numhits = 1; X } X } X else { X InitAttrs (&AF_attrbuf, name); X X /* now go, and get some info.... */ X if ((numhits = af_find (&AF_attrbuf, &AF_sfileset)) == -1) { X (void)sprintf (error_string, X "%s: in ReportVersionInfo(): af_find (%s)", X GetProgramName (), name); X af_perror (error_string); X return (1); /*exit (1);*/ X } X if (IsOptionSet(VL_O_LISTBINARY)) { X if ((Bnumhits = af_bpfind (&AF_attrbuf, &AF_bfileset)) == -1) { X (void)sprintf (error_string, X "%s: in ReportVersionInfo(): af_find (%s)", X GetProgramName (), name); X af_perror (error_string); X return (1); /*exit (1);*/ X } X } X } X if (af_union (&AF_sfileset, &AF_bfileset, &AF_fileset) < 0) { X af_perror ("af_union"); X return 1; X } X numhits += Bnumhits; X af_dropset (&AF_sfileset); X af_dropset (&AF_bfileset); X /* nothing found ? */ X if (numhits == 0) { X if (!IsOptionSet(VL_O_BEQUIET)) { X if (name && *name) { X if (! FileExists (name)) { X printf ("%s: %s: nothing appropriate found\n", GetProgramName (), name); X } X } X } X VinfoCleanup (); X return 1; /* report failure */ X } X X if ((*name != '\0') && IsDirectory (name)) { X if (immediate_output) { X /* X * dir name must be printed, iff X * something is found. But we can determine X * this not yet. X */ X dir_pending = 1; X pending_name = name; X } X else X AddClist (name); X } X X /* X * sort by name and version number. Busy version first then X * versions with increasing version numbers. X */ X X if (af_sortset (&AF_fileset, AF_ATTHUMAN) == -1) { X (void)sprintf (error_string, X "%s: in ReportVersionInfo(): af_sortset by AF_ATTHIMAN", X GetProgramName); X af_perror (error_string); X exit (1); X } X X for (i = 0; i < AF_fileset.af_nkeys; i++) { X if (af_gattrs (&(AF_fileset.af_klist[i]), &AF_attrbuf) == -1) { X (void)sprintf (error_string, "%s: in ReportVersionInfo(): af_gattrs"); X af_perror (error_string); X exit (1); X } X else { X if (IsHiddenFile(&AF_attrbuf) && !IsOptionSet(VL_O_LISTHIDDEN)) X continue; X X if (IsOptionSet(VL_O_STATEGIVEN)) { X if (!MatchesVersionStates (&AF_attrbuf)) X continue; X } X X if (!IsOptionSet(VL_O_BEQUIET)) { X if (IsOptionSet(VL_O_LOGMSG)) { X if (IsInHistoryLogMsgList (&AF_attrbuf)) { X if (PrintVinfo (&AF_attrbuf)) { X (void)putchar (':'); (void)putchar ('\n'); X PrintLogMsg (&(AF_fileset.af_klist[i])); X retcode = 0; /* success */ X } X } X } X else { X (void)PrintVinfo (&AF_attrbuf); X retcode = 0; /* success */ X } X } X } X } X/* VinfoCleanup (); */ X return retcode; X} X XInitReportVersion () X{ X InitCList (); X} X Xint PrintLogMsg (key) X Af_key *key; X{ X register char *logmsg; X X if ((logmsg = af_rnote (key)) == NULL) { X (void)sprintf (error_string, "%s: af_rnote", GetProgramName ()); X af_perror (error_string); X exit (1); X } X X printf ("%s", logmsg); X if (logmsg[strlen(logmsg)-1] != '\n') { X (void)putchar ('\n'); X (void)fflush (stdout); X } X free (logmsg); X X} X Xint IsInHistoryLogMsgList (attrbuf) X Af_attrs *attrbuf; X{ X if (attrbuf->af_state == AF_BUSY) X return 0; /* is busy version */ X if (IsOptionSet(VL_O_HISTLOG) && X ! IsOptionSet(VL_O_VERSIONNUM)) X return 1; X X if (!IsOptionSet(VL_O_HISTLOG|VL_O_VERSIONNUM)) X return 1; X else { X if (IsOptionSet(VL_O_HISTLOGPLUS)) { X if (attrbuf->af_gen > gen(version_number)) X return 1; X if ((gen(version_number) == attrbuf->af_gen) && X (attrbuf->af_rev > rev(version_number))) X return 1; X } X else { X if (attrbuf->af_gen < gen(version_number)) X return 1; X if ((gen(version_number) == attrbuf->af_gen) && X (attrbuf->af_rev < rev(version_number))) X return 1; X } X if ((gen(version_number) == attrbuf->af_gen) && X (rev(version_number) == attrbuf->af_rev)) return 1; X } X return 0; X} X Xstruct entry { X char *repr; X struct entry *next; X}; X Xstruct clist { /* column list */ X char *dir; /* name of dir */ X struct entry *entry; X struct clist *next; X}; X Xstruct clist *clistroot; Xstruct clist *curclist; Xstruct entry *curentry; X XInitCList () X{ X if ((clistroot = (struct clist*) malloc (sizeof (struct clist))) == NULL) { X (void)strcpy (error_string, "in InitClist (): malloc,1"); X perror (error_string); X exit (1); X } X X clistroot->dir = NULL; /* has never a name */ X X/* if ((clistroot->next = (struct clist*) malloc (sizeof (struct clist))) X == NULL) { X (void)strcpy (error_string, "in InitClist (): malloc,2"); X perror (error_string); X exit (1); X } X */ X clistroot->next = NULL; X curclist = clistroot; X X if ((curentry = (struct entry*) malloc (sizeof (struct entry))) == NULL) { X (void)strcpy (error_string, "in InitClist (): malloc,3"); X perror (error_string); X exit (1); X } X curentry->repr = NULL; X curentry->next = NULL; X X clistroot->entry = curentry; X} X XAddClist (name) X char *name; X{ X struct clist *this_clist; X X if ((this_clist = (struct clist*) malloc (sizeof (struct clist))) == NULL) { X (void)strcpy (error_string, "in AddCList (): malloc,1"); X perror (error_string); X exit (1); X } X X if ((this_clist->dir = malloc ((unsigned)(strlen (name)+1))) == NULL) { X (void)strcpy (error_string, "in AddCList (): malloc,2"); X perror (error_string); X exit (1); X } X X if ((this_clist->entry = (struct entry*) malloc (sizeof (struct entry))) X == NULL) { X (void)strcpy (error_string, "in AddCList (): malloc,2"); X perror (error_string); X exit (1); X } X X (void)strcpy (this_clist->dir, name); X this_clist->next = NULL; X curentry = this_clist->entry; X curentry->repr = NULL; X curentry->next = NULL; X X curclist->next = this_clist; X curclist = this_clist; X X} X XAddEntry (str) X char *str; X{ X struct entry* this_entry; X X if ((curentry->repr = malloc ((unsigned)(strlen (str)+1))) == NULL) { X (void)strcpy (error_string, "in AddEntry (): malloc,2"); X perror (error_string); X exit (1); X } X X (void)strcpy (curentry->repr, str); X X if ((this_entry = (struct entry*) malloc (sizeof (struct entry))) == NULL) { X (void)strcpy (error_string, "in AddEntry (): malloc,1"); X perror (error_string); X exit (1); X } X X this_entry->repr = NULL; X this_entry->next = NULL; X curentry->next = this_entry; X curentry = this_entry; X} X Xint computemaxlength (root) X struct entry *root; X{ X struct entry *this_entry; X int length = 0, maxlength = 0; X X if (!root) return 0; X X for (this_entry = root; X this_entry->repr && this_entry->next; X this_entry = this_entry->next) { X length = strlen (this_entry->repr); X if (length > maxlength) { X maxlength = length; X } X } X return maxlength; X} X XPrintList (root, wordsperline, colwidth, newline_required, group_it) X struct clist *root; X int wordsperline, colwidth, newline_required, group_it; X{ X struct entry *this_entry; X int nwordsprinted = 0; /* number of words per line yet printed */ X int ntabs = 0; X int length; X X if (/*root->entry && */root->entry->repr) { X if (root->dir) { X if (newline_required) (void)putchar ('\n'); X X printf ("%s:\n", root->dir); X } X } X X if (!group_it) { X for (this_entry = root->entry; X this_entry->repr && this_entry->next; X this_entry = this_entry->next) { X printf ("%s\n", this_entry->repr); X } X } X else { X for (this_entry = root->entry; X this_entry->repr && this_entry->next; X this_entry = this_entry->next) { X nwordsprinted++; X if (!(nwordsprinted % wordsperline)) { /* if last word in this line */ X printf ("%s\n", this_entry->repr); X } X else { X printf ("%s", this_entry->repr); X X /* compute #tabs to get to the next word position */ X length = strlen (this_entry->repr); X ntabs = (colwidth - length) / 8; X if ((colwidth - length) % 8) X ntabs++; X X while (ntabs--) (void)putchar ('\t'); X } X } X if (nwordsprinted % wordsperline) printf ("\n"); X } X} X XFlushIt (root) X struct clist *root; X{ X struct clist *this_clist; X int colwidth = 0, wordsperline = 0; X int maxlength = 0, newline_required = 0; X X for (this_clist = root; this_clist; this_clist = this_clist->next) { X X if (this_clist->entry && (this_clist->entry->repr == (char *) NULL)) X continue; /* skip empty list */ X X if (multicol_output_is_possible ()) { X /* compute length of longest word in this list */ X maxlength = computemaxlength (this_clist->entry); X X /* compute length to next tab stop */ X colwidth = (maxlength / 8) + 1; X colwidth *= 8; X X /* compute # words that fit in a line */ X#define maxcol 80 X if (!(wordsperline = maxcol / colwidth)) wordsperline++; X X } X X PrintList (this_clist, wordsperline, colwidth, newline_required, X multicol_output_is_possible ()); X newline_required++; X } X} X Xvoid FlushInfo () X{ X if (!immediate_output) X FlushIt (clistroot); /* Print now */ X} END_OF_FILE if test 18709 -ne `wc -c <'src/vc/vldovl.c'`; then echo shar: \"'src/vc/vldovl.c'\" unpacked with wrong size! fi # end of 'src/vc/vldovl.c' fi echo shar: End of archive 21 \(of 33\). cp /dev/null ark21isdone 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.