home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume19
/
shape
/
part14
< prev
next >
Wrap
Text File
|
1989-05-31
|
55KB
|
2,132 lines
Subject: v19i027: A software configuration management system, Part14/33
Newsgroups: comp.sources.unix
Sender: sources
Approved: rsalz@uunet.UU.NET
Submitted-by: Axel Mahler <unido!coma!axel>
Posting-number: Volume 19, Issue 27
Archive-name: shape/part14
#! /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 14 (of 33)."
# Contents: src/afs/afcompar.c src/shape/macro.c src/vc/vadm_note.c
# src/vc/vadm_reserve.c
# Wrapped by rsalz@papaya.bbn.com on Thu Jun 1 19:27:04 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/afs/afcompar.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/afs/afcompar.c'\"
else
echo shar: Extracting \"'src/afs/afcompar.c'\" \(12396 characters\)
sed "s/^X//" >'src/afs/afcompar.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 * afcompar.c -- attribute comparison routines
X *
X * Author: Andreas Lampen, TU-Berlin (andy@coma.UUCP)
X * (andy@db0tui62.BITNET)
X *
X * $Header: afcompar.c[1.4] Wed Feb 22 16:27:23 1989 andy@coma published $
X *
X * EXPORT:
X * af_cmpatime -- compare dates of last access
X * af_cmpauthor -- compare authors
X * af_cmpctime -- compare dates of last status change
X * af_cmpgen -- compare generation numbers
X * af_cmphost -- compare hosts
X * af_cmphuman -- compare name, type, gen, rev, variant
X * af_cmplocker -- compare lockers
X * af_cmpltime -- compare date of last lock change
X * af_cmpmode -- compare protections
X * af_cmpmtime -- compare dates of last modification
X * af_cmpname -- compare names
X * af_cmpowner -- compare owners
X * af_cmprev -- compare revision numbers
X * af_cmpsize -- compare file sizes
X * af_cmpstate -- compare states
X * af_cmpsvtime -- compare dates of saving
X * af_cmpspath -- compare syspaths
X * af_cmptype -- compare types
X * af_cmpvariant -- compare variant attributes
X * af_cmpversion -- compare version numbers (gen.rev)
X *
X * af_cmpfuncts -- list of names of all compare functions
X * af_attrlist -- list of attribute names
X * af_udaname -- global variable holding the name of the
X * user defined attribute used for sorting
X * af_cmpuda -- compare user defined attributes
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
X/*================================================================
X * af_cmpatime -- compare dates of last access
X *
X *================================================================*/
X
XEXPORT int af_cmpatime (key1, key2)
X Af_key *key1, *key2;
X{
X return (VATTR(key1).af_atime - VATTR(key2).af_atime);
X}
X
X/*================================================================
X * af_cmpauthor -- compare authors
X *
X *================================================================*/
X
XEXPORT af_cmpauthor (key1, key2)
X Af_key *key1, *key2;
X{
X int res;
X
X if (!(res = strcmp (NOTNIL(VATTR(key1).af_auname),
X NOTNIL(VATTR(key2).af_auname))))
X return (strcmp (NOTNIL(VATTR(key1).af_auhost),
X NOTNIL(VATTR(key2).af_auhost)));
X else
X return (res);
X}
X
X/*================================================================
X * af_cmpctime -- compare dates of last status change
X *
X *================================================================*/
X
XEXPORT af_cmpctime (key1, key2)
X Af_key *key1, *key2;
X{
X return (VATTR(key1).af_ctime - VATTR(key2).af_ctime);
X}
X
X/*================================================================
X * af_cmpgen -- compare generation numbers
X *
X *================================================================*/
X
XEXPORT af_cmpgen (key1, key2)
X Af_key *key1, *key2;
X{
X return (VATTR(key1).af_gen - VATTR(key2).af_gen);
X}
X
X/*================================================================
X * af_cmphost -- compare hostnames
X *
X *================================================================*/
X
XEXPORT af_cmphost (key1, key2)
X Af_key *key1, *key2;
X{
X return (strcmp (CATTR(key1).af_host, CATTR(key2).af_host));
X}
X
X/*================================================================
X * af_cmphuman -- compare name, type, gen, rev, variant
X *
X *================================================================*/
X
XEXPORT af_cmphuman (key1, key2)
X Af_key *key1, *key2;
X{
X int diff;
X
X if (!(diff = strcmp (VATTR(key1).af_name, VATTR(key2).af_name)) &&
X !(diff = strcmp (NOTNIL(VATTR(key1).af_type),
X NOTNIL(VATTR(key2).af_type))) &&
X !(diff = VATTR(key1).af_gen - VATTR(key2).af_gen) &&
X !(diff = VATTR(key1).af_rev - VATTR(key2).af_rev))
X {
X return (strcmp (NOTNIL(VATTR(key1).af_variant),
X NOTNIL(VATTR(key2).af_variant)));
X }
X return (diff);
X}
X
X/*================================================================
X * af_cmplocker -- compare lockers
X *
X *================================================================*/
X
XEXPORT af_cmplocker (key1, key2)
X Af_key *key1, *key2;
X{
X int res;
X
X if (!(res = strcmp (NOTNIL(VATTR(key1).af_lckname),
X NOTNIL(VATTR(key2).af_lckname))))
X return (strcmp (NOTNIL(VATTR(key1).af_lckhost),
X NOTNIL(VATTR(key2).af_lckhost)));
X else
X return (res);
X}
X
X/*================================================================
X * af_cmpltime -- compare dates of last lock change
X *
X *================================================================*/
X
XEXPORT af_cmpltime (key1, key2)
X Af_key *key1, *key2;
X{
X return (VATTR(key1).af_ltime - VATTR(key2).af_ltime);
X}
X
X/*================================================================
X * af_cmpmode -- compare protections
X *
X *================================================================*/
X
XEXPORT af_cmpmode (key1, key2)
X Af_key *key1, *key2;
X{
X return (VATTR(key1).af_mode - VATTR(key2).af_mode);
X}
X
X/*================================================================
X * af_cmpmtime -- compare dates of last modification
X *
X *================================================================*/
X
XEXPORT af_cmpmtime (key1, key2)
X Af_key *key1, *key2;
X{
X return (VATTR(key1).af_mtime - VATTR(key2).af_mtime);
X}
X
X/*================================================================
X * af_cmpname -- compare names
X *
X *================================================================*/
X
XEXPORT af_cmpname (key1, key2)
X Af_key *key1, *key2;
X{
X return (strcmp (VATTR(key1).af_name, VATTR(key2).af_name));
X}
X
X/*================================================================
X * af_cmpowner -- compare owners
X *
X *================================================================*/
X
XEXPORT af_cmpowner (key1, key2)
X Af_key *key1, *key2;
X{
X int res;
X
X if (!(res = strcmp (CATTR(key1).af_ownname, CATTR(key2).af_ownname)))
X return (strcmp (CATTR(key1).af_ownhost, CATTR(key2).af_ownhost));
X else
X return (res);
X}
X
X/*================================================================
X * af_cmprev -- compare revision numbers
X *
X *================================================================*/
X
XEXPORT af_cmprev (key1, key2)
X Af_key *key1, *key2;
X{
X return (VATTR(key1).af_rev - VATTR(key2).af_rev);
X}
X
X/*================================================================
X * af_cmpsize -- compare file size
X *
X *================================================================*/
X
XEXPORT af_cmpsize (key1, key2)
X Af_key *key1, *key2;
X{
X return (VATTR(key1).af_fsize - VATTR(key2).af_fsize);
X}
X
X/*================================================================
X * af_cmpstate -- compare states
X *
X *================================================================*/
X
XEXPORT af_cmpstate (key1, key2)
X Af_key *key1, *key2;
X{
X return (VATTR(key1).af_state - VATTR(key2).af_state);
X}
X
X/*================================================================
X * af_cmpsvtime -- compare dates of saving
X *
X *================================================================*/
X
XEXPORT af_cmpsvtime (key1, key2)
X Af_key *key1, *key2;
X{
X return (VATTR(key1).af_stime - VATTR(key2).af_stime);
X}
X
X/*================================================================
X * af_cmpspath -- compare syspaths
X *
X *================================================================*/
X
XEXPORT af_cmpspath (key1, key2)
X Af_key *key1, *key2;
X{
X return (strcmp (CATTR(key1).af_syspath, CATTR(key2).af_syspath));
X}
X
X/*================================================================
X * af_cmptype -- compare types
X *
X *================================================================*/
X
XEXPORT af_cmptype (key1, key2)
X Af_key *key1, *key2;
X{
X return (strcmp (NOTNIL(VATTR(key1).af_type),
X NOTNIL(VATTR(key2).af_type)));
X}
X
X/*================================================================
X * af_cmpvariant -- compare variant attribute
X *
X *================================================================*/
X
XEXPORT af_cmpvariant (key1, key2)
X Af_key *key1, *key2;
X{
X return (strcmp (NOTNIL(VATTR(key1).af_variant),
X NOTNIL(VATTR(key2).af_variant)));
X}
X
X/*================================================================
X * af_cmpversion -- compare version numbers (gen.rev)
X *
X *================================================================*/
X
XEXPORT af_cmpversion (key1, key2)
X Af_key *key1, *key2;
X{
X if (VATTR(key1).af_gen == VATTR(key2).af_gen)
X return (VATTR(key1).af_rev - VATTR(key2).af_rev);
X else
X return (VATTR(key1).af_gen - VATTR(key2).af_gen);
X}
X
X/*===============================================================
X * af_cmpfuncts -- array of comparison functions
X *
X *===============================================================*/
X
Xstruct cmpfun { int (*func) (); };
X
XEXPORT struct cmpfun af_cmpfuncts[] = { af_cmpatime,
X af_cmpauthor,
X af_cmpctime,
X af_cmpgen,
X af_cmphost,
X af_cmphuman,
X af_cmplocker,
X af_cmpltime,
X af_cmpmode,
X af_cmpmtime,
X af_cmpname,
X af_cmpowner,
X af_cmprev,
X af_cmpsize,
X af_cmpstate,
X af_cmpsvtime,
X af_cmpspath,
X af_cmptype,
X af_cmpvariant,
X af_cmpversion,
X };
X
X
X/*===============================================================
X * af_attrlist -- list of attribute names
X * (in alphabetical order)
X *
X *===============================================================*/
X
XEXPORT char *af_attrlist[] = { AF_ATTATIME,
X AF_ATTAUTHOR,
X AF_ATTCTIME,
X AF_ATTGEN,
X AF_ATTHOST,
X AF_ATTHUMAN,
X AF_ATTLOCKER,
X AF_ATTLTIME,
X AF_ATTMODE,
X AF_ATTMTIME,
X AF_ATTNAME,
X AF_ATTOWNER,
X AF_ATTREV,
X AF_ATTSIZE,
X AF_ATTSTATE,
X AF_ATTSTIME,
X AF_ATTSPATH,
X AF_ATTTYPE,
X AF_ATTVARIANT,
X AF_ATTVERSION,
X };
X
X/*================================================================
X * af_cmpuda -- compare user defined attributes
X *
X *================================================================*/
X
XEXPORT char af_udaname[AF_UDANAMLEN];
X
XEXPORT af_cmpuda (key1, key2)
X Af_key *key1, *key2;
X{
X char *uda1, *uda2, *vallist1, *vallist2, *af_symlookup();
X
X uda1 = af_symlookup (&(VATTR(key1).af_uhtab), af_udaname,
X (Af_revlist *)0, (Af_revlist **)0);
X uda2 = af_symlookup (&(VATTR(key2).af_uhtab), af_udaname,
X (Af_revlist *)0, (Af_revlist **)0);
X
X if (uda1 == (char *)0)
X {
X if (uda2 == (char *)0)
X return (0); /* equal */
X else
X return (1); /* key1 is "greater" than key2 */
X }
X else
X {
X if (uda2 == (char *)0)
X return (-1); /* key2 is "greater" than key1 */
X }
X
X /* see if ther are values */
X vallist1 = index (uda1, AF_UDANAMDEL);
X vallist2 = index (uda2, AF_UDANAMDEL);
X
X if (vallist1 == (char *)0)
X {
X if (vallist2 == (char *)0)
X return (0); /* equal */
X else
X return (1); /* key1 is "greater" than key2 */
X }
X else
X {
X if (vallist2 == (char *)0)
X return (-1); /* key2 is "greater" than key1 */
X }
X
X /* compare values of user defined attributes */
X /* this is a simple textual comparison up to now */
X return (strcmp (vallist1, vallist2));
X}
X
END_OF_FILE
if test 12396 -ne `wc -c <'src/afs/afcompar.c'`; then
echo shar: \"'src/afs/afcompar.c'\" unpacked with wrong size!
fi
# end of 'src/afs/afcompar.c'
fi
if test -f 'src/shape/macro.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/shape/macro.c'\"
else
echo shar: Extracting \"'src/shape/macro.c'\" \(12566 characters\)
sed "s/^X//" >'src/shape/macro.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: macro.c,v 3.2 89/02/20 16:25:49 wolfgang Exp $";
X#endif
X#ifndef lint
Xstatic char *ConfFlg = CFFLGS; /* should be defined from within Makefile */
X#endif
X/*
X * $Log: macro.c,v $
X * Revision 3.2 89/02/20 16:25:49 wolfgang
X * NET-RELEASE
X *
X * Revision 3.1 89/02/08 12:45:34 wolfgang
X * performance improved.
X *
X * Revision 3.0 89/01/24 11:35:54 wolfgang
X * New System Generation
X *
X * Revision 2.19 89/01/03 13:11:05 wolfgang
X * changes done for lint
X *
X * Revision 2.18 88/12/21 15:03:44 wolfgang
X * changes done for lint
X *
X * Revision 2.17 88/12/15 16:16:23 wolfgang
X * bug fixed in get_macros (segmantation violation on sissy (SUN))
X *
X * Revision 2.16 88/11/21 20:56:56 wolfgang
X * changes done for sun
X *
X * Revision 2.15 88/11/18 15:01:18 wolfgang
X * bug fixed: ::= indicates no longer a macrodef.
X *
X * Revision 2.14 88/11/04 16:41:58 wolfgang
X * variant macros no are accumulated.
X *
X * Revision 2.13 88/10/27 16:37:40 wolfgang
X * bugs fixed (new variant handling).
X *
X * Revision 2.12 88/10/20 13:20:56 wolfgang
X * bug fixed in get_variant_macro.
X *
X * Revision 2.11 88/10/18 17:41:12 wolfgang
X * new handling for variants implemented. macro expansion changed.
X *
X * Revision 2.10 88/10/14 17:14:10 wolfgang
X * new procedure: get_variant_macro added and changes don for new
X * handling of variants.
X *
X * Revision 2.9 88/10/13 12:03:24 wolfgang
X * handle_comments changed: white space is now required after #%.
X *
X * Revision 2.8 88/09/16 13:30:57 wolfgang
X * getlin changed. In continuation lines one leading TAB is now suppressd.
X *
X * Revision 2.7 88/09/09 11:40:31 wolfgang
X * little bug fixed.
X *
X * Revision 2.6 88/09/08 11:57:51 wolfgang
X * handle_comments(line) improved: # are allowed in quotes.
X *
X * Revision 2.5 88/09/08 11:48:29 wolfgang
X * handle_comments improved: kills commenmts if there are no quotes.
X *
X * Revision 2.4 88/09/08 10:32:55 wolfgang
X * handle_comments(line) added. Now comments are allowed in rule- and
X * variant-section, respectively.
X *
X * Revision 2.3 88/09/07 11:22:38 wolfgang
X * get_macros changed; the files are copied into a tmp file which is
X * the input file for yylex.
X *
X * Revision 2.2 88/08/23 16:33:21 wolfgang
X * In dump() now \t is supressed for generating confid's (im macrodefinitions
X * \t is not allowed as first char.
X *
X * Revision 2.1 88/08/19 10:17:33 wolfgang
X * This version is part of a release
X *
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/dir.h>
X#include "macro.h"
X#include "shape.h"
X
Xextern FILE *mkstemp();
Xextern void addhash();
Xextern char *get_variant_macro();
Xextern char *curvar[];
Xextern struct vardef *vardefs[];
Xchar *template = "/tmp/shapeXXXXXX";
XFILE *temp;
X
X
Xchar *curvpath[8] = {NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL};
Xchar *errstring;
Xint macdepth;
Xint variants_active = 0;
X
Xchar *get_next_item(string)
X char *string;
X{
X char *p1;
X
X if ((p1 = index(string,' ')) != NIL)
X {
X *p1 = '\0';
X return string;
X }
X else
X return string;
X}
X
X
Xchar *getlin(file)
X FILE *file;
X{
X char line[MAXLINELENGTH];
X char line2[MAXLINELENGTH];
X int len = 0;
X while (fgets(line, MAXLINELENGTH, file)) /* getc ????? */
X {
X len = strlen(line);
X while ((line[len-2] == '\\') && (line[len-1] == '\n'))
X {
X line[len-2] = ' ';
X line[len-1] = '\0';
X (void) fgets(line2, MAXLINELENGTH, file);
X if(line2[0] == '\t')
X (void) strcat(line,&line2[1]);
X else
X (void) strcat(line,line2);
X len = strlen(line);
X }
X len = strlen(line);
X line[len-1] = '\0';
X return (line);
X }
X/*NOTREACHED*/
X}
X
X
Xget_macros(file)
X FILE *file;
X{
X FILE *incfile;
X char *line;
X char *incp;
X int inck;
X char incfilename[MAXNAMLEN];
X extern char *expandmacro();
X
X while((line = getlin(file)) != NIL)
X {
X
X if((strncmp(line,INCLUDE,7)) == 0)
X {
X inck = 7;
X while ((line[inck] == '\t') || (line[inck] == ' '))
X inck++;
X if ((incp = rindex(line+inck,' ')) != NIL)
X *incp = '\0';
X if ((incp = rindex(line+inck,'\t')) != NIL)
X *incp = '\0';
X if (index(line+inck,'$') != NIL)
X (void) strcpy(incfilename,expandmacro(line+inck));
X else
X (void) strcpy(incfilename,line+inck);
X if ((incfile = fopen(incfilename,"r")) == NULL)
X errexit(24,incfilename);
X else
X {
X get_macros(incfile);
X (void) fclose(incfile);
X }
X }
X else
X {
X handle_comments(line);
X fputs(line,temp);
X fputs("\n",temp);
X
X macrodef(line);
X }
X }
X}
X
X
Xmacrodef(line)
X char *line;
X{
X char *name;
X char *value;
X int hashv;
X char *p1, *p2;
X char *enventry;
X char *line2;
X
X if (!line)
X return;
X
X if ((name = malloc(MACRONAM)) == NIL)
X errexit(10,"malloc");
X if((value = malloc(MACROVAL)) == NIL)
X errexit(10,"malloc");
X if((line2 = malloc(MAXLINELENGTH)) == NIL)
X errexit(10,"malloc");
X if (*line != '\t')
X {
X p1 = index(line,'=');
X p2 = index(line,':');
X
X if ((p1 != NIL) && (*(p1-1) != ':') && (*(p1-2) != ':'))
X {
X if ((p2 == NIL) || (p1 < p2))
X {
X *p1 = '\0';
X p2 = p1;
X p2--;
X while((*line == '\t') || (*line == ' '))
X line++;
X while((*p2 == ' ') || (*p2 == '\t'))
X *p2-- = '\0';
X name = line;
X }
X p1++;
X while((*p1 == '\t') || (*p1 == ' '))
X p1++;
X value = p1;
X if (strcmp(name,IMPORT) != 0)
X {
X#ifdef DEBUG_MACRO
Xprintf("name=#%s#\nvalue=#%s#\n\n", name, value);
X#endif DEBUG_MACRO
X hashv = hashval(name);
X addhash(hashv,name,value);
X if (strcmp(name,"VPATH") == 0)
X {
X insertvpath(value);
X }
X }
X else
X {
X /* get environment variables */
X while((name = get_next_item(value)) != NIL)
X {
X if (strcmp(value,"") == 0)
X break;
X value = index(value,'\0');
X value++;
X if ((enventry = getenv(name)) != NIL)
X {
X (void) strcpy(line2,name);
X (void) strcat(line2,"=");
X (void) strcat(line2,enventry);
X macrodef(line2);
X }
X }
X }
X }
X }
X free(name);
X free(line2);
X free(value);
X}
X
Xchar *expandmacro(inpstring)
X char *inpstring;
X{
X
Xchar name[64];
Xint hashv;
Xchar *p;
Xstruct hash *current = (struct hash *) NIL;
Xint j = 0;
Xint ii = 0;
Xchar *list[100];
Xchar klazu;
Xchar *start;
Xchar newstr[MAXLINELENGTH];
Xchar *string;
Xchar *mist;
Xchar *variant_macro = NIL;
XBool dollar;
Xdollar = FALSE;
Xif (macdepth == 0)
X errstring = inpstring;
X
Xmacdepth++;
X
Xif (macdepth == 50)
X errexit(25, errstring);
X
Xnewstr[0] = '\0';
Xif ((string = malloc((unsigned) (strlen(inpstring) + sizeof(char)))) == NIL)
X errexit(10,"malloc");
X(void) strcpy(string,inpstring);
Xp = string;
X
Xwhile (*p != '\0')
X {
X if (*p != '$')
X {
X if (dollar == FALSE)
X {
X list[ii] = p;
X ii++;
X dollar = FALSE;
X }
X if (ii > 100)
X errexit(25, errstring);
X }
X while ((*p != '$') && (*p != '\0'))
X p++;
X if ( *p == '\0')
X break;
X else
X {
X if ((*(p+1) == '(') || (*(p+1) == '{'))
X {
X klazu = ((*(p+1) == '(') ? ')':'}');
X *p = '\0';
X p = p + 2;
X start = p;
X
X while(*p != klazu)
X {
X p++;
X }
X *p = '\0';
X (void) strcpy(name,start);
X p++;
X }
X else
X {
X if ((*(p+1) != '@') && (*(p+1) != '?') &&
X (*(p+1) != '<') && (*(p+1) != '*') &&
X (*(p+1) != '$') && (*(p+1) != '+'))
X {
X name[0] = *(p+1);
X name[1] = '\0';
X *p = '\0';
X p = p + 2;
X }
X else
X {
X name[0] = '\0';
X dollar = TRUE;
X p = p + 2;
X }
X }
X if (name[0] != '\0')
X {
X dollar = FALSE;
X
X if(strcmp(curvar[0],""))
X {
X variant_macro = get_variant_macro(name);
X if (strcmp(variant_macro,BLUMENKOHL))
X {
X mist = expandmacro(variant_macro);
X if ((list[ii] =
X malloc((unsigned)
X (strlen(mist) + sizeof(char)))) == NIL)
X errexit(10,"malloc");
X (void) strcpy(list[ii],mist);
X ii++;
X if (ii > 100)
X errexit(25, errstring);
X }
X }
X if((variant_macro == NIL) || (!strcmp(variant_macro,BLUMENKOHL)))
X {
X variant_macro = NIL;
X hashv = hashval(name);
X if (hashtab[hashv] != (struct hash *) NIL)
X {
X current = hashtab[hashv];
X while (((strcmp (current->name, name)) != 0) && (current->next != (struct hash *) NIL))
X current = current->next;
X
X if ((strcmp(current->name, name) == 0))
X {
X mist = expandmacro(current->entry);
X if ((list[ii] =
X malloc((unsigned)
X (strlen(mist) + sizeof(char)))) == NIL)
X errexit(10,"malloc");
X (void) strcpy(list[ii],mist);
X ii++;
X if (ii > 100)
X errexit(25, errstring);
X }
X }
X }
X }
X }
X }
Xfor (j = 0; j < ii; j++)
X (void) strcat(newstr,list[j]);
Xmacdepth = 0;
Xreturn newstr;
X} /*end expandmacro */
X
X
X
Xhandle_comments(line)
X char *line;
X{
X char *p;
X int i;
X int q = 0;
X int dq = 0;
X
X if (( p = index(line,'#')) == NIL)
X /* no comment */
X return;
X
X if ((line[0] == '#') && (line[1] != '%'))
X {
X /* comment, starting at beginning of line */
X line[0] = '\0';
X return;
X }
X
X if (((line[0] == '#') && (line[1] == '%')) &&
X ((line[2] == ' ') || (line[2] == '\t')))
X return;
X
X if (p != NIL)
X {
X if((index(line,'\'') == NIL) && (index(line,'\"') == NIL))
X /* the # is not in quotes */
X {
X *p = '\0';
X return;
X }
X else
X /* maybe no comment */
X {
X for(i = 0; line[i] != '\0'; i++)
X {
X if(line[i] == '\'')
X q++;
X if(line[i] == '\"')
X dq++;
X if((line[i] == '#') && ((q % 2) == 0) && ((dq % 2) == 0))
X {
X line[i] = '\0';
X return;
X }
X }
X }
X }
X}
X
X
Xchar *get_variant_macro(name)
X char *name;
X
X /* get macro value for variant */
X{
Xint i = 0;
Xint k = 0;
Xint j = 0;
X
Xchar *p;
Xchar *p1;
Xchar *p2;
Xchar *p3;
X
Xchar macro[2048];
Xchar retval[1024];
X
Xretval[0] = '\0';
X
Xwhile(strcmp(curvar[i],""))
X {
X k = 0;
X while (vardefs[k] != (struct vardef *) NIL)
X {
X if (strcmp(vardefs[k]->name,curvar[i]))
X k++;
X else
X break;
X }
X
X if (vardefs[k] != (struct vardef *) NIL)
X {
X if ((!strcmp(name,"vpath")) && (vardefs[k]->vpath != NIL))
X {
X if (retval[0] == '\0')
X (void) strcat(retval, vardefs[k]->vpath);
X else
X {
X (void) strcat(retval," ");
X (void) strcat(retval, vardefs[k]->vpath);
X }
X }
X
X if ((!strcmp(name,"vflags")) && (vardefs[k]->vflags != NIL))
X {
X if (retval[0] == '\0')
X (void) strcat(retval,vardefs[k]->vflags);
X else
X {
X (void) strcat(retval," ");
X (void) strcat(retval,vardefs[k]->vflags);
X }
X }
X
X for(j = 0; j < MAXVMACROS; j++)
X {
X if (vardefs[k]->vmacros[j] == NIL)
X {
X i++;
X break;
X }
X (void) strcpy(macro,vardefs[k]->vmacros[j]);
X if (!strcmp(macro,""))
X {
X i++;
X break;
X }
X p1 = index(macro,'=');
X p2 = index(macro,' ');
X p3 = index(macro,'\t');
X
X if (p2 == NIL)
X p2 = p1 + 1;
X
X if (p3 == NIL)
X p3 = p1 + 1;
X
X if (( p1 < p2) && (p1 < p3))
X p = p1;
X if (( p2 < p1) && (p2 < p3))
X p = p2;
X if (( p3 < p2) && (p3 < p1))
X p = p3;
X
X *p = '\0';
X p1++;
X
X if (!strcmp(name,macro))
X {
X while((*p1 == ' ') || (*p1 == '\t') || (*p1 == '='))
X p1++;
X if(retval[0] == '\0')
X (void) strcat(retval,p1);
X else
X {
X (void) strcat(retval," ");
X (void) strcat(retval,p1);
X }
X }
X }
X }
X else
X i++;
X }
Xif(retval[0] != '\0')
X return(retval);
Xelse
X return(BLUMENKOHL);
X}
END_OF_FILE
if test 12566 -ne `wc -c <'src/shape/macro.c'`; then
echo shar: \"'src/shape/macro.c'\" unpacked with wrong size!
fi
# end of 'src/shape/macro.c'
fi
if test -f 'src/vc/vadm_note.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/vc/vadm_note.c'\"
else
echo shar: Extracting \"'src/vc/vadm_note.c'\" \(12678 characters\)
sed "s/^X//" >'src/vc/vadm_note.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: vadm_note.c[3.10] Thu Feb 23 18:14:13 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/vadm_note.c[3.4]
X * Thu Feb 23 18:14:13 1989 axel@coma published $
X * --- empty log message ---
X * vadm_note.c[3.6] Thu Feb 23 18:14:13 1989 axel@coma published $
X * --- empty log message ---
X * vadm_note.c[3.7] Thu Feb 23 18:14:13 1989 axel@coma save $
X * --- empty log message ---
X * vadm_note.c[3.8] Thu Feb 23 18:14:13 1989 axel@coma save $
X * --- empty log message ---
X * vadm_note.c[3.9] Thu Feb 23 18:14:13 1989 axel@coma save $
X * --- empty log message ---
X * vadm_note.c[3.10] Thu Feb 23 18:14:13 1989 axel@coma published $
X * --- empty log message ---
X */
X
X#include <stdio.h>
X#include <strings.h>
X#include <afs.h>
X#include "vadm.h"
X#include "afsapp.h"
X#include "locks.h"
X#include "vc_sysdep.h"
X
X/* Externals */
Xextern int af_errno;
Xextern jmp_buf here; /* reentrance point after we caught a sig */
Xextern char *malloc (), *getenv();
Xextern char **environment; /* pointer to our environment */
Xextern struct Transaction ThisTransaction;
Xextern char *get_from_stdin(); /* read a text from stdin */
Xextern int call_editor(); /* returns a text */
Xextern char *FindProgram(), *FindFile();
Xextern unsigned int options;
Xextern int def_vnum;
X
X/* locals */
Xstatic char buf[100]; /* buffer for error messages */
Xstatic char *editor; /* user's favorite editor*/
X
X/**/
Xstatic
Xint determine_defaults ()
X{
X /*
X * Returns 0 on error (editor not found, editor not executable, and so).
X * 1 on success.
X */
X char *neweditor;
X int ask_default = 0; /* if env-editor is not available */
X /* user if he/she want's default editor */
X
X /* examine user's favorite editor, if any */
X if ((editor = getenv (EDITOR_ENV_NAME)) == NULL)
X editor = DEFAULT_EDITOR;
X
X if (!index (editor, '/'))
X if ((neweditor = FindFile (editor)) == NULL) {
X (void)sprintf (buf, "Sorry, your favorite editor %s is not available on this machine.",
X editor);
X logmsg (buf);
X ask_default++;
X }
X else
X editor = neweditor;
X
X /* is editor executable ? */
X if (!ask_default && !FileExecutable (editor)) {
X (void)sprintf (buf, "Sorry, your favorite editor %s is not executable.",
X editor);
X logmsg (buf);
X ask_default++;
X }
X
X if (ask_default) {
X /* if default editor not available resign. */
X if (strcmp (editor, DEFAULT_EDITOR)) {
X (void)sprintf (buf, "Do you accept default editor %s ?", DEFAULT_EDITOR);
X if (ask_confirm (buf, "yes")) {
X editor = DEFAULT_EDITOR;
X if (!FileExecutable (editor)) {
X logmsg ("Arrg, also default editor is not available. --- I resign.");
X return 0;
X }
X }
X else
X return 0; /* user doesn't want */
X }
X else
X return 0; /* default editor is not available */
X }
X return 1;
X}
X
X/**/
Xstatic
Xint note_ok (newnote, oldnote)
X char *newnote, *oldnote;
X{
X /*
X * returns 0 if no changes detected, 1 otherwise.
X */
X
X if (!newnote) {
X if (ask_confirm ("Description is empty. Save anyway ?", "no"))
X return 0;
X else
X return 1;
X }
X
X if (oldnote && !strcmp (newnote, oldnote)) {
X logmsg ("No changes detected.");
X return 0;
X }
X
X /* newnote contains only layout ? */
X while (*newnote) {
X switch (*newnote) {
X case ' ':
X case '\n':
X case '\t':
X break;
X default:
X return 1;
X break;
X }
X newnote++;
X }
X
X if (ask_confirm ("Description contains only layout. Save anyway?", "no"))
X return 0;
X else
X return 1;
X}
X
X/**/
Xstatic
Xint save_it (key, note)
X Af_key *key;
X char *note;
X{
X af_snote (key, note);
X ThisTransaction.tr_done = 1;
X}
X
X/**/
Xstatic
Xint save_note_multiple (note, set)
X char *note;
X Af_set *set;
X{
X int i, rc = 0;
X
X for (i = 0 ; i < set->af_nkeys; i++) {
X rc += af_snote (&(set->af_klist[i]), note);
X }
X if (note) free (note);
X return rc;
X}
X
X/**/
Xstatic
Xint process_notes (set, change_it)
X Af_set *set;
X int change_it;
X{
X int i;
X char *note, *newnote, *mktemp();
X int retcode; /* retcode from editor */
X char tmp_file[20]; /* tmp-file's name */
X char name[MAXNAMLEN], nametype[MAXTYPLEN];
X
X if (!determine_defaults ()) /* that is the editor */
X return -1;
X
X CatchSigs ();
X
X /* read description per file and save if changes. */
X for (i = 0; i < set->af_nkeys; i++) {
X
X /* remember this location */
X if (setjmp (ThisTransaction.tr_env)) {
X if ( i < set->af_nkeys )
X continue;
X else
X return 0;
X }
X
X /* construct file name */
X (void)sprintf (nametype, "%s", af_rtype(&set->af_klist[i]));
X (void)sprintf (name, "%s%c%s", af_rname(&set->af_klist[i]),
X nametype ? '.' : NULL,
X nametype ? nametype : NULL);
X
X ThisTransaction.tr_seqno = i;
X (void)strcpy (ThisTransaction.tr_fname, name);
X ThisTransaction.tr_done = 0;
X
X /* print afsname and version */
X (void)sprintf (buf, "%s[%d.%d]:", name, af_rgen (&set->af_klist[i]),
X af_rrev (&set->af_klist[i]));
X logmsg (buf); /* this file */
X
X (void)strcpy (tmp_file, mktemp ("/tmp/vctlXXXXXX"));
X
X /* Do we change the old note ? */
X if (change_it) { /* get old note */
X note = af_rnote (&set->af_klist[i]);
X
X /* Note "Empty log message" is an empty note */
X if (!strcmp (note, EMPTYNOTE)) {
X free (note);
X note = NULL;
X }
X }
X else
X note = NULL;
X
X newnote = NULL;
X retcode = call_editor (editor, tmp_file, note, &newnote);
X
X if (retcode == -1) { /* editor exited abnormally */
X if (i == (set->af_nkeys - 1)) {
X logmsg ("Description lost.");
X return 1;
X }
X
X if (ask_confirm ("Description lost. Continue ?", "no"))
X return 1;
X else
X continue;
X }
X
X if (note_ok (newnote, note)) { /* any changes ? */
X save_it (&set->af_klist[i], newnote);
X logmsg ("Description saved.");
X }
X else
X logmsg ("Description not saved.");
X
X if (note)
X free (note);
X
X if (newnote)
X free (newnote);
X }
X return 0;
X}
X
X/**/
Xprint_erroneous (erroneous, errs)
X char **erroneous;
X int errs;
X{
X int i, j;
X
X fprintf (stderr, "No saved versions of");
X j = 0;
X for (i = 0; i < errs; i++) {
X if (++j == errs)
X if (errs == 1)
X fprintf (stderr, " \"%s\"", erroneous[i]);
X else
X fprintf (stderr, " and \"%s\"", erroneous[i]);
X else
X fprintf (stderr, " \"%s\",", erroneous[i]);
X }
X fprintf (stderr, " found --- skipped\n");
X}
X
X/**/
Xstatic
Xint do_note (vlist, ac, av, change_it)
X struct vc_vlist *vlist;
X int ac;
X char **av;
X int change_it;
X{
X Af_set set;
X int errs;
X char **erroneous;
X
X if (IsOptionSet(Vopt_version)) {
X errs = GetKeysByGenRev
X (ac,av, gen(def_vnum), rev(def_vnum), &set,
X &erroneous);
X }
X else {
X if (! ((vlist->from_version_set) || vlist->to_version_set))
X errs = GetKeysByGenRev
X (ac,av, AF_BUSYVERS, AF_BUSYVERS, &set, &erroneous);
X else
X errs = GetKeysByName (ac,av, vlist, &set, &erroneous);
X }
X if (errs)
X print_erroneous (erroneous, errs);
X
X /* all given files do not exist ? */
X if (!set.af_nkeys) {
X logmsg ("Nothing appropriate found.");
X return 1;
X }
X
X if (af_sortset (&set, AF_ATTHUMAN) == -1) {
X af_perror ("Do_note: af_sortset AF_ATTHUMAN");
X return 1;
X }
X
X /* If stdin is redirected use text as description for *all* afs files. */
X if (!isatty (0)) { /* 0 == stdin */
X /* do not append to old desc. Also we have no special term-char.
X * Read until EOF. */
X return save_note_multiple (get_from_stdin ((char *)NULL, -1), &set);
X }
X
X /* shall we go on if an error occurs? Ask user. */
X if (errs && (!ask_confirm ("Continue anyway ?", "yes")))
X return 1;
X
X return process_notes (&set, change_it);
X}
X
X/**/
Xint DoSetNote (vlist, ac, av)
X struct vc_vlist *vlist;
X int ac;
X char **av;
X{
X return do_note (vlist, ac, av, 0); /* don't change existing note */
X}
X
X/**/
Xint DoChangeNote (vlist, ac, av)
X struct vc_vlist *vlist;
X int ac;
X char **av;
X{
X return do_note (vlist, ac, av, 1); /* change existing note */
X}
X
X/**/
Xstatic
Xint do_description (vlist, ac, av, change_it)
X struct vc_vlist *vlist;
X int ac;
X char **av;
X int change_it; /* if set, append to old note */
X{
X /*
X * Changes an existing description note of the first version (i.e. 1.0)
X * of an AFS file. Returns 0 on success, otherwise 1 to indicate an error.
X */
X
X Af_set set;
X int errs = 0; /* # of not found afs files */
X char **erroneous;
X
X /* A version list makes no sence. Ignore it, but display warning msg. */
X if (vlist->from_version_set || vlist->to_version_set)
X logwng ("version specification list ignored.");
X
X errs = GetKeysByGenRev (ac,av, AF_FIRSTVERS, AF_FIRSTVERS, &set,
X &erroneous);
X
X if (errs)
X print_erroneous (erroneous, errs);
X
X /* all given files do not exist ? */
X if (!set.af_nkeys) {
X logmsg ("Nothing appropriate found.");
X return 1;
X }
X
X if (af_sortset (&set, AF_ATTHUMAN) == -1) {
X af_perror ("Do_description: af_sortset AF_ATTHUMAN");
X return 1;
X }
X
X /* If stdin is redirected use text as description for *all* afs files. */
X if (!isatty (0)) { /* 0 == stdin */
X /* do not append to old desc. Also we have no special term-char.
X * Read until EOF. */
X return save_note_multiple (get_from_stdin ((char *)NULL, -1), &set);
X }
X
X /* shall we go on if an error occurs? Ask user. */
X if (errs && (!ask_confirm ("Continue anyway ?", "yes")))
X return 1;
X
X return process_notes (&set, change_it);
X}
X
X/**/
Xint DoSetDescription (vlist, ac, av)
X struct vc_vlist *vlist;
X int ac;
X char **av;
X{
X return do_description (vlist, ac, av, 0); /* don't change existing note */
X}
X
X/**/
Xint DoChangeDescription (vlist, ac, av)
X struct vc_vlist *vlist;
X int ac;
X char **av;
X{
X return do_description (vlist, ac, av, 1); /* change to old note */
X}
X
Xint DoSetIntent (ac, av) int ac; char **av; {
X /* We must hold the lock for the history, that we wanna change. */
X register int i;
X int rc, rcsum = 0;
X char fname[256], messg[80], *oldintent, *intent, *getintent(), *intattr,
X *lockerid();
X Af_key thiskey;
X Af_user *locker;
X
X
X for (i=0; i < ac; i++) {
X if (setjmp (ThisTransaction.tr_env)) continue;
X rc = af_getkey (af_afpath (av[i]), af_afname (av[i]),
X af_aftype (av[i]), AF_BUSYVERS, AF_BUSYVERS,
X AF_NONAME, &thiskey);
X if (rc < 0) {
X (void)sprintf (messg, "can't find busy version for %s.", av[i]);
X logerr (messg);
X continue;
X }
X mkvstring (fname, &thiskey);
X if (locked(locker=vc_testlock_v(&thiskey))) {
X if (lockeruid (locker) == (Uid_t)getuid ()) {
X oldintent = af_rudattr (&thiskey, INTENT);
X intent = getintent ((char *)NULL, oldintent);
X if (oldintent) free (oldintent);
X intattr = malloc ((unsigned)(strlen (intent) + strlen (INTENT) +1));
X (void)sprintf (intattr, "%s%s", INTENT, intent);
X if (fail(af_sudattr (&thiskey, AF_REPLACE, intattr)))
X af_sudattr (&thiskey, AF_ADD, intattr);
X free (intattr);
X af_dropkey (&thiskey);
X }
X else {
X (void)sprintf (messg, "Can't set intent on %s (locked by %s).",
X fname, lockerid (locker));
X logerr (messg);
X af_dropkey (&thiskey);
X rcsum++;
X continue;
X }
X }
X else {
X (void)sprintf (messg, "You must have a lock on %s to set change intention.",
X fname);
X logerr (messg);
X af_dropkey (&thiskey);
X rcsum++;
X continue;
X }
X }
X return rcsum;
X}
X
END_OF_FILE
if test 12678 -ne `wc -c <'src/vc/vadm_note.c'`; then
echo shar: \"'src/vc/vadm_note.c'\" unpacked with wrong size!
fi
# end of 'src/vc/vadm_note.c'
fi
if test -f 'src/vc/vadm_reserve.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/vc/vadm_reserve.c'\"
else
echo shar: Extracting \"'src/vc/vadm_reserve.c'\" \(12489 characters\)
sed "s/^X//" >'src/vc/vadm_reserve.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: vadm_reserve.c[3.13] Thu Feb 23 18:14:17 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/vadm_reserve.c[3.7]
X * Thu Feb 23 18:14:17 1989 axel@coma published $
X * --- empty log message ---
X * vadm_reserve.c[3.9] Thu Feb 23 18:14:18 1989 axel@coma published $
X * --- empty log message ---
X * vadm_reserve.c[3.11] Thu Feb 23 18:14:18 1989 axel@coma published $
X * --- empty log message ---
X * vadm_reserve.c[3.12] Thu Feb 23 18:14:18 1989 axel@coma save $
X * --- empty log message ---
X * vadm_reserve.c[3.13] Thu Feb 23 18:14:18 1989 axel@coma published $
X * --- empty log message ---
X */
X
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#include <pwd.h>
X#include <stdio.h>
X#include <strings.h>
X
X#include "afs.h"
X#include "vadm.h"
X#include "afsapp.h"
X#include "locks.h"
X
X/* externals */
Xextern char *malloc();
Xextern int newmode;
Xextern Af_user newauthor;
Xextern int def_vnum;
Xextern struct Transaction ThisTransaction;
X
X/* forward */
Xchar *uidname ();
X
X/* locals */
Xstatic char buf[2048];
X
X/**/
XUid_t af_MY_rouid (key) Af_key *key; {
X /*
X * This function returns the userid of the owner of the AFS directory
X * containing the AFS object identified by key.
X */
X char path[256];
X struct stat statbuf;
X
X (void)strcpy (path, af_rsyspath (key));
X if (strcmp (path, "/") == NULL)
X (void)strcpy (path, "");
X (void)strcat (path, "/AFS");
X if (stat (path, &statbuf) < 0) {
X perror (path);
X return -1;
X }
X return statbuf.st_uid;
X}
X
Xint do_reserve (set)
X Af_set *set;
X{
X register int i;
X Af_user *locker;
X int errs = 0;
X char version[1024], *fn, *mkfn(), *p, *lockerid();
X struct stat sbuf;
X
X if (af_sortset (set, AF_ATTHUMAN) == -1)
X vctl_abort ("do_reserve: af_sortset()");
X
X for (i = 0; i < set->af_nkeys; i++) {
X mkvstring (version, &set->af_klist[i]);
X if (setjmp (ThisTransaction.tr_env)) continue;
X /* if (locking == AF_GLOBALLOCK) { /* to be implemented */
X if (p=rindex(version, '[')) *p = '\0';
X
X if (!locked(locker = vc_testlock_g(&set->af_klist[i]))) {
X logmsg ("WARNING! Administrative locking may lose attribute citations.");
X if (vc_lock_g(&set->af_klist[i], (Uid_t)geteuid()) == (Af_user *)NULL) {
X af_perror ("af_lock");
X continue;
X }
X else {
X if (af_rstate (&set->af_klist[i]) == AF_BUSY) {
X char *intent, *getintent();
X extern unsigned int options;
X if (!IsOptionSet (Vopt_quiet)) {
X intent = getintent ("Describe intended changes ?", (char *)NULL);
X }
X else intent = (char *)NULL;
X if (intent) {
X char *intattr;
X intattr = malloc ((unsigned)(strlen (intent) +
X strlen (INTENT) +1));
X (void)sprintf (intattr, "%s%s", INTENT, intent);
X if (fail(af_sudattr (&set->af_klist[i], AF_REPLACE, intattr)))
X af_sudattr (&set->af_klist[i] , AF_ADD, intattr);
X free (intattr);
X }
X }
X (void)sprintf (buf, "%s reserved.", version);
X fn = mkfn (&set->af_klist[i]);
X if (stat (fn, &sbuf) == 0) {
X (void)chmod (fn, (int)(sbuf.st_mode | 0200));
X }
X logmsg (buf);
X }
X }
X else { /* testlock returned something */
X if (lockeruid(locker) != (Uid_t)geteuid()) {
X (void)sprintf (buf, "%s is already locked by %s.", version,
X lockerid (locker));
X logmsg (buf);
X errs++;
X continue;
X }
X else {
X (void)sprintf (buf, "%s reserved.", version);
X fn = mkfn (&set->af_klist[i]);
X if (stat (fn, &sbuf) == 0) {
X (void)chmod (fn, (int)(sbuf.st_mode | 0200));
X }
X logmsg (buf);
X }
X }
X }
X if (errs)
X return 1;
X else
X return 0;
X}
X
Xint do_chmod (set)
X Af_set *set;
X{
X int i;
X int errs = 0;
X char version[1024];
X
X if (af_sortset (set, AF_ATTHUMAN) == -1)
X vctl_abort ("do_chmod: af_sortset()");
X
X for (i = 0; i < set->af_nkeys; i++) {
X mkvstring (version, &set->af_klist[i]);
X if (setjmp (ThisTransaction.tr_env)) continue;
X if (af_MY_rouid (&set->af_klist[i]) != (Uid_t)geteuid()) {
X (void)sprintf (buf, "%s not owned by %s.", version,
X uidname((Uid_t)geteuid()));
X logmsg (buf);
X errs++;
X continue;
X }
X else {
X if (af_chmod (&set->af_klist[i], newmode) < 0) {
X af_perror ("af_chmod");
X errs++;
X continue;
X }
X (void)sprintf (buf, "%s done.", version);
X logmsg (buf);
X }
X }
X if (errs)
X return 1;
X else
X return 0;
X}
X
Xint do_chown (set)
X Af_set *set;
X{
X int i;
X int errs = 0;
X char version[1024];
X
X if (af_sortset (set, AF_ATTHUMAN) == -1)
X vctl_abort ("do_chown: af_sortset()");
X
X for (i = 0; i < set->af_nkeys; i++) {
X mkvstring (version, &set->af_klist[i]);
X if (setjmp (ThisTransaction.tr_env)) continue;
X if (lockeruid (af_rowner (&set->af_klist[i])) != geteuid()) {
X (void)sprintf (buf, "%s not owned by %s.", version,
X uidname (geteuid()));
X logmsg (buf);
X errs++;
X continue;
X }
X else {
X logmsg ("This function is not available under BSD.");
X errs++;
X continue;
X }
X }
X if (errs)
X return 1;
X else
X return 0;
X}
X
Xint do_chaut (set)
X Af_set *set;
X{
X int i;
X int errs = 0;
X char version[1024];
X
X if (af_sortset (set, AF_ATTHUMAN) == -1)
X vctl_abort ("do_chaut: af_sortset()");
X
X for (i = 0; i < set->af_nkeys; i++) {
X mkvstring (version, &set->af_klist[i]);
X if (setjmp (ThisTransaction.tr_env)) continue;
X if (af_MY_rouid (&set->af_klist[i]) != (Uid_t)geteuid()) {
X (void)sprintf (buf, "%s not owned by %s.", version,
X uidname ((Uid_t)geteuid()));
X logmsg (buf);
X errs++;
X continue;
X }
X else {
X if (af_chauthor (&set->af_klist[i], &newauthor) < 0) {
X af_perror ("af_chaut");
X errs++;
X continue;
X }
X (void)sprintf (buf, "%s done.", version);
X logmsg (buf);
X }
X }
X if (errs)
X return 1;
X else
X return 0;
X}
X
X/**/
XDoReserve (ac, av)
X int ac;
X char **av;
X{
X Af_set set;
X int errs, errput = 0;
X char **erroneous;
X
X errs = GetKeysByGenRev (ac,av, AF_BUSYVERS, AF_BUSYVERS, &set,
X &erroneous);
X
X if (errs) {
X print_erroneous (erroneous, errs);
X errput++;
X }
X
X if (!set.af_nkeys && !errput) {
X logmsg ("Nothing appropriate found.");
X return 1;
X }
X
X if (errs && !ask_confirm ("Continue ?", "yes"))
X return 1;
X
X return do_reserve (&set);
X}
X
Xint do_unreserve (set)
X Af_set *set;
X{
X int i;
X Af_user *locker;
X int errs = 0;
X char version[1024];
X char *p;
X FILE *pip;
X
X if (af_sortset (set, AF_ATTHUMAN) == -1)
X vctl_abort ("do_promote: af_sortset()");
X for (i = 0; i < set->af_nkeys; i++) {
X mkvstring (version, &set->af_klist[i]);
X if (setjmp (ThisTransaction.tr_env)) continue;
X /* if (locking == AF_GLOBALLOCK) { /* to be implemented */
X if (p=rindex(version, '[')) *p = '\0';
X if (!locked(locker = af_testlock (&set->af_klist[i], AF_GLOBALLOCK))) {
X (void)sprintf (buf, "%s unlocked.", version);
X logmsg (buf);
X continue;
X }
X if (lockeruid (locker) == geteuid()) {
X (void)vc_unlock_g(&set->af_klist[i]);
X (void)sprintf (buf, "%s unlocked.", version);
X logmsg (buf);
X continue;
X }
X else { /* locked by somebody else */
X /* The following is an evil hack. BSD doesn't allow chmod(2)
X * for ordinary user processes.
X */
X if (af_MY_rouid (&set->af_klist[i]) == geteuid()) {
X /* we've got the power ... */
X (void)sprintf (buf, "%s currently locked by %s. Break the lock ?", version,
X lockerid (locker));
X if (ask_confirm (buf, "yes")) {
X if (vc_unlock_g(&set->af_klist[i]) == NULL) {
X af_perror ("af_unlock");
X continue;
X }
X (void)sprintf (buf, MAIL, version, uidname(geteuid()));
X (void)strcat (buf, lockerid (locker));
X if ((pip = popen (buf, "w")) == NULL) {
X logmsg ("WARNING: couldn't notify lockholder...");
X }
X else {
X fprintf (pip, "This message was issued automatically by ");
X fprintf (pip, "the version control system.\n");
X fprintf (pip, "Your lock on %s was broken by %s.\n",
X version, uidname(geteuid()));
X (void)pclose (pip);
X }
X (void)sprintf (buf, "%s unlocked.", version);
X logmsg (buf);
X continue;
X }
X else { /* we don't wanna break the lock */
X (void)sprintf (buf, "%s remains locked by %s.", version,
X lockerid (locker));
X logmsg (buf);
X continue;
X }
X }
X else { /* we cannot unlock the required version */
X (void)sprintf (buf, "%s is locked by %s.", version, lockerid (locker));
X logmsg (buf);
X errs++;
X continue;
X }
X }
X }
X if (errs)
X return 1;
X else
X return 0;
X}
X
X/**/
XDoUnreserve (ac, av)
X int ac;
X char **av;
X{
X Af_set set;
X int errs;
X char **erroneous;
X
X errs = GetKeysByGenRev (ac,av, AF_BUSYVERS, AF_BUSYVERS, &set,
X &(erroneous));
X
X if (errs)
X print_erroneous (erroneous, errs);
X
X if (!set.af_nkeys) {
X logmsg ("Nothing appropriate found.");
X return 1;
X }
X
X if (errs && !ask_confirm ("Continue ?", "yes"))
X return 1;
X
X return do_unreserve (&set);
X}
X
XDoChmod (vlist, ac, av)
X struct vc_vlist *vlist;
X int ac;
X char **av;
X{
X Af_set set;
X int errs;
X char **erroneous;
X
X if (IsOptionSet(Vopt_version)) {
X errs = GetKeysByGenRev
X (ac,av, gen(def_vnum), rev(def_vnum), &set, &erroneous);
X }
X else {
X if (!(vlist->from_version_set) || !(vlist->to_version_set))
X errs = GetKeysByGenRev
X (ac,av, AF_BUSYVERS, AF_BUSYVERS, &set, &erroneous);
X else
X errs = GetKeysByName ( ac, av, vlist, &set, &erroneous);
X }
X if (errs)
X print_erroneous (erroneous, errs);
X
X if (!set.af_nkeys) {
X logmsg ("Nothing appropriate found.");
X return 1;
X }
X
X if (errs && !ask_confirm ("Continue ?", "yes"))
X return 1;
X
X return do_chmod (&set);
X}
X
XDoChown (ac, av)
X int ac;
X char **av;
X{
X Af_set set;
X int errs;
X char **erroneous;
X
X errs = GetKeysByGenRev (ac,av, AF_BUSYVERS, AF_BUSYVERS, &set,
X &erroneous);
X
X if (errs)
X print_erroneous (erroneous, errs);
X
X if (!set.af_nkeys) {
X logmsg ("Nothing appropriate found.");
X return 1;
X }
X
X if (errs && !ask_confirm ("Continue ?", "yes"))
X return 1;
X
X return do_chown (&set);
X}
X
XDoChaut (vlist, ac, av)
X struct vc_vlist *vlist;
X int ac;
X char **av;
X{
X Af_set set;
X int errs;
X char **erroneous;
X
X if (IsOptionSet(Vopt_version)) {
X errs = GetKeysByGenRev
X (ac,av, gen(def_vnum), rev(def_vnum), &set, &erroneous);
X }
X else {
X if (!(vlist->from_version_set) || !(vlist->to_version_set))
X errs = GetKeysByGenRev
X (ac,av, AF_LASTVERS, AF_LASTVERS, &set, &erroneous);
X else
X errs = GetKeysByName ( ac, av, vlist, &set, &erroneous);
X }
X if (errs)
X print_erroneous (erroneous, errs);
X
X if (!set.af_nkeys) {
X logmsg ("Nothing appropriate found.");
X return 1;
X }
X
X if (errs && !ask_confirm ("Continue ?", "yes"))
X return 1;
X
X return do_chaut (&set);
X}
X
Xchar *mkfn (key) Af_key *key; {
X /* construct a unix (busy-)filename for object pointed to by key */
X static char name[128];
X char *n, *t;
X
X name[0] = '\0';
X t = af_rtype (key); t = *t ? t : NULL;
X (void)sprintf (name, "%s%s%s", n=af_rname (key), t ? "." : "", t ? t : "");
X free (n); free (t);
X return name;
X}
X
Xchar *uidname (uid) Uid_t uid; {
X struct passwd *pwent = getpwuid ((int)uid);
X char un[80];
X
X if (pwent == NULL) {
X (void)sprintf (un, "somebody (uid=%d)", uid);
X return un;
X }
X else return pwent->pw_name;
X}
X
END_OF_FILE
if test 12489 -ne `wc -c <'src/vc/vadm_reserve.c'`; then
echo shar: \"'src/vc/vadm_reserve.c'\" unpacked with wrong size!
fi
# end of 'src/vc/vadm_reserve.c'
fi
echo shar: End of archive 14 \(of 33\).
cp /dev/null ark14isdone
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