rsalz@uunet.uu.net (Rich Salz) (06/05/89)
Submitted-by: Axel Mahler <unido!coma!axel> Posting-number: Volume 19, Issue 30 Archive-name: shape/part17 #! /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 17 (of 33)." # Contents: man/man1/vadm.1 man/man3/afintro.3 src/vc/dosave.c # Wrapped by rsalz@papaya.bbn.com on Thu Jun 1 19:27:09 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'man/man1/vadm.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'man/man1/vadm.1'\" else echo shar: Extracting \"'man/man1/vadm.1'\" \(16429 characters\) sed "s/^X//" >'man/man1/vadm.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: vadm.1[3.3] Thu Feb 23 18:14:02 1989 axel@coma published $ X... X... Log for /u/shape/dist-tape/src/vc/vadm.1[3.1] X... Thu Feb 23 18:14:02 1989 axel@coma published $ X... --- empty log message --- X... vadm.1[3.2] Thu Feb 23 18:14:03 1989 axel@coma published $ X... --- empty log message --- X... vadm.1[3.3] Thu Feb 23 18:14:03 1989 axel@coma published $ X... --- empty log message --- X... X.UC X.TH VADM 1 vadm \n(dy.\n(mo.\n(yr X.SH NAME Xvadm \- manipulate and administer version object base X.SH SYNOPSIS X\fBvadm\fR [\ \fIoptions\fR\ ]\ [\ \fIversion\ range\fR\ ]\ [\ \fIaction\fR\ ] name\|.\|. X.SH DESCRIPTION X.PP X\fBvadm\fR is a general purpose command to perform all sorts of Xactions upon parts of an AFS object base. It can be used to lock or unlock Xan AFS object, to reserve (or unreserve) an object for modification, to Xdelete a particular object instance, to associate symbolic names with Xversion objects, to promote or unpromote certain version objects from Xone status to another, to modify an object's access permissions, to set or Xmodify a descriptive entry of particular version objects, to set or Xmodify an eventual change intention, and to set Xor unset various object attributes such as the author or any user Xdefined attributes. X.PP XThe typical command invocation is supplemented by one or more X\fIcommand options\fR, a \fIversion range\fR usually defining a Xrange of object instances to be acted upon, an \fIaction specifier\fR Xindicating the sort of action to be performed, and a set of \fIobject Xnames\fR defining the initial subset of the object base that's going Xto be manipulated. X.PP XObject names may be given in \fIbound version notation\fR, Xi.e. a notation that identifies a particular version of an object (e.g. X\fCmkattr.c[2.4]\fR). It is also possible to use a previously assigned X\fIsymbolic name\fR rather than a numerical Xversion identification (e.g. \fCmkattr.c[tools-V4R3]\fR). Make sure Xto escape the bracket-symbols as these usually have meaning to the Xshell. X.PP XThe following \fIoptions\fR are recognized: X.IP "\fB\-version\fR" \w'\fB\-version++\fR'u Xprint version information about the \fBvadm\fR program itself. No action Xwill be performed on the database. X.IP "\fB\-b\fR" Xapply the requested operation to objects residing in the \fIbinary pool\fR. XThe set of actions that may be performed on binary pool objects is limited. X.IP "\fB\-h\fR" Xprint brief instructions about using \fBvadm\fR X.IP "\fB\-q\fR" Xsuppress any prompts, informal messages and user dialogues. Default Xvalues are assumed for everything that might otherwise be inquired Xinteractively. This option is useful for batch operation. X.in -0.25i X.PP X\fBvadm\fR will perform all of its operations upon a specified set of XAFS version objects. In case no such set is specified, the operation Xwill be applied to the most recently saved versions of the named Xobject(s). A particular version can be identified by specifying its X\fIversionnumber\fR or a previously assigned \fIsymbolic name\fR Xthrough the \fB\-V\fI<version>\fR argument. A \fIrange\fR of versions can Xbe defined through use of the \fB\-from\fI<versionnumber>\fR and X\fB\-to\fI<versionnumber>\fR arguments. The specified range X\fIincludes\fR the given margin versions. Use of either version range Xspecification form (\fB\-V \fR or \fB\-from/\-to\fR) excludes the Xother form. X.PP XThe kind of operation to be performed upon a specified set of AFS Xobjects is indicated by a keyword. The following actions are defined: X.in +0.25i X.IP "\fB\-lock\fR" \w'\fB\-unpromote++\fR'u Xtries to reserve the privilege to add a new version to an objects Xhistory, thus preventing multiple programmers working upon the same Xobject base from interfering with each other by saving concurrent updates. XThis simple mechanism is for use in small development projects, that do X\fInot\fR employ the scheme of private, experimental archives for each Xparticipating programmer, and one centralized \fIproject library\fR where Xindividual work results are collected. XWhen setting a new lock on an object history, the requesting user Xis prompted for an optional description of the planned changes. XSee also \fB\-reserve\fR. X.RS X.PP XIn order to lock an object history successfully, the history must not Xbe locked by any other programmer, and the programmer requesting the Xlock must have write permission on the AFS subdirectory hosting the Xobject base. X.PP XThis option is not available for objects in binary pools. X.RE X.IP "\fB\-unlock\fR" Xgives up the previously reserved privilege to update the history of an XAFS object. \fB\-unlock\fR may be used by the \fIowner\fR of an object Xhistory to \fIbreak a lock\fR previously set by any programmer. This Xoption is useful to resolve deadlock situations resulting from careless Xuse of \fB\-lock\fR, or exceptional circumstances that require immediate Xupdating of an object history, even if the lockholder is not present. XThe previous owner of a broken lock is notified by a Xmail message. An eventually expressed change intention (see \fB\-lock\fR) Xwill be cleared. X.RS X.PP XTechnically, the owner of an object's history is the owner of the XAFS subdirectory hosting the object base. X.PP XThis option is not available for objects in binary pools. X.RE X.IP "\fB\-reserve\fR" Xtries to reserve a version object from a centrally maintained project Xlibrary in order to use it as starting point for the development of Xa new entry in the objct's history. In fact, \fB\-reserve\fR does nothing Xelse but eventually copy the specified version object from the Xproject library to the programmer's workspace, and set a lock on the Xobject's history in the project library. XWhen setting a new lock on an object history, the requesting user Xis prompted for an optional description of the planned changes. XSee also \fB\-lock\fR. X.RS X.PP XAs with the \fB\-lock\fR request, an object's history must not be reserved Xby any other programmer, and the requesting programmer must have permission Xto do so. X.PP XTo communicate with the project library, the reserve command either accesses Xa distant object base directory, or connects to a local (unix domain) or Xremote (internet domain) \fIlibrary server\fR. The place where a project's Xcentral library resides is identified by an entry in a projects database. XThis database is either \fI~/af_projects\fR or a default file such Xas \fI/usr/local/lib/af_projects\fR. The name of the project a requesting Xprogrammer is currently working on should be defined in the programmer's Xshell environment by the \fIAF_PROJECT\fR variable. X.PP XThis command is currently not implemented. X.PP XThis option is not available for objects in binary pools. X.RE X.IP "\fB\-unreserve\fR" Xcancels a previously issued \fB\-reserve\fR request. As with the X\fB\-lock\fR request, \fB\-unreserve\fR can be used by the \fIlibrary Xadministrator\fR to forcefully cancel an update reservation by any Xprogrammer. Programmers who are subject to forced cancellations will Xbe notified by a mail message. X.RS X.PP XThis command is currently not implemented. X.PP XThis option is not available for objects in binary pools. X.RE X.IP "\fB\-delete\fR" Xremoves the specified version objects from the object base, provided Xthe objects' status is \fIsaved\fR. Any other status indicates that Xsome kind of project interaction concerning this object might be in Xprogress. If the programmer wants to delete such a version object Xanyway, he has to \fB\-unpromote\fR the respective object's status to X\fIsaved\fR before it can actually be deleted. X.IP "\fB\-symbolic\fI\ <uniquename>" Xassigns the name \fIuniquename\fR to the specified version. The symbolic Xname works as an alias for the version number, so it must be different Xfrom any other symbolic name assigned to any version object in a particular Xobject history. It is, however, possible to assign the same symbolic Xname to version objects in \fIdifferent object histories\fR. An object Xhistory is usually denoted by a name, similarly to a file's name. X.RS X.PP XThe use of symbolic names is a simple but effective way to associate component Xmembers of a \fIsystem configuration\fR. Typical symbolic names will Xlook something like \fIMysystem_Release_4.22(vax)\fR, indicating that Xversion objects with this name are part of release 4.22 of the system Xin question. X.RE X.IP "\fB\-promote\fR" Xassigns the next-higher value to the specified objects' \fIstate\fR attribute. XThere are six states that an object instance can be in: \fIbusy, saved, Xproposed, published, accessed, \fRand\fI frozen\fR. Version states are Xintended to relate to visibility and operational restrictions (see for Xexample \fB\-delete\fR) within a complex project environment. X.RS X.PP XDue to the current lack of project library support, the version states Xhave very little actual functionality. Implemented to its full extent, Xcertain state transitions may only be triggered by appropriately Xauthorized users. The transitions \fIbusy\(->saved\fR and X\fIsaved\(->proposed\fR will be triggered by regular programmers, whereas Xthe remaining transitions have to be initiated by the \fIproject Xadministrator\fR. X.PP XEach transition corresponds to a specific action or interaction within Xa general software project communication scheme. As these actions/interactions Xwill be functionally supported by the project support system currently Xunder development, the explicit manipulation of object states will no Xlonger be necessary (except, perhaps for manual adjusting of ill situations). X.PP XThe following actions relate to the state transitions: X.IP "\fIsave\fR" X(\fIbusy\(->saved\fR, performed by programmer) X.IP "\fIsbmt\fR" X(\fIsaved\(->proposed\fR, performed by programmer) X.IP "\fIunsbmt\fR" X(\fIproposed\(->saved\fR, performed by programmer) X.IP "\fIaccpt\fR" X(\fIproposed\(->published\fR, performed by project administrator) X.IP "\fIrject\fR" X(\fIproposed\(->proposed\fR, performed by project administrator) X.IP "\fIaccs\fR" X(\fIpublished\(->accessed\fR, performed by any project member) X.IP "\fIrelease\fR" X(\fIaccessed\(->frozen\fR, performed by project administrator) X.PP XThis option is not available for objects in binary pools. X.RE X.IP "\fB\-unpromote\fR" Xreverses a state transition carried out through a prior \fB\-promote\fR. XThe same remarks about functional embedding (and thus \fIhiding\fR Xthe state transitions) of state transitions made for \fB\-promote\fR Xhold for \fB\-unpromote\fR. X.RS X.PP XThis option is not available for objects in binary pools. X.RE X.IP "\fB\-chmod \fI<mode>\fR" Xchanges the access permission code of the specified version objects to Xthe supplied three-octal-digit \fImode\fR. Currently, the access Xpermissions are centered around UNIX' notions of \fIowner, group,\fR and X\fIworld\fR Xaccess as well as the access categories \fIread, write,\fR and \fIexecute\fR. XThese Xpermissions are inherited upon \fBsave\fR from the permissions of the Xfile representing the \fIbusy object\fR of an AFS history. See X\fBchmod\fR(2) for details. X.IP "\fB\-chown \fI<user>\fR" Xsets \fIuser\fR the owner of an entire object history. This option Xis not supported on BSD type systems, as only the superuser may Xchange the owner of a file. X.IP "\fB\-chaut \fI<user>\fR" Xsets \fIuser\fR the author of a particular revision. Normally, the Xauthor of a revision is considered the user who \fIsaved\fR or \fIsubmitted\fR Xthat revision. However, as certain permissions are tied to the author Xattribute of a revision, circumstances may occur that make it necessary Xto change the author. X.IP "\fB\-set \fR[\fIdescription \fR| \fInote\fR | \fIintent\fR]" Xallows to set or modify the \fIdescriptive text\fR for an AFS history object X(i.e. an entire version history), the \fInote\fR usually describing the Xdifferences of a version object with respect to its preceding version, or Xan entry describing a planned change. X(Re-) setting the change intention may be appropriate, if a previously Xset change intent has been consumed by a \fBsbmt\fR command that Xretained the lock on an object history. X.RS X.nr Ii \n(.i X.PP X\fBvadm\fR will check the caller's environment for the \fIEDITOR\fR Xvariable and invoke the program identified therein. If the \fIEDITOR\fR Xvariable is not set, the system's default editor will be activated. XThe user may write an arbitrary length descriptive or note entry using Xthe editor. When the user leaves the editor, the resulting text is Xstored with the object history or the specified version objects. X.PP XThis option is not available for objects in binary pools. X.RE X.PP X\fB\-setc\fI\ commentstring\fR X.nr Ci \n(.i X.in \n(Iiu Xsets \fIcommentstring\fR as the (sequence of) character(s) that opens a Xcommentline within the formalism of the document. XThis commentstring will be prepended to the lines of the log history Xwhen the \fC$__log$\fR attribute is expanded within the text of a revision. X.PP X\fB\-setuda\fI <attrname=\fR[\fI@\fR]\fIstring>\fR X.nr Ci \n(.i X.in \n(Iiu Xsets the user defined attribute \fIattrname\fR to the value \fIstring\fR Xfor all specified version objects. If the first character of \fIstring\fR Xis an at-sign, the rest of \fIstring\fR is taken to be the \fIname of a file\fR Xthe contents of which will be taken as the value of the attribute. User Xdefined attributes may be of arbitrary length. Any sequence of ASCII Xcharacters \- with the exception of \e01 (control-A) \- is allowed to make Xup an attribute value. X.sp \n()Pu XIf \fIattrname\fR was already set to some value, the previous value Xwill be replaced by the newly specified one. X.in \n(Ciu X.IP "\fB\-unsetuda\fI <attrname>\fR" \w'\fB\-unpromote++\fR'u Xdeletes the user defined attribute \fIattrname\fR from the set of attributes Xassociated with the specified version objects. X.IP "\fB\-setattrs\fI <filename>\fR" Xreads names and values of user defined attributes from the file \fIfilename\fR. XThe entries in the attribute file are of the form \fINAME=VALUE\fR. \fINAME\fR Xmust be an alphanumeric string (no spaces) imediately followed by the equal Xsign. The value may be an arbitrary ASCII string with the exception of Xcontrol-A and newline characters. There is exactly one attribute definition Xper line. The file's last character must be a newline character. X.RS X.PP XThis way to attach attributes was introduced to allow quick attachment Xof a large number of attributes to version objects. This is \fInot\fR Xthe primary user interface for doing this. Unfortunately, \fBvadm\fR Xreacts ungracefully if the described convention is not followed. X.PP XPreviously assigned values of user defined attributes are overridden by Xthe values defined in the attributefile. X.RE X.SH SEE ALSO Xsave(1), retrv(1), rsrv(1), sbmt(1), vl(1), shape(1), Xaf_intro(3), af_archive(5) X.PP XRecommended reading: A. Mahler, A. Lampen, \fI\(lqAn Integrated XToolkit for Engineering Software Configurations\(rq\fR, Proceedings of Xthe ACM SIGSOFT/SIGPLAN Software Engineering Symposium on Practical XSoftware Development Environments, November 1988, Boston Mass. (to Xbe published). X.SH BUGS XI'm afraid that there might be quite a lot of flaws around. Consistent Xhandling of permissions is an especially error prone subject. Please report Xany bugs to the authors. X.SH AUTHOR XUli Pralle and Axel Mahler X.br XTechnical University Berlin X.sp X\fIUUCP:\fR axel@coma.uucp (unido!coma!axel) X.br X uli@coma.uucp (unido!coma!uli) X.br X\fIBITNET:\fR axel@db0tui62 X.br X uli@db0tui62 X END_OF_FILE if test 16429 -ne `wc -c <'man/man1/vadm.1'`; then echo shar: \"'man/man1/vadm.1'\" unpacked with wrong size! fi # end of 'man/man1/vadm.1' fi if test -f 'man/man3/afintro.3' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'man/man3/afintro.3'\" else echo shar: Extracting \"'man/man3/afintro.3'\" \(16204 characters\) sed "s/^X//" >'man/man3/afintro.3' <<'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.TH AF_INTRO 3 "" \n(dy.\n(mo.\n(yr X.SH NAME Xaf_intro \(em introduction to AFS library functions and error codes X.SH SYNOPSIS X#include <afs.h> X.SH DESCRIPTION XThe following manual pages (named AF_*) describe the library functions Xof the \fIAttribute Filesystem\fR (AFS). X.PP XAFS is an extension to the \s-1UNIX\s+1 Xfilesystem interface that allows the storage of files as complex of Xcontent data and an arbitrary number of associated attributes. XThese are called \fIattributed software objects\fR (ASOs). XAFS has a built-in version Xcontrol system that manages \fIlines of development\fR. A line of Xdevelopment consists of a \fIbusy object\fR and a number of saved Xversions. The busy object is an ordinary alterable \s-1UNIX\s+1 file. XIt can be accessed via AFS \fIand\fR \s-1UNIX\s+1 Xfilesytem operations. Versions come Xinto being by making a copy of the current state of the busy object. XThey can be stored as source objects or as derived objects. X.PP XSource objects are typically composed manually (e.g. by use of a text Xeditor). AFS stores source objects as immutable objects. Once saved, Xthey cannot be modified any longer. Saved ASOs are stored in archive Xfiles (like SCCS and RCS). AFS maintains two archive files for each Xline of development of source objects \- one holding the attributes Xand the other holding the data. Normally, archives are stored in a Xsubdirectory called AFS (see \fIaf_setarchpath\fR for an exception to Xthis rule). To save disk space, the versions in an archive are stored Xas deltas (differences to the previous version). X.PP XDerived objects Xare typically derived automatically (e.g. by a compiler) from a source Xobject and thus be reproducible at any time. They are kept in a X\fIderived object pool\fR (or \fIbinary pool\fR), Xa data store of limited size that is Xadministered in a cache fashion. The oldest (access date) derived Xobjects get removed if space runs short in the derived object pool. XDerived objects are stored physically unchanged. The attributes for Xderived objects are stored in a \fIndbm\fR database residing in the XAFS subdirectory. The maximum number of objects stored in a binary pool Xcan be given by setting the environment variable AFSBPSIZ to the Xappropriate value (default is 64). X.PP XAFS makes no assumptions Xwhether a copy of a busy object shall be stored as source object or as Xderived object. The application has to decide that by calling the Xappropriate function (see \fIAF_VERSIONS\fR). X.PP XThe main datatypes for AFS applications are: X.IP \(bu 0.2i XThe \fIobject key\fR that uniquely Xidentifies a software object. The structure of this type can be Xdifferent in different implementations of AFS. Consequently, Xapplication programs should handle this type as opaque type and should Xnot access single fields. X.IP \(bu X\fISet descriptors\fR represent a Xset of object keys. A set descriptor contains information about the Xnumber of keys in the set and a pointer to a list of object keys (see X\fIAF_SETS\fR). X.IP \(bu XAn \fIAttribute buffer\fR is capable to hold Xall attributes of a software object (standard attributes and user Xdefined attributes). Attribute buffers have two different purposes. XFirst, they can hold a retrieve pattern, i.e. they may be (partially) Xfilled with \fIdesired\fR attribute values and then be passed as Xargument to a retrieve operation (\fIAF_RETRIEVE\fR). Second, an Xattribute buffer is used to return all attributes of an identified ASO Xon demand (see \fIAF_ATTRS\fR). X.RE X.PP XMost of the AFS calls have Xone or more error returns. An error is indicated by a return value Xthat is either \-1 or a nil pointer, depending on the type of the Xfunction. If one of the functions returns with an error, the variable X\fIaf_errno\fR is set to indicate the appropriate error number. X\fIAf_errno\fR is not cleared upon successful calls. X.bp X.PP XThe following is a complete collection of the error numbers Xdefined in \fIafs.h\fR. The first list contains return values Xindicating \(lqnormal\(rq errors like unplausible arguments passed to Xan AFS function or permission problems. The error codes listed in the Xsecond list point to serious trouble, which can either be an internal Xerror in AFS or a corrupted archive file. The occurrence of an Xserious problem is recorded in an error protocol X(\fI/usr/adm/AFSerrlog\fR). On machines without \fIsyslog (3)\fR Xfacility, the error protocol is located in a \fI/tmp/AFSerrlog\fR. X.IP " -2 AF_ESYSERR Error during execution of syslib-command or syscall" XA called syslib function or syscall returned with an error Xcondition. See \fIerrno\fR for a more precise error specification. X.IP " -3 AF_EACCES permission denied" XAn attempt was made to perform Xan operation (e.g. open a file) without appropriate permissions. X.IP " -4 AF_EARCHANGED archive file has changed since last read" XOne of the archive files you are operating on has been modified Xby another process since your process has read it from disk. XIn this case, AFS refuses to store your changes because this would Xdestroy the modifications made by the other process. XIn order to make your desired changes happen, you have to rerun Xyour application. X.IP " -5 AF_EARLOCKED archive file is locked for writing" XAnother process is currently writing one of the archive files Xyou are operating on. Try again later. X.IP " -6 AF_EBPFULL no additional space in derived object pool" XThe AFS is Xunable to delete an old object from a derived object pool in order to Xget space for a new one. This error occurs if the concerning derived Xobject pool is full and all objects stored in this derived object pools Xare accessed by the current application. Use \fIaf_dropkey\fR or X\fIaf_dropset\fR to release one or more derived objects. X.IP " -7 AF_EBUSY Specified ASO must not be a busy version" XSome AFS-operations (eg. \fIaf_snote\fR, \fIaf_svnum\fR) cannot be Xperformed on ASOs which have the state \fIAF_BUSY\fR. X.IP " -8 AF_EDERIVED Specified ASO must not be a derived object" XSome AFS-operations (eg. \fIaf_lock\fR, \fIaf_newgen\fR) cannot be Xperformed on ASOs stored in derived object pools. X.IP " -9 AF_EFORMAT illegal format of udattr string" XUser defined attributes must have the form \fIname[=value]\fR. XSee af_udas (3) for further details. X.IP "-10 AF_EINVKEY invalid object key" XAn invalid object key (eg. nil pointer) was passed to an AFS-function. X.IP "-11 AF_EINVSET invalid set descriptor" XAn invalid set descriptor (eg. nil pointer) was passed to an AFS-function. X.IP "-12 AF_EINVUSER invalid user" XAn invalid user name was passed to an AFS-operation. X.IP "-13 AF_EINVVNUM Bad version number" XAn attempt was made to set a version number, that Xcontradicts the AFS version numbering philosophy, to an ASO. XYou cannot change the version number of an ASO into a version Xnumber that is \(lqsmaller\(rq than the one given by the system. X.IP "-14 AF_ELOC invalid location of archive file" XAn archive file has been moved without updating the \fIhost\fR and X\fIpathname\fR attribute. X.IP "-15 AF_EMISC miscellaneous errors" XThis error code is set when an error occurs that does not fit in any Xof the other error categories. XSee your error logging file (\fI/usr/adm/AFSerrlog\fR of \fI/tmp/AFSerrlog\fR) Xfor a detailed description of the error. X\fIAf_perror\fR also gives a diagnostic message explaining the error. X.IP "-16 AF_EMODE invalid mode" XThe functions \fIaf_svar\fR and \fIaf_sudattrs\fR require a change mode. XThis error condition complains about an invalid mode given to one Xof these two functions. See \fIaf_udattrs\fR for further Xdetails. X.IP "-17 AF_ENOAFSDIR AFS subdirectory missing or not writable" XThere is no place where AFS can create it's archive files. XEither a global archive path should be defined (see \fIaf_setarchpath\fR) Xor a subdirectory named \(lqAFS\(rq should be present and writable. X.IP "-18 AF_ENOKEY key does not exist in set" XA specified key that shall be removed from a keyset does not exist Xin the concerning set. X.IP "-19 AF_ENOPOS invalid position in set" XA specified position in a keyset (keysets are organized as arrays Xof object keys) lies beyond the bounds of the concerning set. X.IP "-20 AF_ENOREV specified revision does not exist" XA revision - uniquely identified by a set of attributes (eg. X\fIaf_getkey\fR) - does not exist in the current search space. X.IP "-21 AF_ENOTBUSY specified ASO is not busy version" XSome AFS-operations (eg. af_setbusy (3)) require the key of a busy ASO Xas input parameter. If you pass key of a non-busy ASO, the Xfunction sets this error code. X.IP "-22 AF_ENOTDERIVED specified ASO is no derived object" XAn attempt was made to restore an object that in not stored in a Xderived object pool. X.IP "-23 AF_ENOTLOCKED spec. ASO is not locked or locked by another user" XAn AFS-operation cannot be performed because the specified ASO Xis either not locked (see \fIaf_lock\fR) or it is locked by Xanother user. X.IP "-24 AF_ENOTREGULAR specified ASO is no regular file" XWith this error number the AFS refuses to generate versions of Xnon-regular \s-1UNIX\s+1 files such as directories, special files and sockets. X.IP "-25 AF_ENOTVERS specified ASO has no versions" XTypically, this error occurs if an operation that requires at least Xone saved revision (eg. af_newgen (3)) is applied on a versionless file. X.IP "-26 AF_ENOUDA user defined attribute does not exist" XA user defined attribute with the given name does not exist. X.IP "-27 AF_ESAVED saved versions cannot be modified" XAn attempt was made to open a non-busy version with write access. X.IP "-28 AF_ESTATE invalid state transition" XThe \fIAttribute Filesystem\fR's built in revision-states model allows Xonly well defined revision state changes. See af_states (3) for further Xdetails. X.IP "-29 AF_ETOOLONG String too long" XA given string that shall be set as the value of a string attribute X(eg. \fIaf_variant\fR) is too long. X.IP "-30 AF_EUDASNUM too many user defined attributes" XDue to the Xfact, that an attribute buffer can only hold a limited number of user Xdefined attributes, AFS complains if the number of user defined Xattributes attached to an ASO exceeds this limit. The constant X\fIAF_MAXUDAS\fR defined in \fIafs.h\fR defines the maximum number of Xuser defined attributes. X.IP "-31 AF_EWRONGSTATE wrong state" XSome AFS-operations can only be performed on ASOs with a specific version Xstate. X.RE X.PP XThe error codes indicating real trouble: X.IP "-32 AF_EDELTA Error during delta operation" XSome error occurred during Xinvocation of the delta processor. X.IP "-33 AF_EINCONSIST Archive file inconsistent" XThe data in the archive file are corrupted. This Xmay have happened by editing the archive file or by malfunction of an XAFS-operation. Please inform your local trouble shooting service, go Xto your favorite pub and order a beer. X.IP "-34 AF_EINTERNAL internal error" XPlease inform your local trouble shooting service, go to your Xfavorite pub and order two beers. X.IP "-35 AF_ENOAFSFILE No AFS file" XArchive file missing. X.RE X.SH LIST OF FUNCTIONS X.ta 1.4i 2.8i X\fIName Appears on Page Description\fR X.sp Xaf_access af_misc.3 test accessibility of ASO X.br Xaf_afname af_misc.3 get ASO name from \s-1UNIX\s+1 path X.br Xaf_afpath af_misc.3 get ASO syspath from \s-1UNIX\s+1 path X.br Xaf_aftype af_misc.3 get ASO type from \s-1UNIX\s+1 path X.br Xaf_bpfind af_retr.3 find derived objects by attributes X.br Xaf_chauthor af_perm.3 change author of ASO X.br Xaf_chmod af_perm.3 change access permissions of ASO X.br Xaf_chowner af_perm.3 change owner of ASO X.br Xaf_cleanup af_misc.3 do cleanup X.br Xaf_close af_files.3 close ASO X.br Xaf_copyset af_setops.3 copy sets X.br Xaf_crkey af_files.3 create object key for \s-1UNIX\s+1\-file X.br Xaf_diff af_setops.3 build difference between two sets of object keys X.br Xaf_dropkey af_retrieve.3 drop object key X.br Xaf_dropset af_sets.3 drop set of object keys X.br Xaf_find af_retrieve.3 find ASOs by attributes X.br Xaf_gattrs af_attrs.3 get all attributes of ASO X.br Xaf_getkey af_retrieve.3 get key by unique attributes X.br Xaf_initattrs af_retrieve.3 initialize attribute buffer X.br Xaf_initset af_sets.3 initialize set X.br Xaf_intersect af_setops.3 build intersection between two sets of object keys X.br Xaf_link af_files.3 create a link between two ASOs X.br Xaf_lock af_lock.3 set lock on ASO X.br Xaf_newgen af_versions.3 increase generation number of ASO X.br Xaf_nrofkeys af_sets.3 return number of keys in set of object keys X.br Xaf_open af_files.3 open ASO X.br Xaf_perror af_misc.3 report AFS- or system error X.br Xaf_rauthor af_perm.3 return author X.br Xaf_restore af_files.3 restore derived ASO X.br Xaf_rgen af_attr.3 return generation number of ASO X.br Xaf_rm af_files.3 remove ASO X.br Xaf_rname af_attrs.3 return name of ASO X.br Xaf_rnote af_note.3 read note attribute X.br Xaf_rowner af_perm.3 return owner of ASO X.br Xaf_rrev af_attr.3 return revision number of ASO X.br Xaf_rstate af_versions.3 return version state of ASO X.br Xaf_rsyspath af_attrs.3 return system path of ASO X.br Xaf_rtype af_attrs.3 return type of ASO X.br Xaf_rudattr af_udattrs.3 return user defined attribute X.br Xaf_rvariant af_variant.3 return variant attribute X.br Xaf_savebinary af_versions.3 save derived object X.br Xaf_saverev af_versions.3 save busy version of source object X.br Xaf_setaddkey af_sets.3 add key to set of object keys X.br Xaf_setarchpath af_misc.3 set path for location of archives X.br Xaf_setbusy af_versions.3 set version busy X.br Xaf_sgetkey af_sets.3 get key from set of object keys X.br Xaf_setposrmkey af_sets.3 remove key (id. by position) from set of object keys X.br Xaf_setrmkey af_sets.3 remove key from set of object keys X.br Xaf_snote af_note.3 set note attribute X.br Xaf_sortset af_setops.3 sort set of object keys X.br Xaf_sstate af_versions.3 set version state X.br Xaf_subset af_setops.3 build subset of set of object keys X.br Xaf_sudattr af_udattrs.3 set user defined attribute X.br Xaf_svariant af_variant.3 set variant attribute X.br Xaf_svnum af_versions.3 set version number X.br Xaf_testlock af_lock.3 see if ASO is locked X.br Xaf_union af_setops.3 build union of two sets of object keys X.br Xaf_unlock af_lock.3 remove lock from ASO X.br Xaf_version af_misc.3 return identification of current AFS version X.br X.SH FILES X/usr/adm/AFSerrlog (/tmp/AFSerrlog) X.SH SEE ALSO Xintro (2), intro (3) X.br XA. Lampen and A. Mahler, \(lqAn Object Base for Attributed XSoftware Objects,\(rq X.br X\fIProceedings of the Autumn '88 EUUG Conference\fR (Cascais, 3-7 October) X.br XEuropean UNIX system User Group, London 1988 X.SH BUGS XThe built in archive file locking to prevent concurrent updates Xis very simple and my lead to confusing situations. XIt may happen that changes will not be saved to disk. XSee the error conditions \fIAF_EARCHANGED\fR and \fIAF_EARLOCKED\fR Xfor more details X.PP XThis is a draft version of the AFS-Manual. XIt may still be a bit vague or even uncomplete every here and there. XIf you have questions or suggestions, please mail them to the author. XNevertheless, I hope this manual will provide enough information Xto enable you to write AFS-applications. Happy hackin'! X.SH AUTHOR XAndreas Lampen, TU Berlin X.br X.ta 0.7i XUUCP: unido!coma!andy X.br XBITNET: andy@db0tui62 END_OF_FILE if test 16204 -ne `wc -c <'man/man3/afintro.3'`; then echo shar: \"'man/man3/afintro.3'\" unpacked with wrong size! fi # end of 'man/man3/afintro.3' fi if test -f 'src/vc/dosave.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/vc/dosave.c'\" else echo shar: Extracting \"'src/vc/dosave.c'\" \(16567 characters\) sed "s/^X//" >'src/vc/dosave.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: dosave.c[3.21] Thu Feb 23 18:13:30 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/dosave.c[3.8] X * Thu Feb 23 18:13:30 1989 axel@coma save $ X * Intention for change: X * This is still a test. A minute ago, I was able to set an intention X * but now I doubt, that I'll be allowed to set a user defined attribute X * to the bus X * dosave.c[3.9] Thu Feb 23 18:13:30 1989 axel@coma save $ X * Intention for change: X * This is still a test. A minute ago, I was able to set an intention X * but now I doubt, that I'll be allowed to set a user defined attribute X * to the bus X * dosave.c[3.15] Thu Feb 23 18:13:30 1989 axel@coma published $ X * --- empty log message --- X * dosave.c[3.19] Thu Feb 23 18:13:30 1989 axel@coma published $ X * --- empty log message --- X * dosave.c[3.20] Thu Feb 23 18:13:30 1989 axel@coma save $ X * --- empty log message --- X * dosave.c[3.21] Thu Feb 23 18:13:30 1989 axel@coma published $ X * --- empty log message --- X */ X X#include <strings.h> X#include <stdio.h> X#include <pwd.h> X#include "afs.h" X#include "save.h" X#include <sys/types.h> X#include <sys/stat.h> X#include "project.h" X#include "locks.h" X Xextern unsigned int options; Xextern char tfname[], vcomment[], atr_fname[], symname[]; Xextern int newvnum; Xextern struct Transaction ThisTransaction; X XSaveAFile (fname, proj) char *fname; Project *proj; { X/* X * Save working file with the given name in the project location (syspath) X * determined by proj. Check for changes before saving. X * Attributes are also derived from the proj-context. X * Unless QUIETPLEASE is set, the user will be prompted for a note X * describing the changes to be saved. X * On the locking strategy: X * An author can save a busy version, only if he holds a lock (update X * privilege) for the document history. When an archive is newly X * created from a (busy) file, such a lock is assumed to be set. X * Upon save operations - which are conceptually local to a user context - X * the lock is kept. A lock can be released by submitting a version X * to the project and explicitly giving up the lock (option). After that, X * no more 'saves' are possible even though the user is in unix sense still X * owner of his local archive-file. This is so because we guarantee object X * consistency in a project among several databases. X * Locks on certain documents can be obtained through means of 'reserve' X * which is a User <--> Project transaction. Locally created documents X * are placed under project discipline (or configuration control) the X * first time they are submitted -- even if they have not been reserved X * yet. Locks have token-character, i.e. they may be passed around, but X * never ever be duplicated. X */ X /* X * NOTE: use of variant attribute in af_getkey is not yet functional. X * The parameter, however, is necessary to occupy the slot. X * Implementation of variant selection may make it necessary X * to add another parameter to this procedure. X */ X char spath[MAXNAMLEN], origpath[MAXNAMLEN], name[MAXNAMLEN], X *afname, *aftype, *afvariant = NULL, str[80], messg[80], *note, X *getnote(), *gettxt(), *vnum(), *getattr(), *as; X int truth = TRUE; X Af_attrs reqattrs, busyattrs, sattrs; X Af_key busy, lastsave, skey, *newkey, ngkey, tmpkey; X Af_set junkset; X X if (!fname) return; X X af_initattrs (&reqattrs); X getsyspath (fname, proj, spath, origpath, name); X /* splits name and pathname prefix */ X X afname = af_afname (name); X aftype = af_aftype (name); X /* give a little feedback ... */ X if (spath[0]) { X (void)sprintf (messg, "[%s]%s:", spath, name); X } X else { X (void)sprintf (messg, "%s:", name); X } X logmsg (messg); X X if (options & SYMNSET) { X af_initattrs (&sattrs); X (void)strcpy (sattrs.af_syspath, spath); X (void)strcpy (sattrs.af_name, afname); X (void)strcpy (sattrs.af_type, aftype); X (void)sprintf (str, "%s=%s", SYMNAME, symname); X sattrs.af_udattrs[0] = str; X sattrs.af_udattrs[1] = NULL; X af_find (&sattrs, &junkset); X if (af_nrofkeys(&junkset)) { X af_setgkey (&junkset, 0, &tmpkey); X (void)sprintf (messg, "symbolic name %s already in use by %s[%s]", X symname, fname, vnum(&tmpkey)); X logerr (messg); X af_dropset (&junkset); X af_dropkey (&tmpkey); X abort_this (FALSE); X } X else { X af_cleanup (); /* ??? */ X } X } X if (fail(af_getkey (spath, afname, aftype, AF_BUSYVERS, X AF_BUSYVERS, afvariant, &busy))) { X (void)sprintf (messg, "%s[busy]", fname); X af_perror (messg); X abort_this (TRUE); X } X X if (fail(af_gattrs (&busy, &busyattrs))) { X (void)sprintf (messg, "Cannot access attributes of %s.", name); X af_perror (messg); X af_dropkey (&busy); X abort_this(TRUE); X } X if (fail(af_getkey (spath, afname, aftype, AF_LASTVERS, X AF_LASTVERS, afvariant, &lastsave))) { X logmsg ("creating archive"); X if (options & TXTFSET) { X note = gettxt (tfname); X } X else { X note = getnote ("How about describing the purpose of this document ?", X truth, TRUE, (char *)NULL); X } X if (lockeruid(vc_lock_g(&busy, (Uid_t)getuid())) != (Uid_t)getuid()) { X af_perror ("cannot lock archive"); X af_dropkey (&busy); X abort_this (TRUE); X } X if (fail(af_saverev (&busy, &skey))) { X af_perror (fname); X af_dropkey (&busy); X abort_this(TRUE); X } X newkey = &skey; X ThisTransaction.tr_done = TRUE; X if (options & SUBMIT) { X af_sstate (newkey, AF_PROPOSED); X af_sstate (newkey, AF_PUBLISHED); X } X (void)sprintf (messg, "saved version %s", vnum (newkey)); X logmsg (messg); X } /* This was handling of newly created archive */ X else { X#ifdef PROJIMPL X if (!mylock (&busy, proj)) /* { */ /* -- emacs c-mode */ X#else X if (!mylock (&busy, (Project *)NULL)) { X#endif X (void)sprintf (messg, "%s not saved.", fname); X logmsg (messg); X af_dropkey (&busy); X abort_this (FALSE); X } X if (changed (&busy, &lastsave, &truth)) { X /* Version alias problem: copy or ref */ X if (options & TXTFSET) { X note = gettxt (tfname); X } X else if (options & MSGSET) { X note = vcomment; X } X else { X char *intent = (char *)0; X if (options & (LCKGIVEUP | SUBMIT)) X intent = af_rudattr (&busy, INTENT); X note = getnote ("Do you want to comment your modifications ?", truth, X FALSE, intent); X if (intent) free (intent); X af_sudattr (&busy, AF_REMOVE, INTENT); X } X if (fail(af_saverev (&busy, &skey))) { X af_perror (fname); X af_dropkey (&busy); X abort_this(TRUE); X } X newkey = &skey; X ThisTransaction.tr_done = TRUE; X af_sudattr (newkey, AF_REMOVE, INTENT); X if (options & NEWGEN) { X if (myproject(proj)) { X af_newgen (newkey, &ngkey); X (void)sprintf (messg, X "saved version %s (aliassed by ", X vnum (newkey)); X (void)sprintf (messg, "%s%s due to new generation)", messg, vnum(&ngkey)); X logmsg (messg); X af_dropkey (newkey); X newkey = &ngkey; X if (options & SUBMIT) X setpublished (newkey); X } X else { X logmsg ("You must be project-admin to increase generation number."); X } X } X else { X (void)sprintf (messg, "saved version %s", vnum (newkey)); X logmsg (messg); X if (options & SUBMIT) X setpublished (newkey); X } X } X else { X if (options & SUBMIT) { X char *intent = (char *)0; X intent = af_rudattr (&busy, INTENT); X note = getnote ("Do you want to comment your modifications ?", truth, X FALSE, intent); X if (intent) free (intent); X af_sudattr (&busy, AF_REMOVE, INTENT); X setpublished (&lastsave); X (void)sprintf X (messg, "%s set to state \"published\" (no changes to be saved)", X fname); X logmsg (messg); X newkey = &lastsave; X } X else { X (void)sprintf (messg, "%s not saved.", fname); X logmsg (messg); X af_dropkey (&busy); X abort_this(FALSE); X } X } X } X /* If we get here, something has been saved -- set note */ X if (fail(af_snote (newkey, note))) { X af_perror (""); X } X if (options & SYMNSET) { X (void)sprintf (str, "%s=%s", SYMNAME, symname); X as = str; X af_sudattr (newkey, AF_ADD, as); X } X if (options & SETVNUM) { X if (!(mkvno(vnum(newkey)) == newvnum)) { /* do nothing */ X if (af_svnum (newkey, gen(newvnum), rev(newvnum)) < 0) { X (void)sprintf (messg, "version number %d.%d too small for %s.", X gen(newvnum), rev(newvnum), fname ); X logerr (messg); X } X } X } X if (options & ATTRDEF) { X as = getattr (atr_fname, proj, aftype, REWIND); X af_sudattr (newkey, AF_ADD, as); X while (as=getattr (atr_fname, proj, aftype, NEXT)) { X af_sudattr (newkey, AF_ADD, as); X } X } X if (options & LCKGIVEUP) { X if ((lockeruid(vc_unlock_g(&busy))) != (Uid_t)getuid()) { X af_perror ("af_unlock: foul"); X } X } X /* right before we are done, release the version lock on new version */ X (void)vc_unlock_v(newkey); X af_dropkey (newkey); X af_dropkey (&busy); X} X Xchanged (new, old, realtruth) Af_key *new, *old; int *realtruth; { X/* X * Return true if new and old are actually different OR deposit is X * forced OR if user says 'yes' when asked whether an unchanged version X * shall be saved anyway. X * As AFS is still in the tests, this is programmed very defensively. X */ X FILE *newf, *oldf; X Af_attrs newat, oldat; X char *news, *olds, *malloc(), messg[80]; X X *realtruth = TRUE; /* initially assume that something has act. changed */ X if (fail(af_gattrs (new, &newat))) { X af_perror ("busy-version"); X } X if (fail(af_gattrs (old, &oldat))) { X af_perror ("lastsaved-version"); X } X if (newat.af_size != oldat.af_size) { X return TRUE; X } X else { /* lets have a closer look at 'em */ X if ((news = malloc ((unsigned)newat.af_size)) == NULL) { X (void)sprintf (messg, "Can't malloc %d bytes.", newat.af_size); X logmsg (messg); X abort_this(TRUE); X } X if ((olds = malloc ((unsigned)oldat.af_size)) == NULL) { X (void)sprintf (messg, "Can't malloc %d bytes.", oldat.af_size); X logmsg (messg); X free (news); X abort_this(TRUE); X } X if ((newf = af_open (new, "r")) == NULL) { X af_perror ("busy-version"); X free (news); X free (olds); X abort_this(TRUE); X } X if ((oldf = af_open (old, "r")) == NULL) { X af_perror ("lastsaved-version"); X free (news); X free (olds); X af_close (newf); X abort_this(TRUE); X } X#ifdef ULTRIX_2_0 X if (fread (news, sizeof (char), (unsigned)newat.af_size, newf) == NULL) X#else X if (fread (news, sizeof (char), (int)newat.af_size, newf) == NULL) X#endif X { X logmsg ("Couldn't read busy version."); X free (news); X free (olds); X af_close (newf); X af_close (oldf); X abort_this (TRUE); X } X#ifdef ULTRIX_2_0 X if (fread (olds, sizeof (char), (unsigned)oldat.af_size, oldf) == NULL) X#else X if (fread (olds, sizeof (char), (int)oldat.af_size, oldf) == NULL) X#endif X { X logmsg ("Couldn't read lastsaved version."); X free (news); X free (olds); X af_close (newf); X af_close (oldf); X abort_this (TRUE); X } X af_close (newf); X af_close (oldf); X free (news); X free (olds); X if (bcmp (olds, news, (int)newat.af_size)) { X return TRUE; X } X else { /* Hmmm, looks like nothing has changed ... */ X *realtruth = FALSE; /* return value may be a lie */ X if (options & FORCE) { X return TRUE; X } X else { X if (options & QUIETPLEASE) { X return FALSE; X } X if (isatty (fileno (stdin)) && isatty (fileno (stdout))) { X (void)sprintf (messg, "There are no changes with respect to the previously saved version.\nSave anyway ?"); X return !ask_confirm (messg, "no"); X } X else return FALSE; X } X } X } X} X Xchar *gettxt (fname) char *fname; { X static char *txt = EMPTYNOTE; X FILE *txtfil; X struct stat statbuf; X static int firsttime = TRUE; X X if (firsttime) { X firsttime = FALSE; X if ((txtfil = fopen (fname, "r")) == NULL) { X logerr ("no descriptive text file"); X } X else { X if (fstat (fileno(txtfil), &statbuf) == -1) { X perror ("couldn't stat"); X } X else { X txt = malloc ((unsigned)statbuf.st_size); X if (!txt) { X logerr ("not enough memory for descriptive text."); X txt = EMPTYNOTE; X } X else { X (void)fread (txt, sizeof (char), (Size_t)statbuf.st_size, txtfil); X (void)fclose (txtfil); X } X } X } X } X return txt; X} X Xchar *getnote (prompt, changeflg, force, intent) char *prompt, *intent; { X char *tmpname, *mktemp(), *edname, cmd[128], *getenv(), messg[80]; X static char *notetxt; X FILE *tmpfil; X struct stat statbuf; X static int firsttime = TRUE; X X if ((options & QUIETPLEASE) || X (!(isatty(fileno(stdin))))) { X if (intent) goto retintent; X else return EMPTYNOTE; X } X if ((!force) && (!firsttime) && notetxt) { X if (ask_confirm ("Use previous log message ?", "yes")) { X return notetxt; X } X else { X free (notetxt); X } X } X firsttime = FALSE; X if (changeflg) { X if (!ask_confirm (prompt, "yes")) X if (intent) goto retintent; X else return EMPTYNOTE; X } X else { X if (ask_confirm ("The new version is unmodified. Comment it anyway ?", X "no")) X if (intent) goto retintent; X else return EMPTYNOTE; X } X tmpname = mktemp ("/tmp/afsXXXXXX"); X Register (tmpname, TYPEF); X if (intent) { X FILE *tfd; X tfd = fopen (tmpname, "w"); X if (fwrite (intent, strlen (intent), sizeof (char), tfd) != X strlen (intent)) { X logerr ("write failure on tmp-file"); X } X (void)fclose (tfd); X } X if (edname = getenv ("EDITOR")) { X (void)sprintf (cmd, "%s %s", edname, tmpname); X (void)sprintf (messg, "starting up %s ...", edname); X logmsg (messg); X if (system (cmd) == NOSHELL) { X logerr ("couldn't execute shell"); X } X else { X if ((tmpfil = fopen (tmpname, "r")) == NULL) { X logerr ("empty logentry"); X return EMPTYNOTE; X } X else { X (void)unlink (tmpname); X UnRegister (tmpname, TYPEF); X if (fstat (fileno(tmpfil), &statbuf) == -1) { X perror ("couldn't stat"); X } X else { X notetxt = malloc ((unsigned)statbuf.st_size); X if (!notetxt) { X logerr ("not enough memory for note text."); X } X (void)fread (notetxt, sizeof (char), (Size_t)statbuf.st_size, X tmpfil); X (void)fclose (tmpfil); X return notetxt; X } X } X } X } X logerr ("You must set the EDITOR environment variable to write a note"); X return EMPTYNOTE; /* maybe we should try to read from stdin */ X retintent: X notetxt = malloc ((unsigned)(strlen (intent) + 1)); X (void)strcpy (notetxt, intent); X return notetxt; X} X Xsetpublished (key) Af_key *key; { X /* set specified version to state 'published' */ X X int sdiff, oldstate = af_rstate (key); X register int i; X X if (sdiff = (AF_PUBLISHED - oldstate)) { X if (sdiff > 0) X for (i = 1; i <= sdiff; i++) { X if ((lockeruid(vc_lock_v(key, (Uid_t)getuid()))) != (Uid_t)getuid()) { X logerr ("can't change state to published -- locked"); X return; X } X af_sstate (key, oldstate+i); X (void)vc_unlock_v(key); X } X else /* sdiff must be < 0 */ X for (i = 1; i <= abs(sdiff); i++) { X if ((lockeruid(vc_lock_v(key, (Uid_t)getuid()))) != (Uid_t)getuid()) { X logerr ("can't change state to published -- locked"); X return; X } X af_sstate (key, oldstate-i); X (void)vc_unlock_v(key); X } X } X /* else: state already is published */ X} END_OF_FILE if test 16567 -ne `wc -c <'src/vc/dosave.c'`; then echo shar: \"'src/vc/dosave.c'\" unpacked with wrong size! fi # end of 'src/vc/dosave.c' fi echo shar: End of archive 17 \(of 33\). cp /dev/null ark17isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 33 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.