home *** CD-ROM | disk | FTP | other *** search
- Subject: v19i035: A software configuration management system, Part22/33
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Axel Mahler <unido!coma!axel>
- Posting-number: Volume 19, Issue 35
- Archive-name: shape/part22
-
-
-
- #! /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 22 (of 33)."
- # Contents: man/man1/vcintro.1 src/vc/vadm.c
- # Wrapped by rsalz@papaya.bbn.com on Thu Jun 1 19:27:14 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'man/man1/vcintro.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'man/man1/vcintro.1'\"
- else
- echo shar: Extracting \"'man/man1/vcintro.1'\" \(23895 characters\)
- sed "s/^X//" >'man/man1/vcintro.1' <<'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... $Header: vcintro.1[1.1] Thu Feb 23 18:14:37 1989 axel@coma published $
- X...
- X... Log for /u/shape/dist-tape/src/vc/vcintro.1[1.0]
- X... Thu Feb 23 18:14:37 1989 axel@coma published $
- X... --- empty log message ---
- X... vcintro.1[1.1] Thu Feb 23 18:14:37 1989 axel@coma published $
- X... --- empty log message ---
- X...
- X.UC
- X.TH VCINTRO 1 vcintro \n(dy.\n(mo.\n(yr
- X.SH NAME
- Xvcintro \- introduction to the version control system of the shape toolkit
- X.SH DESCRIPTION
- XThe version control commands of the shape toolkit are useful to manage
- Xmultiple revisions of \fIsource objects\fR (usually ASCII text files
- Xbut not limited to) as well as multiple instances of \fIderived
- Xobjects\fR (usually produced by compiling one ore more source
- Xobjects). The version control system allows the storing, retrieval,
- Xlogging, and identification of revisions. All objects are stored in an
- Xobject base that resides in a subdirectory with the name \fIAFS\fR.
- X.PP
- XConsequent use of version control is the prerequisite for
- Xconfiguration management and software maintenance. Using the version
- Xcontrol system also eases cooperation within a programmer team, and even
- Xsupports individual working styles, such as saving intermediate work
- Xresults that may be backed up to, if modifications turn out to be
- Xunsatisfying.
- X.PP
- XThe following introductory overview of shape's version control system
- Xuses a terminology that tries to be as intuitive as possible. However, as
- Xterminology is quite different from the well known notions of the UNIX
- Xfilesystem, you might eventually find yourself confused. If this is the
- Xcase, go to the end of this manual and read the section about the
- Xobject base and related terminology.
- X.PP
- XThe basic user interface consists of a number of simple commands.
- XThe novice user only needs to know three of them: \fBsave\fR, \fBretrv\fR,
- Xand \fBvl\fR. \fBsave\fR stores the contents of a specified
- Xfile as a \fIversion\fR in the object base. \fBretrv\fR, short for
- X\(lqretrieve\(rq, retrieves versions from the object base. \fBvl\fR,
- Xshort for \(lqversion list\(rq, lists the contents of the object base.
- XWhile these three commands may suffice to serve the needs of single-programmer
- Xprojects, shape's version control system also
- Xoffers more sophisticated support for larger projects that
- Xemploy programmer teams.
- X.PP
- X\fBFunctions of the version control system\fR
- X.IP \(bu 0.2i
- XStorage and retrieval of multiple revisions of design objects.
- XAll revisions are stored in a space efficient manner. Changes
- Xno longer destroy possibly worthwhile status of the original,
- Xbecause previous revisions remain accessible. Revisions can
- Xbe retrieved from the object base according to revision numbers,
- Xsymbolic names, states, and arbitrary attribute patterns.
- X.IP \(bu
- XBuilt in automatic status model for revisions. Each revision
- Xis in one of the states \fIbusy, saved, proposed, published, accessed, \fRor
- X\fIfrozen\fR, according to its quality and access status. State
- Xtransitions happen (semi-) automatically upon invocation of certain
- Xcommands (\fBsave\fR, \fBsbmt\fR, \fBaccpt\fR, \fBrjct\fR, \fBrelease\fR).
- XThis status model helps to organize larger, multi-programmer projects.
- X.IP \(bu
- XMaintenance of a complete history of changes. Besides the contents of each
- Xrevision, the version control system stores the author, date and time
- Xof the save operation, and a log message summarizing the changes as
- Xattributes of the newly created version object. The version control
- Xsystem distinguishes saving of intermediate work status and
- Xsubmitting final work results to the project. In the latter case,
- Xthe log message is initialized with the description of the planned
- Xchange which is acquired upon reservation of the update privilege for
- Xthe design object.
- X.IP \(bu
- XResolution of access conflicts. When two or more programmers whish
- Xto modify the same design object, the version control system
- Xalerts the programmers and prevents them from mutually corrupt each
- Xother's modifications.
- X.IP \(bu
- XComprehensive support for configuration control. Revisions can be
- Xassigned symbolic names that typically are shared among all component
- Xrevisions of a configuration. Moreover, the version control system
- Xis fully integrated with \fBshape\fR, the configuration identification
- Xand building tool.
- X.IP \(bu
- XAutomatic identification of each revision with name, version number,
- Xsave date, author etc. The identification is like a stamp that can
- Xbe embedded at an appropriate place in the contents of a design object.
- XThe identification makes it simple to determine which revisions have
- Xbeen included in a given configuration.
- X.sp 3p
- X.PP
- X\fBGetting started with the shape toolkit\fR
- X.PP
- XBefore you can use any of the version control facilities, you should
- Xcreate a subdirectory \fIAFS\fR in order to have an initial location
- Xfor the version object base.
- XNow, suppose you have a file \(lqxyzzy.c\(rq that you whish to put under version
- Xcontrol. To do this, just invoke the \fBsave\fR command
- X.DS
- X\fCsave xyzzy.c\fR
- X.DE
- XThis command creates an entry for \(lqxyzzy.c\(rq in the object base. Before
- Xthe first version of a design object is created, \fBsave\fR asks
- Xfor a short description of the object's purpose. This description
- Xshould be a synopsis of the contents. All later \fBsave\fR commands
- Xwill ask for a log, which should describe the changes that
- Xhave been made. If you issue the command \fBvl\fR, you should get
- Xsomething like
- X.DS
- X.nf
- X\fCxyzzy.c xyzzy.c[1.0]\fR
- X.fi
- X.DE
- Xindicating, that you now have a busy version and a
- Xrevision 1.1 of of \(lqxyzzy.c\(rq. After saving a revision of a file,
- Xone automatically owns a \fIlock\fR for the entire object history.
- XA locks represents the exclusive privilege to add new revisions
- Xto the object history. This makes sure that no other author in a project
- Xyou are working on, can interfere with your work.
- X.PP
- XYou may retrieve revisions from the object base with the \fBretrv\fR command.
- X.DS
- X\fCretrv xyzzy.c\fR
- X.DE
- Xfetches the latest revision of \(lqxyzzy.c\(rq from the object base
- Xand installs it in the current working directory. As this operation
- Xmight overwrite a current busy version, \fBretrv\fR asks for permission
- Xto do so. In case you just want to have a look at the saved revision
- Xwithout overwriting the busy version you should rather type
- X.DS
- X\fCvcat xyzzy.c\fR
- X.DE
- Xthan invoke \fBretrv\fR. The \fBvcat\fR command simply prints the
- Xcontents of the revision on the screen (standard output). As is the
- Xcase with \fBvl\fR, this command also tries to resemble regular UNIX
- Xcommands that do similar things.
- X.PP
- XJust retrieving a revision from the object base is not sufficient
- Xif you whish to modify that revision and save it back into the
- Xobject base at a later time. Precisely, \fBretrv\fR in its plain
- Xform doesn't set a lock on the object history, which is necessary
- Xin order to add a new revision to it. Accordingly, the access
- Xmode of the file containing the retrived revision is set to \fIread only\fR.
- XIf you whish to create a new revision on the basis of some saved
- Xversion in the object base, you should retrieve it with
- X.DS
- X\fCretrv -lock xyzzy.c\fR
- X.DE
- XIf \(lqxyzzy.c\(rqs object history is not locked by anybody else,
- X\fBretrv\fR will ask for a description of the changes you plan to
- Xmake, and installs the retrieved revision as busy version in the
- Xdirectory containing the object base (this is necessary to keep
- Xthe defined relationship between the busy version and the corresponding
- Xobject history). It may happen from time to time that you applied
- Xchanges to a (supposedly) busy version of a design object without
- Xholding a lock for it. In this case you probably don't want your
- Xchanges to be overwritten by a newly installed busy version created
- Xby \fCretrv -lock\fR. Instead, invoke
- X.DS
- X\fCvadm -lock xyzzy.c\fR
- X.DE
- XThis command tries to set the necessary lock subsequently. If, however,
- Xsome other author has locked the object history in the meantime, you
- Xare in limbo. To get out of this dilemma is only possible by using
- Xhuman interaction. Locking assures that you, and only you, can save
- Xthe next update of a design object, and avoids nasty problems if
- Xseveral people are working on the same project, possibly on the same
- Xdesign object. Even if an object history is locked, revisions can
- Xstill be retrieved for reading, compiling etc. All that locking
- Xprevents is a save operation by anybody but the locker.
- X.PP
- X\fBvadm\fR is a general purpose command, used to manipulate the
- Xversion object base in various ways. If any of the simpler commands
- X(\fBsave\fR, \fBretrv\fR, and \fBvl\fR) can't serve a particular need
- Xthat you might have in mind (delete revisions, change the state or
- Xother attributes of a revision, modify logentries etc.),
- X\fBvadm\fR probably can. Check the manual pages for details.
- X.PP
- XAfter having used version control commands for a while, you might
- Xhave quite a lot of revisions in each object history. The \fBvl\fR
- Xcommand might print something like
- X.DS
- X.nf
- X\fCefg.c fgh.c fgh.c[1.3] xyz.c[1.1]
- Xefg.c[1.0] fgh.c[1.0] fgh.c[1.4] xyz.c[1.2]
- Xefg.c[1.1] fgh.c[1.1] xyz.c xyzzy.c
- Xefg.c[1.2] fgh.c[1.2] xyz.c[1.0] xyzzy.c[1.0]\fR
- X.fi
- X.DE
- XWhile most version control commands by default access the most recent revision
- Xit is possible to reference any revision by explicitly specifying
- Xits respective revision number. This can be done in either of two
- Xways, common to all version control commands. The command option
- X\fI-V<version>\fR specifies an explicit default revision number.
- XFor example, the command:
- X.DS
- X.nf
- X\fCvl -l -V 1.2
- X.fi
- X.DE
- Xprints more detailed information about revision 1.2 of all object
- Xhistories:
- X.DS
- X.nf
- X\fC-rw-r--r-- s axel@coma 437 Nov 2 01:21:46 1988 efg.c[1.2]
- X-rw-r--r-- P axel@coma 1027 Oct 26 22:04:33 1988 fgh.c[1.2]
- X-rw-r--r-- s axel@coma 731 Nov 1 02:01:34 1988 xyz.c[1.2]\fR
- X.fi
- X.DE
- XThe other notational convention understood by all version control
- Xcommands is the \fIbound version notation\fR. The revision number
- Xis simply specified as an extension to the object name, enclosed
- Xin brackets. For example, the command:
- X.DS
- X\fCvl -l efg.c[1.2] fgh.c[1.1] xyz.c[1.3] xyzzy.c[1.0]\fR
- X.DE
- Xprints
- X.DS
- X.nf
- X\fC-rw-r--r-- s axel@coma 437 Nov 2 01:21:46 1988 efg.c[1.2]
- X-rw-r--r-- s axel@coma 726 Oct 26 22:04:30 1988 fgh.c[1.1]
- X-rw-r--r-- s axel@coma 727 Nov 1 02:25:51 1988 xyz.c[1.3]
- X-rw-r--r-- s axel@coma 391 Nov 8 19:21:11 1988 xyzzy.c[1.0]\fR
- X.fi
- X.DE
- XThe long format of the version list command is similar to ls(1)
- Xlong format file information. The information printed in this
- Xformat is (from left to right): file
- X\fIaccess permissions\fR of the busy version (when saved), revision
- X\fIstatus\fR (b = busy, s = saved, p = proposed, P = published, a = accessed,
- Xf = frozen), network userid of the \fIowner\fR of the object history,
- Xoriginal \fIsize\fR of the revision (revsions are actually
- Xstored as differences to the previous revision), \fIdate
- Xand time\fR when the revision was saved, and \fIname\fR, \fItype\fR
- X(represented as name suffix), \fIgeneration-\fR, and \fIrevision number\fR
- X(to either side of the dot). All these informations are examples for
- Xindividual \fIattributes\fR of version objects. Many other
- Xattributes are stored for each version object that can be examined
- Xby \fBvl\fR. Check the manual for details.
- X.PP
- XKeeping track of \fIconfigurations\fR, composed of particular versions
- Xmany different objects, is easy with the shapetools version control
- Xsystem. While the ultimate tool to create, maintain, and
- Xoperate with configurations within this toolkit is \- of course \-
- Xthe \fBshape\fR program, the version control system allows to
- Xassociate different objects in a configuration, and is able to
- Xreinstall a given configuration from the object base. Saving a simple
- Xconfiguration, consisting of all the current instances of the
- Xbusy versions can be done by invoking
- X.DS
- X\fCsave -n conf1 efg.c fgh.c xyz.c xyzzy.c -m "versions work together"\fR
- X.DE
- XProvided all necessary locks are (or can be) set \fBsave\fR will
- Xprint something like:
- X.DS
- X.nf
- X\fCefg.c:
- Xsaved version 1.3
- Xfgh.c:
- Xsaved version 1.5
- Xxyz.c:
- Xsaved version 1.4
- Xxyzzy.c:
- Xsaved version 1.1
- Xdone.\fR
- X.fi
- X.DE
- XEach newly created version is assigned the name of the configuration
- Xas \fIsymbolic name\fR attribute (\fB\-n\fR option). The text
- Xsupplied with the \fB\-m\fR (short for \fImessage\fR) is taken
- Xas logentry for the evolving versions, so \fBsave\fR won't prompt
- Xfor a descriptive log. The specified symbolic name is an \fIalias\fR
- Xfor the version number. No single symbolic name may be assigned to more
- Xthan one version in an object history. A single version may be
- Xassigned any number of symbolic names, however.
- XThe elements of the configuration just saved may be identified any
- Xtime, for example by invoking
- X.DS
- X\fCvl -l -n conf1\fR
- X.DE
- Xresulting in the following version list:
- X.DS
- X.nf
- X\fC-rw-r--r-- s axel@coma 302 Nov 8 23:31:15 1988 efg.c[1.3]
- X-rw-r--r-- s axel@coma 2060 Nov 8 23:31:17 1988 fgh.c[1.5]
- X-rw-r--r-- s axel@coma 1089 Nov 8 23:31:20 1988 xyz.c[1.4]
- X-rw-r--r-- s axel@coma 749 Nov 8 23:32:24 1988 xyzzy.c[1.1]\fR
- X.fi
- X.DE
- XThe symbolic name of a version may be used anyplace where a version
- Xnumber might be used. So, an entire configuration can be reinstalled
- Xwith the command:
- X.DS
- X\fCretrv -V conf1 efg.c fgh.c xyz.c xyzzy.c
- X.DE
- X.PP
- X\fBIdentification of object code
- X.PP
- XIt is good practice to insert a piece of information into
- Xthe source code of program modules that will allow to identify the
- Xsource object versions, a given piece of object code has been
- Xcompiled from. In C programs for example, such a piece of information typically
- Xlooks sort of
- X.DS
- X\fCstatic char *RCSID = "$Header: vcintro.1,v 3.0 88/11/09 23:12:21 axel Exp $";\fR
- X.DE
- Xor
- X.DS
- X\fCstatic char *SCCSID = "@(#)xyzzy.c 1.2 8/11/88";\fR
- X.DE
- XThe two examples displayed above show the standard identification string
- Xformat used by the \fIRCS\fR and \fISCCS\fR source control systems
- Xrespectively. The cryptic character sequences serve as magic cookies
- Xfor special identification programs which extract tehese strings
- Xfrom the compiled objects or executable programs (\fBident\fR and \fBwhat\fR).
- Xshape's version control system has some special support for this kind
- Xof code identification. If you insert the line
- X.DS
- X\fCstatic char *AFSID = "$\&__Header$";\fR
- X.DE
- Xin the source of the program modules, the version control system will
- Xexpand this expression into
- X.DS
- X\fCstatic char *AFSID=
- X "$Header: vcintro.1,v 3.0 88/11/09 23:12:21 axel Exp $";\fR
- X.DE
- Xallowing to identify compiled objects with the \fBident\fR command.
- XThe sequence \fC$_\&_Header$\fR is an \fIattribute citation expression\fR.
- XWhen a version is retrieved from the object base, attribute citations are
- X\fIsubstituted\fR by the value of the cited attribute. In the given example,
- Xthe magic string \fI$_\&_\fR indicates the (possible) beginning of an
- Xattribute citation. The string that immediately follows the citation
- Xmarker is taken to be the \fIname of an attribute\fR of the version
- Xobject under consideration. Each object in the object base has a
- Xnumber of standard attributes and may additionally have
- Xany number of so called \fIuser defined attributes\fR attributes (see
- Xbelow). A \(lq$\(rq charakter or white space immediately following
- Xthe attribute name delimits an attribute citation. If no attribute with
- Xthe specified name is associated with an object version, the whole
- Xcitation will be ignored, i.e. treated as ordinary text.
- X.PP
- X\(lqHeader\(rq is one of two \fIpseudo attributes\fR that each version
- Xobject has in addition to its regular attributes. While \(lqHeader\(rq
- Xexpands into a string that displays a number of a version's attributes
- Xall at once (\fIname, type, version, savedate, author, \fRand\fI state\fR),
- Xthe \(lqLog\(rq pseudo-attribute pops in the complete log history
- Xof the respective version. This is useful to add some kind of development
- Xdocumentation to a particular version. To prevent the inserted log text
- Xfrom causing syntax errors, each inserted line is preceded by a
- X\fIcomment leader\fR symbol, which is stored in another attribute. In
- Xorder to use this feature properly, the comment leader symbol must
- Xbe explicitly set for each design object that has a syntax requiring
- Xcomments to be marked. For C language objects, this can be done with
- X.DS
- X\fCvadm -setc " * " xyzzy.c\fR
- X.DE
- XIt is a good idea to use a utility program, such as \fBafsit\fR,
- Xto insert proper object identification and log attributes automatically.
- XThe lines that \fBafsit\fR adds to C files look like
- X.DS
- X\fCstatic char *AFSid = "$Header: vcintro.1[1.1] Thu Feb 23 18:14:37 1989 axel@coma published $";
- X
- X/*
- X * Log for /u/shape/dist-tape/src/vc/vcintro.1[1.0]
- X... Thu Feb 23 18:14:37 1989 axel@coma published $
- X... --- empty log message ---
- X... vcintro.1[1.1] Thu Feb 23 18:14:37 1989 axel@coma published $
- X... --- empty log message ---
- X */\fR
- X.DE
- X.sp 5p
- X\fBSetting up a project\fR
- X.PP
- XThe shape toolkit is very useful for organizing programming projects
- Xemploying programmer teams. The version control system's \fIlocking
- Xmechanism\fR makes it easy to prevent problems with concurring updates
- Xof the same design objects. If a programmer plans to modify an object
- Xhe reserves the \fIupdate privilege\fR by setting a lock on this object.
- XHaving done this, no other programmer is allowed to save any modifications
- Xinto the object base. Locks should, however, be used with care. Locking
- Xall object histories without having a serious intention of modifying
- Xthem, may prevent the other team members from doing their work. The
- Xversion control system provides means for resolving deadlock situations
- Xwhen objects are locked and the lockholder is not present to give up
- Xthe lock when somebody else needs it.
- X.PP
- XWithin a project, there are three basic roles that a programmer
- Xmay play in respect to a design object: \fIowner\fR of the entire
- Xdesign object (i.e. all of its versions), \fIauthor\fR of a particular
- Xversion, and \fIlocker\fR of the object history. All three roles
- Xmay be played by different people for each design object. The network
- Xuserids of the people who play these roles are recorded as attributes
- Xof each version object in the object base.
- X.PP
- XThe following project organzation pattern has proven to be useful
- Xfor medium sized programming projects.
- X.IP 1)
- XCreate a designated userid to be the \fIproject owner\fR. The project
- Xowner will be the owner of all design objects that are part of the project.
- XCreate a special entry for the project, the \fIproject group\fR
- Xin the \fI/etc/group\fR file.
- XThe central object base for a project will be installed as an AFS
- Xsubdirectory in the project owners homedirectory. The AFS directory
- Xshould have the group ID of the project group, and be made
- Xgroup-writable.
- XThe project owner's home directory
- Xwill also be referred to as \fIproject home\fR. The project home should
- Xbe the \fIintegration area\fR, i.e. the place, where the \fIpublished\fR
- Xwork results of the various team members are collected and integrated
- Xinto the product that is subject of the project.
- X.IP 2)
- XAll programmers who are member of the project team should create
- Xa special directory that is dedicated to the project. In this directory,
- Xthere should be a \fIsymbolic link\fR, called AFS, that points to the
- XAFS subdirectory in the project home. By using this mechanism, all
- Xteam members \fIshare\fR the same object base. It should be made sure
- Xthat each team member \- also called \fIauthor\fR \- is member of
- Xthe project group (the UNIX group). This is necessary in order to
- Xgrant all authors write access to the object base.
- X.PP
- XIn a project setup of this kind, the status attribute of version
- Xobjetcs begins to have real meaning. \fIsaved\fR means that a possibly
- Xintermediate version of the object was created as (kind of) backup.
- X\fIproposed\fR means that a version is in a \fIresult\fR state and
- Xproposed by the author to be assigned official status. \fIpublished\fR
- Xmeans, that a version has public status, indicating that it might
- Xand should be used by the other authors. In the current version
- Xof the shapetools, state transitions are managed informally. No special
- X\fImanagement permission\fR is necessary to promote a particular version
- Xfrom one state to another. It is also possible, that authors access
- Xversions of other authors that have an unpublished status.
- X.PP
- XAccessing and selecting particular versions in a dynamic but
- Xwell controlled and organized fashion is best be done with the
- X\fBshape\fR tool. Basic version control can only supply the very
- Xbasic means for sophisticated technical project support. Particular
- Xmanagement policies for projects require more effort. However, the
- Xproposed scheme has been proven to work well for medium sized projects.
- XUnfortunately, this particular scheme can only be realized on BSD type
- Xsystems, as the System V derivates of UNIX mostly don't support symbolic
- Xlinks, and also have a different group permission philosophy.
- X.PP
- X.sp 5p
- X\fBThe object base and related terminology
- X.PP
- XThe principal structures in the object base are \fIobject
- Xhistories\fR, \fIindividual objects\fR (also called \fIobject
- Xversions\fR), and \fIderived objects\fR. An object history is a set of
- Xsubsequent revisions of a \fIconceptual object\fR (e.g. program
- Xmodule, documentation, graphics, paper etc.) that result from
- Xrepeatedly saving the contents of a conceptual object's \fIbusy
- Xversion\fR. The busy version is a regular UNIX file that can be
- Xmanipulated by any program that operates on files (editors, compilers,
- Xformatters etc.). Unlike the busy version, object versions are immutable.
- XObject histories are represented in a space efficient manner that only
- Xkeeps the \fIdifferences\fR between two adjacent versions (\fIdeltas\fR).
- X
- XEach object in the object base is a complex of \fIcontents\fR and
- Xassociated \fIattributes\fR. Attributes are the usual file attributes
- X(of the busy version) known from the filesystem (e.g. name, type, size,
- Xowner, access privileges etc.) plus any number of arbitrary \fIuser
- Xdefined attributes\fR of the form \fI<name>=<value>\fR, where \fIname\fR
- Xis a single word (no whithespace) and \fIvalue\fR can be any string
- Xthat does not contain control-A characters (\'\\01\').
- X
- X\fIDerived objects\fR reside in a part of the object base which is
- Xcalled \fIderived object pool\fR. The derived object pool serves to
- Xmaintain multiple instances of compiled objects in parallel that
- Xresult \- for instance \- from compiling different versions of the
- Xsame conceptual object. The derived object pool has a fixed size
- Xand is administered as a cache. The size of a binary pool is 64 by default
- Xbut may be set via the environment variable \fIAFSBPSIZ\fR. A good
- Xestimate for the derived object pool size is two times the number
- Xof the compilable source objects.
- END_OF_FILE
- if test 23895 -ne `wc -c <'man/man1/vcintro.1'`; then
- echo shar: \"'man/man1/vcintro.1'\" unpacked with wrong size!
- fi
- # end of 'man/man1/vcintro.1'
- fi
- if test -f 'src/vc/vadm.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/vc/vadm.c'\"
- else
- echo shar: Extracting \"'src/vc/vadm.c'\" \(22191 characters\)
- sed "s/^X//" >'src/vc/vadm.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.c[3.12] Thu Feb 23 18:14:05 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.c[3.6]
- X * Thu Feb 23 18:14:05 1989 axel@coma published $
- X * --- empty log message ---
- X * vadm.c[3.9] Thu Feb 23 18:14:05 1989 axel@coma published $
- X * --- empty log message ---
- X * vadm.c[3.10] Thu Feb 23 18:14:05 1989 axel@coma save $
- X * --- empty log message ---
- X * vadm.c[3.11] Thu Feb 23 18:14:05 1989 axel@coma save $
- X * --- empty log message ---
- X * vadm.c[3.12] Thu Feb 23 18:14:05 1989 axel@coma published $
- X * --- empty log message ---
- X */
- X
- X#include <pwd.h>
- X#include <stdio.h>
- X#include <signal.h>
- X#include <strings.h>
- X
- X#include "afs.h"
- X#include "afsapp.h"
- X#include "vadm.h"
- X#include "ParseArgs.h"
- X
- Xextern char *malloc();
- X
- X/* forward declarations */
- X/*
- X * Options (e.g. -V, -from, or -to) and actions (-delete, -set, etc.)
- X * are parse at the same time by calling function ParseArgs().
- X */
- X
- X/* option */
- Xextern int handle_binary_option ();
- Xextern int handle_help_option (); /* handler for option -h */
- Xextern int handle_version_option (); /* handler for -V option */
- Xextern int handle_from_option (); /* handler for -from option */
- Xextern int handle_to_option (); /* handler for -to option */
- Xextern int handle_no_option (); /* handler for -no option */
- Xextern int handle_quiet_option ();
- Xextern int handle_R_option ();
- Xchar debug_on = 0;
- Xextern int handle_d_option ();
- X
- X/* actions */
- Xextern int handle_reserve_action ();
- Xextern int handle_unreserve_action ();
- Xextern int handle_symname_action ();
- Xextern int handle_setc_action ();
- Xextern int handle_delete_action ();
- Xextern int handle_promote_action ();
- Xextern int handle_unpromote_action ();
- Xextern int handle_change_action ();
- Xextern int handle_lock_action ();
- Xextern int handle_unlock_action ();
- Xextern int handle_chmod_action ();
- Xextern int handle_chown_action ();
- Xextern int handle_chaut_action ();
- Xextern int handle_set_action ();
- Xextern int handle_setuda_action ();
- Xextern int handle_unsetuda_action ();
- Xextern int handle_setattrs_action ();
- X
- X/* Global variables */
- XOptDesc argdesc[] = { /* known options,actions and its handler */
- X { "version", OPT_IS_SWITCH, handle_R_option },
- X { "b", OPT_IS_SWITCH, handle_binary_option },
- X { "h", OPT_HAS_OPT_ARG, handle_help_option },
- X { "V", OPT_HAS_ARG, handle_version_option},
- X { "from", OPT_HAS_ARG, handle_from_option },
- X { "to", OPT_HAS_ARG, handle_to_option },
- X { "no", OPT_HAS_ARG, handle_no_option },
- X { "q", OPT_IS_SWITCH, handle_quiet_option },
- X { "debug", OPT_IS_SWITCH, handle_d_option },
- X { "reserve", OPT_IS_SWITCH, handle_reserve_action},
- X { "unreserve", OPT_IS_SWITCH, handle_unreserve_action},
- X { "symbolic", OPT_HAS_ARG, handle_symname_action},
- X { "setc", OPT_HAS_ARG, handle_setc_action},
- X { "delete", OPT_IS_SWITCH, handle_delete_action},
- X { "promote", OPT_IS_SWITCH, handle_promote_action },
- X { "unpromote", OPT_IS_SWITCH, handle_unpromote_action },
- X { "lock", OPT_IS_SWITCH, handle_lock_action },
- X { "unlock", OPT_IS_SWITCH, handle_unlock_action },
- X { "chmod", OPT_HAS_ARG, handle_chmod_action },
- X { "chown", OPT_HAS_ARG, handle_chown_action },
- X { "chaut", OPT_HAS_ARG, handle_chaut_action },
- X { "set", OPT_HAS_ARG, handle_set_action },
- X { "setuda", OPT_HAS_ARG, handle_setuda_action },
- X { "unsetuda", OPT_HAS_ARG, handle_unsetuda_action },
- X { "setattrs", OPT_HAS_ARG, handle_setattrs_action },
- X { "change", OPT_HAS_ARG, handle_change_action },
- X { (char *) NULL, NULL, NULL }
- X};
- X
- Xunsigned int options = 0; /* given options */
- Xunsigned int actions = 0; /* given actions */
- Xchar *progname; /* program's name */
- Xstruct vc_vlist *vlist = (struct vc_vlist*) NULL;
- X /* versions to be processed */
- Xstruct vc_vlist *vcur = (struct vc_vlist*) NULL;
- Xint def_vnum;
- Xint to_option_pending = 0; /* if -from is given, -to is expected later */
- Xint from_option_pending = 0; /* if -to is given before any -from, -from is
- X * pending. If -to is followed by -V, any
- X * from-pending is rejected.*/
- Xchar *symname = NULL; /* symbolic name -symname arg */
- Xchar *csym = NULL; /* comment leader symbol */
- Xint newmode;
- XAf_user newauthor; /* arguments of the resp. actions */
- Xchar *TakeFromFile = NULL; /* Filename, where uda-val will be taken
- X from (see handle_setuda_action) */
- Xchar Attrfile[128]; /* Name of file where attribute definitions
- X will be taken from */
- Xchar udaname[AF_UDANAMLEN]; /* Name of uda to be set */
- Xchar udaval[256]; /* String val to which udaname will be set */
- Xstruct Transaction ThisTransaction;
- Xstatic char buf[100];
- Xchar **environment;
- Xjmp_buf here;
- X
- X/**/
- Xmain (ac, av, ev)
- X int ac;
- X char **av, **ev;
- X{
- X int nac; /* ac after parsing */
- X char **nav, *cp; /* av after parsing */
- X int retcode = 0; /* return value */
- X register int i, j;
- X
- X progname = (cp = rindex (av[0], '/')) ? ++cp : av[0];
- X /* make prog-name available to entire program */
- X environment = ev; /* */
- X CatchSigs();
- X if (setjmp (ThisTransaction.tr_env)) return 1;
- X InitVcontrol ();
- X if (ParseArgs (ac, av, &nac, &nav, argdesc)) {
- X (void)sprintf (buf, "BTW, try \"%s -h\" for more information or rtfm.",
- X progname);
- X logmsg (buf);
- X exit (1); /* error detected */
- X }
- X /* Look for identical arguments -- zero out twins */
- X for ( i = 0; i < nac; i++)
- X for (j = i+1; j < nac; j++)
- X if (!strcmp (nav[i], nav[j])) nav[j][0] = '\0';
- X
- X if (debug_on)
- X DumpVlist ();
- X
- X if (!nac) {
- X if (actions) /* if an action is given */
- X logmsg ("Filenames missing.");
- X else
- X logmsg ("An action and filenames missing.");
- X
- X ShortUsage ();
- X exit (1);
- X }
- X
- X if (!ActionsPlausible ()) exit (1); /* no chance to do anything */
- X
- X switch (actions) {
- X case Varg_set_note:
- X retcode = DoSetNote (vlist, nac, nav);
- X break;
- X case Varg_change_note:
- X retcode = DoChangeNote (vlist, nac, nav);
- X break;
- X case Varg_set_description:
- X retcode = DoSetDescription (vlist, nac, nav);
- X break;
- X case Varg_change_description:
- X retcode = DoChangeDescription (vlist, nac, nav);
- X break;
- X case Varg_set_intent:
- X retcode = DoSetIntent (nac, nav);
- X break;
- X case Varg_setc_symbol:
- X retcode = DoSetCommentSymbol (nac, nav, csym);
- X break;
- X case Varg_delete:
- X retcode = DoDelete (vlist, nac, nav);
- X break;
- X case Varg_promote:
- X retcode = DoPromote (vlist, nac, nav);
- X break;
- X case Varg_unpromote:
- X retcode = DoUnpromote (vlist, nac, nav);
- X break;
- X case Varg_lock:
- X case Varg_reserve:
- X retcode = DoReserve (nac, nav);
- X break;
- X case Varg_unlock:
- X case Varg_unreserve:
- X retcode = DoUnreserve (nac, nav);
- X break;
- X case Varg_chmod:
- X retcode = DoChmod (vlist, nac, nav);
- X break;
- X case Varg_chown:
- X retcode = DoChown (nac, nav);
- X break;
- X case Varg_chaut:
- X retcode = DoChaut (vlist, nac, nav);
- X break;
- X case Varg_symname:
- X retcode = DoSymname (vlist, nac, nav, symname);
- X break;
- X case Varg_setuda:
- X retcode = DoSetUda (vlist, nac, nav);
- X break;
- X case Varg_unsetuda:
- X retcode =DoUnsetUda (vlist, nac, nav);
- X break;
- X case Varg_setattrs:
- X retcode = DoSetAttrs (vlist, nac, nav);
- X break;
- X default:
- X logerr ("Ooops, You have requested more than one action.\
- X Please try again");
- X logmsg ("with only *one* action at a time.");
- X retcode = 1;
- X break;
- X }
- X
- X if (retcode)
- X logmsg ("terminated.");
- X else
- X logmsg ("done.");
- X return (retcode);
- X}
- X
- X/**/
- Xint ActionsPlausible ()
- X{
- X if (actions) {
- X return 1;
- X }
- X else {
- X logmsg ("Action missing.");
- X ShortUsage ();
- X return 0;
- X }
- X}
- X
- X/**/
- Xint InitVcontrol ()
- X{
- X if ((vlist = (struct vc_vlist*) malloc (sizeof (struct vc_vlist))) == NULL) {
- X vctl_abort ("malloc vc_vlist");
- X }
- X
- X vlist->from_version_set = vlist->to_version_set = NULL;
- X vlist->from_generation = NULL;
- X vlist->from_revision = NULL;
- X vlist->to_generation = NULL;
- X vlist->to_revision = NULL;
- X
- X vlist->next = NULL;
- X vcur = vlist;
- X}
- X
- X/**************************
- X * Action handlers *
- X *************************/
- X/**/
- X/*ARGSUSED*/
- Xint handle_reserve_action (act, arg)
- X char *act, *arg;
- X{
- X if (IsOptionSet (Vopt_binary)) {
- X logerr ("Can't reserve or unreserve binary.");
- X exit (1);
- X }
- X SetAction(Varg_reserve); /* macro */
- X if (IsActionSet(Varg_unreserve)) {
- X logerr ("You already mentioned \"unreserve\", so what do you want ?");
- X return 1;
- X }
- X return 0;
- X}
- X
- X/*ARGSUSED*/
- Xint handle_unreserve_action (act, arg)
- X char *act, *arg;
- X{
- X if (IsOptionSet (Vopt_binary)) {
- X logerr ("Can't reserve or unreserve binary.");
- X exit (1);
- X }
- X SetAction(Varg_unreserve);
- X if (IsActionSet(Varg_reserve)) {
- X logerr ("You already mentioned \"reserve\", so what do you want ?");
- X return 1;
- X }
- X return 0;
- X}
- X
- X/*ARGSUSED*/
- Xint handle_symname_action (act, arg)
- X char *act, *arg;
- X{
- X SetAction(Varg_symname);
- X symname = arg;
- X return 0;
- X}
- X
- X/*ARGSUSED*/
- Xint handle_setc_action (act, arg)
- X char *act, *arg;
- X{
- X csym = arg;
- X if (strlen (csym) > (CLEADMAXLEN-(strlen(CLEAD)+2))) {
- X logerr ("Specified comment leader symbol is too long");
- X return 1;
- X }
- X SetAction(Varg_setc_symbol);
- X return 0;
- X}
- X
- X/*ARGSUSED*/
- Xint handle_delete_action (act, arg)
- X char *act, *arg;
- X{
- X SetAction(Varg_delete);
- X return 0;
- X}
- X
- X/*ARGSUSED*/
- Xint handle_promote_action (act, arg)
- X char *act, *arg;
- X{
- X if (IsOptionSet (Vopt_binary)) {
- X logerr ("Can't promote status of binary.");
- X exit (1);
- X }
- X SetAction(Varg_promote);
- X if (IsActionSet(Varg_unpromote)) {
- X logerr ("You already mentioned \"unpromote\", so what do you want ?");
- X return 1;
- X }
- X return 0;
- X}
- X
- X/*ARGSUSED*/
- Xint handle_unpromote_action (act, arg)
- X char *act, *arg;
- X{
- X if (IsOptionSet (Vopt_binary)) {
- X logerr ("Can't unpromote status of binary.");
- X exit (1);
- X }
- X SetAction(Varg_unpromote);
- X if (IsActionSet(Varg_promote)) {
- X logerr ("You already mentioned \"promote\", so what do you want ?");
- X return 1;
- X }
- X return 0;
- X}
- X
- X/*ARGSUSED*/
- Xint handle_change_action (act, arg)
- X char *act, *arg;
- X{
- X char messg[80];
- X if (IsOptionSet (Vopt_binary)) {
- X (void)sprintf (messg, "Can't change %s of binaries. Sorry.",
- X arg ? arg : "note or description" );
- X logerr (messg);
- X exit (1);
- X }
- X if (!strcmp (arg, "note")) {
- X SetAction(Varg_change_note);
- X return 0;
- X }
- X if (!strcmp (arg, "description")) {
- X SetAction(Varg_change_description);
- X return 0;
- X }
- X logerr ("Change what, eh? - Note or description?");
- X return 1;
- X}
- X
- X/*ARGSUSED*/
- Xint handle_lock_action (act, arg) char *act, *arg; {
- X if (IsOptionSet (Vopt_binary)) {
- X logerr ("Can't lock or unlock binary.");
- X exit (1);
- X }
- X if (IsActionSet (Varg_unlock)) {
- X logerr ("Can't lock and unlock at the same time.");
- X exit (1);
- X }
- X SetAction (Varg_lock);
- X return 0;
- X}
- X
- X/*ARGSUSED*/
- Xint handle_unlock_action (act, arg) char *act, *arg; {
- X if (IsOptionSet (Vopt_binary)) {
- X logerr ("Can't lock or unlock binary.");
- X exit (1);
- X }
- X if (IsActionSet (Varg_lock)) {
- X logerr ("Can't lock and unlock at the same time.");
- X exit (1);
- X }
- X SetAction (Varg_unlock);
- X return 0;
- X}
- X
- X/*ARGSUSED*/
- Xint handle_chmod_action (act, arg) char *act, *arg; {
- X register int mode = 0;
- X char messg[80], ciph, err = 0;
- X register char *cp = arg;
- X
- X if (strlen (arg) > 4) err++;
- X else
- X while (ciph = *cp++) {
- X ciph -= '0';
- X if ((ciph > 7) || (ciph < 0)) err++;
- X else {
- X mode <<= 3;
- X mode += ciph;
- X }
- X }
- X if (err) {
- X (void)sprintf (messg, "invalid mode \"%s\".", arg);
- X logerr (messg);
- X exit (1);
- X }
- X SetAction (Varg_chmod);
- X newmode = mode;
- X return 0;
- X}
- X
- X/*ARGSUSED*/
- Xint handle_chown_action (act, arg) char *act, *arg; {
- X char messg[80];
- X
- X if (IsOptionSet (Vopt_binary)) {
- X logerr ("Can't change owner of binary.");
- X exit (1);
- X }
- X if (getpwnam (arg) == NULL) {
- X (void)sprintf (messg, "%s is not a valid userid on this machine.", arg);
- X logerr (messg);
- X exit (1);
- X }
- X SetAction (Varg_chown);
- X/* newowner = opw->pw_uid; */
- X return 0;
- X}
- X
- X/*ARGSUSED*/
- Xint handle_chaut_action (act, arg) char *act, *arg; {
- X char messg[80], hostname[MAXHOSTNAMELEN];
- X
- X if (IsOptionSet (Vopt_binary)) {
- X logerr ("Can't change author of binary.");
- X exit (1);
- X }
- X if (getpwnam (arg) == NULL ) {
- X (void)sprintf (messg, "%s is not a valid userid on this machine.", arg);
- X logerr (messg);
- X exit (1);
- X }
- X SetAction (Varg_chaut);
- X (void) strcpy (newauthor.af_username, arg);
- X (void) gethostname (hostname, MAXHOSTNAMELEN);
- X (void) strcpy (newauthor.af_userhost, hostname);
- X return 0;
- X}
- X
- X/*ARGSUSED*/
- Xint handle_setuda_action (act, arg) char *act, *arg; {
- X char *cp;
- X register int i;
- X
- X if (cp=index(arg, '=')) {
- X if (arg == cp) { /* No attribute name */
- X logerr ("No attribute name given");
- X exit (1);
- X }
- X if (*(cp+1) == '@') { /* the attribute value will be taken from file */
- X TakeFromFile = malloc (128);
- X if (TakeFromFile == NULL) {
- X logerr ("Can't allocate memory for filename");
- X exit (1);
- X }
- X (void)sscanf (cp+1, "@%s", TakeFromFile); /* ignore evtly. trailing junk */
- X if (TakeFromFile ? TakeFromFile[0] ? 0 : 1 : 1) {
- X /* condition holds if no filename specified */
- X TakeFromFile = NULL;
- X (void)strcpy (udaval, "@");
- X }
- X }
- X else { /* attribute value will be taken literally */
- X (void)strcpy (udaval, cp+1);
- X for (i=0; udaval[i]; i++) {
- X if (udaval[i] == 1) { /* cntl-A not allowed */
- X logerr ("Invalid char (cntl-A) in attribute value");
- X exit (1);
- X }
- X }
- X }
- X if ((cp-arg) > AF_UDANAMLEN) {
- X logerr ("Attributename too long");
- X exit (1);
- X }
- X (void)strncpy (udaname, arg, cp-arg);
- X udaname[cp-arg] = '\0';
- X SetAction (Varg_setuda);
- X }
- X else { /* No '=' in arg */
- X logerr ("Illegal format of attribute expression");
- X exit (1);
- X }
- X return 0; /* OK */
- X}
- X
- X/*ARGSUSED*/
- Xint handle_unsetuda_action (act, arg)
- X char *act, *arg; {
- X (void)strcpy (udaname, arg);
- X SetAction (Varg_unsetuda);
- X return 0;
- X }
- X
- X/*ARGSUSED*/
- Xint handle_setattrs_action (act, arg)
- X char *act, *arg; {
- X
- X SetAction (Varg_setattrs);
- X (void)strcpy (Attrfile, arg);
- X return 0;
- X }
- X
- X/*ARGSUSED*/
- Xint handle_set_action (act, arg)
- X char *act, *arg;
- X{
- X char messg[80];
- X
- X if (IsOptionSet (Vopt_binary)) {
- X (void)sprintf (messg, "Can't set %s on binaries. Sorry.",
- X arg ? arg : "note or description" );
- X logerr (messg);
- X exit (1);
- X }
- X if (!strcmp (arg, "note")) {
- X SetAction(Varg_set_note);
- X return 0;
- X }
- X if (!strcmp (arg, "description")) {
- X SetAction(Varg_set_description);
- X return 0;
- X }
- X if (!strcmp (arg, "intent")) {
- X SetAction(Varg_set_intent);
- X return 0;
- X }
- X logerr ("Set what, eh? - note, description, or intent ?");
- X return 1;
- X}
- X
- X/**************************
- X * Option handlers *
- X *************************/
- X
- X/*ARGSUSED*/
- Xint handle_binary_option (opt, arg) char *opt, *arg; {
- X if (IsActionSet (Varg_reserve | Varg_unreserve | Varg_promote |
- X Varg_unpromote | Varg_change_note |
- X Varg_change_description | Varg_set_description |
- X Varg_set_note | Varg_lock | Varg_unlock | Varg_chown |
- X Varg_chaut)) {
- X logerr ("This action request is not supported for binaries.");
- X exit (1);
- X }
- X SetOption (Vopt_binary);
- X return 0;
- X}
- X
- X#ifdef NEVER_SET_THIS
- Xint handle_version_option (opt, arg)
- X char *opt, *arg;
- X{
- X struct vc_vlist *vtmp;
- X int generation = 0, revision = 0;
- X
- X if ((vcur->from_version_set) || (vcur->to_version_set)) {
- X /* if any -to num pending, report error */
- X if (to_option_pending) {
- X (void)sprintf (buf, "\"-to <version number>\" expected. Got \"-%s %s\"",
- X opt, arg);
- X logerr (buf);
- X return 1;
- X }
- X
- X if (from_option_pending) {
- X from_option_pending = 0; /* vctl -to 3.4 -from 5.6 -to 6.7 */
- X /* means: from 1.0 to 3.4 and from 5.6 to */
- X /* 6.7 */
- X }
- X if ((vtmp = (struct vc_vlist*)malloc (sizeof (struct vc_vlist))) == NULL)
- X vctl_abort ("malloc,2 vc_vlist");
- X
- X vcur->next = vtmp;
- X vcur = vtmp;
- X }
- X
- X generation = GetGenerationNumber (arg);
- X revision = GetRevisionNumber (arg);
- X
- X vcur->from_generation = generation;
- X vcur->from_revision = revision;
- X vcur->to_generation = generation;
- X vcur->to_revision = revision;
- X vcur->from_version_set = vcur->to_version_set = 1;
- X vcur->next = NULL;
- X
- X if ((revision < 0) || (generation <= 0)) {
- X (void)sprintf (buf, "%s version number %s.",
- X *arg ? "bad" : "missing",
- X *arg ? arg : "");
- X logerr (buf);
- X return 1;
- X }
- X return 0;
- X}
- X#endif
- X
- X/*ARGSUSED*/
- Xint handle_version_option (opt, arg)
- X char *opt, *arg;
- X{
- X def_vnum = mkvno (arg);
- X if (IsOptionSet(Vopt_version) ||
- X (vlist->from_generation + vlist->to_generation) ) {
- X logerr ("Set only one default version or version range.");
- X return 1;
- X }
- X SetOption(Vopt_version);
- X return 0;
- X}
- X
- X/**/
- Xint handle_from_option (opt, arg)
- X char *opt, *arg;
- X{
- X struct vc_vlist *vtmp;
- X
- X if (IsOptionSet(Vopt_version)) {
- X logerr ("Set only one default version or version range.");
- X return 1;
- X }
- X if (vcur->from_version_set) { /* need a new entry in vlist */
- X if ((vtmp = (struct vc_vlist*)malloc (sizeof (struct vc_vlist))) == NULL)
- X vctl_abort ("malloc,3 vc_vlist");
- X
- X vcur->next = vtmp;
- X vcur = vtmp;
- X vcur->to_generation = vcur->to_revision = NULL;
- X vcur->to_version_set = NULL;
- X vcur->next = NULL;
- X }
- X
- X vcur->from_version_set = 1;
- X vcur->from_generation = GetGenerationNumber (arg);
- X vcur->from_revision = GetRevisionNumber (arg);
- X
- X if (to_option_pending) {
- X (void)sprintf (buf, "\"-to <version number>\" expected. Got \"-%s %s\"",
- X opt, arg);
- X logerr (buf);
- X return 1;
- X }
- X else {
- X if (!from_option_pending)
- X /* e.g.: -to is followed by -from then no -to is pending */
- X to_option_pending++;
- X }
- X
- X if ((vcur->from_revision < 0) || (vcur->from_generation <= 0)) {
- X (void)sprintf (buf, "%s version number %s.",
- X *arg ? "bad" : "missing",
- X *arg ? arg : "");
- X logerr (buf);
- X return 1;
- X }
- X
- X from_option_pending = 0;
- X return 0;
- X}
- X
- X/**/
- Xint handle_to_option (opt, arg)
- X char *opt, *arg;
- X{
- X struct vc_vlist *vtmp;
- X
- X if (IsOptionSet(Vopt_version)) {
- X logerr ("Set only one default version or version range.");
- X return 1;
- X }
- X if (vcur->to_version_set) {
- X if ((vtmp = (struct vc_vlist*) malloc (sizeof (struct vc_vlist))) == NULL)
- X vctl_abort ("malloc,4 vc_vlist");
- X
- X vcur->next = vtmp;
- X vcur = vtmp;
- X vcur->from_generation = vcur->from_revision = NULL;
- X vcur->from_version_set = NULL;
- X vcur->next = NULL;
- X }
- X
- X vcur->to_generation = GetGenerationNumber (arg);
- X vcur->to_revision = GetRevisionNumber (arg);
- X vcur->to_version_set = 1;
- X
- X if (from_option_pending) {
- X (void)sprintf (buf, "\"-from <version number>\" expected. Got \"-%s %s\"",
- X opt, arg);
- X logerr (buf);
- X return 1;
- X }
- X else {
- X if (!to_option_pending) /* -to followd by -from then no -from is
- X * pending */
- X from_option_pending++;
- X }
- X
- Xif ((vcur->to_revision < 0) || (vcur->to_generation <= 0)) {
- X (void)sprintf (buf, "%s version number %s.",
- X *arg ? "bad" : "missing",
- X *arg ? arg : "");
- X logerr (buf);
- X return 1;
- X }
- X
- X to_option_pending = 0;
- X return 0;
- X}
- X
- X/**/
- Xint handle_no_option (opt, arg)
- X char *opt, *arg;
- X{
- X if (*arg) {
- X if (!strcmp ("confirm", arg)) {
- X SetOption(Vopt_no_confirm);
- X return 0;
- X }
- X else {
- X (void)sprintf (buf, "Hmmm, I don't know that. What's up with \"-%s %s\"?", opt, arg);
- X logerr (buf);
- X return 1;
- X }
- X }
- X else {
- X (void)sprintf (buf, "Hey You, please tell me more about \"-%s\".\
- X That sounds familiar to me.", opt);
- X logerr (buf);
- X return 1;
- X }
- X}
- X
- X/*ARGSUSED*/
- Xint handle_quiet_option (o, a) char *o, *a; {
- X SetOption(Vopt_quiet);
- X return 0;
- X}
- X
- X/**/
- XShortUsage ()
- X{
- X pa_ShortUsage (progname, argdesc, "files ...");
- X}
- X
- X/*ARGSUSED*/
- Xint handle_help_option (opt, arg)
- X char *opt, *arg;
- X{
- X if (*arg) {
- X logerr ("long help not yet implemented.");
- X }
- X else {
- X ShortUsage ();
- X }
- X
- X exit (1); /* no way to proceed */
- X}
- X
- X/*ARGSUSED*/
- Xhandle_R_option (o, a) char *o, *a; {
- X extern char *version();
- X
- X printf ("This is %s version %s.\n", progname, version ());
- X printf ("AFS version %s.\n", af_version());
- X exit (0);
- X}
- X
- X/**/
- Xvctl_abort (message)
- X char *message;
- X{
- X perror (message);
- X exit (1);
- X}
- X
- X/*ARGSUSED*/
- Xint handle_d_option (opt, arg)
- X char *opt, *arg;
- X{
- X debug_on++;
- X}
- X
- XDumpVlist ()
- X{
- X struct vc_vlist *vtmp;
- X int f_gen, f_rev, t_gen, t_rev;
- X
- X for (vtmp = vlist; vtmp; vtmp = vtmp->next) {
- X f_gen = vtmp->from_generation;
- X f_rev = vtmp->from_revision;
- X t_gen = vtmp->to_generation;
- X t_rev = vtmp->to_revision;
- X
- X if ( (f_gen == t_gen) && (f_rev == f_rev))
- X fprintf (stderr, "-V%d.%d\n", f_gen, f_rev);
- X else
- X fprintf (stderr, "-from %d.%d -to %d.%d\n", f_gen, f_rev, t_gen, t_rev);
- X }
- X}
- X
- END_OF_FILE
- if test 22191 -ne `wc -c <'src/vc/vadm.c'`; then
- echo shar: \"'src/vc/vadm.c'\" unpacked with wrong size!
- fi
- # end of 'src/vc/vadm.c'
- fi
- echo shar: End of archive 22 \(of 33\).
- cp /dev/null ark22isdone
- 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
-