home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume19 / shape / part17 < prev    next >
Text File  |  1989-05-31  |  53KB  |  1,371 lines

  1. Subject:  v19i030:  A software configuration management system, Part17/33
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Axel Mahler <unido!coma!axel>
  7. Posting-number: Volume 19, Issue 30
  8. Archive-name: shape/part17
  9.  
  10.  
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 17 (of 33)."
  19. # Contents:  man/man1/vadm.1 man/man3/afintro.3 src/vc/dosave.c
  20. # Wrapped by rsalz@papaya.bbn.com on Thu Jun  1 19:27:09 1989
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'man/man1/vadm.1' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'man/man1/vadm.1'\"
  24. else
  25. echo shar: Extracting \"'man/man1/vadm.1'\" \(16429 characters\)
  26. sed "s/^X//" >'man/man1/vadm.1' <<'END_OF_FILE'
  27. X...
  28. X... Copyright (C) 1989, 1990 W. Koch, A. Lampen, A. Mahler, W. Obst,
  29. X...  and U. Pralle
  30. X... 
  31. X... This software is published on an as-is basis. There is ABSOLUTELY NO
  32. X... WARRANTY for any part of this software to work correctly or as described
  33. X... in the manuals. We do not accept any liability for any kind of damage
  34. X... caused by use of this software, such as loss of data, time, money, or 
  35. X... effort.
  36. X... 
  37. X... Permission is granted to use, copy, modify, or distribute any part of
  38. X... this software as long as this is done without asking for charge, and
  39. X... provided that this copyright notice is retained as part of the source
  40. X... files. You may charge a distribution fee for the physical act of
  41. X... transferring a copy, and you may at your option offer warranty
  42. X... protection in exchange for a fee.
  43. X... 
  44. X... Direct questions to: Tech. Univ. Berlin
  45. X...              Wilfried Koch
  46. X...              Sekr. FR 5-6 
  47. X...              Franklinstr. 28/29
  48. X...              D-1000 Berlin 10, West Germany
  49. X... 
  50. X...              Tel: +49-30-314-22972
  51. X...              E-mail: shape@coma.uucp or shape@db0tui62.bitnet
  52. X... 
  53. X...
  54. X... $Header: vadm.1[3.3] Thu Feb 23 18:14:02 1989 axel@coma published $
  55. X... 
  56. X... Log for /u/shape/dist-tape/src/vc/vadm.1[3.1]
  57. X...     Thu Feb 23 18:14:02 1989 axel@coma published $
  58. X...  --- empty log message ---
  59. X...  vadm.1[3.2] Thu Feb 23 18:14:03 1989 axel@coma published $
  60. X...  --- empty log message ---
  61. X...  vadm.1[3.3] Thu Feb 23 18:14:03 1989 axel@coma published $
  62. X...  --- empty log message ---
  63. X...
  64. X.UC
  65. X.TH VADM 1 vadm \n(dy.\n(mo.\n(yr
  66. X.SH NAME
  67. Xvadm \- manipulate and administer version object base
  68. X.SH SYNOPSIS
  69. X\fBvadm\fR [\ \fIoptions\fR\ ]\ [\ \fIversion\ range\fR\ ]\ [\ \fIaction\fR\ ] name\|.\|.
  70. X.SH DESCRIPTION
  71. X.PP
  72. X\fBvadm\fR is a general purpose command to perform all sorts of
  73. Xactions upon parts of an AFS object base. It can be used to lock or unlock
  74. Xan AFS object, to reserve (or unreserve) an object for modification, to
  75. Xdelete a particular object instance, to associate symbolic names with
  76. Xversion objects, to promote or unpromote certain version objects from
  77. Xone status to another, to modify an object's access permissions, to set or
  78. Xmodify a descriptive entry of particular version objects, to set or
  79. Xmodify an eventual change intention, and to set
  80. Xor unset various object attributes such as the author or any user
  81. Xdefined attributes.
  82. X.PP
  83. XThe typical command invocation is supplemented by one or more
  84. X\fIcommand options\fR, a \fIversion range\fR usually defining a
  85. Xrange of object instances to be acted upon, an \fIaction specifier\fR
  86. Xindicating the sort of action to be performed, and a set of \fIobject
  87. Xnames\fR defining the initial subset of the object base that's going
  88. Xto be manipulated. 
  89. X.PP
  90. XObject names may be given in \fIbound version notation\fR,
  91. Xi.e. a notation that identifies a particular version of an object (e.g.
  92. X\fCmkattr.c[2.4]\fR). It is also possible to use a previously assigned
  93. X\fIsymbolic name\fR rather than a numerical 
  94. Xversion identification (e.g. \fCmkattr.c[tools-V4R3]\fR). Make sure
  95. Xto escape the bracket-symbols as these usually have meaning to the
  96. Xshell.
  97. X.PP
  98. XThe following \fIoptions\fR are recognized:
  99. X.IP "\fB\-version\fR" \w'\fB\-version++\fR'u
  100. Xprint version information about the \fBvadm\fR program itself. No action
  101. Xwill be performed on the database.
  102. X.IP "\fB\-b\fR"
  103. Xapply the requested operation to objects residing in the \fIbinary pool\fR.
  104. XThe set of actions that may be performed on binary pool objects is limited.
  105. X.IP "\fB\-h\fR"
  106. Xprint brief instructions about using \fBvadm\fR
  107. X.IP "\fB\-q\fR"
  108. Xsuppress any prompts, informal messages and user dialogues. Default 
  109. Xvalues are assumed for everything that might otherwise be inquired
  110. Xinteractively. This option is useful for batch operation.
  111. X.in -0.25i
  112. X.PP
  113. X\fBvadm\fR will perform all of its operations upon a specified set of
  114. XAFS version objects. In case no such set is specified, the operation
  115. Xwill be applied to the most recently saved versions of the named
  116. Xobject(s).  A particular version can be identified by specifying its
  117. X\fIversionnumber\fR or a previously assigned \fIsymbolic name\fR
  118. Xthrough the \fB\-V\fI<version>\fR argument. A \fIrange\fR of versions can
  119. Xbe defined through use of the \fB\-from\fI<versionnumber>\fR and
  120. X\fB\-to\fI<versionnumber>\fR arguments.  The specified range
  121. X\fIincludes\fR the given margin versions. Use of either version range 
  122. Xspecification form (\fB\-V \fR or \fB\-from/\-to\fR) excludes the
  123. Xother form.
  124. X.PP
  125. XThe kind of operation to be performed upon a specified set of AFS
  126. Xobjects is indicated by a keyword. The following actions are defined:
  127. X.in +0.25i
  128. X.IP "\fB\-lock\fR" \w'\fB\-unpromote++\fR'u
  129. Xtries to reserve the privilege to add a new version to an objects 
  130. Xhistory, thus preventing multiple programmers working upon the same 
  131. Xobject base from interfering with each other by saving concurrent updates.
  132. XThis simple mechanism is for use in small development projects, that do
  133. X\fInot\fR employ the scheme of private, experimental archives for each 
  134. Xparticipating programmer, and one centralized \fIproject library\fR where
  135. Xindividual work results are collected. 
  136. XWhen setting a new lock on an object history, the requesting user
  137. Xis prompted for an optional description of the planned changes.
  138. XSee also \fB\-reserve\fR.
  139. X.RS
  140. X.PP
  141. XIn order to lock an object history successfully, the history must not
  142. Xbe locked by any other programmer, and the programmer requesting the
  143. Xlock must have write permission on the AFS subdirectory hosting the
  144. Xobject base.
  145. X.PP
  146. XThis option is not available for objects in binary pools.
  147. X.RE
  148. X.IP "\fB\-unlock\fR"
  149. Xgives up the previously reserved privilege to update the history of an
  150. XAFS object. \fB\-unlock\fR may be used by the \fIowner\fR of an object
  151. Xhistory to \fIbreak a lock\fR previously set by any programmer. This 
  152. Xoption is useful to resolve deadlock situations resulting from careless
  153. Xuse of \fB\-lock\fR, or exceptional circumstances that require immediate
  154. Xupdating of an object history, even if the lockholder is not present.
  155. XThe previous owner of a broken lock is notified by a
  156. Xmail message. An eventually expressed change intention (see \fB\-lock\fR)
  157. Xwill be cleared.
  158. X.RS
  159. X.PP
  160. XTechnically, the owner of an object's history is the owner of the 
  161. XAFS subdirectory hosting the object base.
  162. X.PP
  163. XThis option is not available for objects in binary pools.
  164. X.RE
  165. X.IP "\fB\-reserve\fR"
  166. Xtries to reserve a version object from a centrally maintained project 
  167. Xlibrary in order to use it as starting point for the development of
  168. Xa new entry in the objct's history. In fact, \fB\-reserve\fR does nothing
  169. Xelse but eventually copy the specified version object from the
  170. Xproject library to the programmer's workspace, and set a lock on the 
  171. Xobject's history in the project library.
  172. XWhen setting a new lock on an object history, the requesting user
  173. Xis prompted for an optional description of the planned changes.
  174. XSee also \fB\-lock\fR.
  175. X.RS
  176. X.PP
  177. XAs with the \fB\-lock\fR request, an object's history must not be reserved
  178. Xby any other programmer, and the requesting programmer must have permission
  179. Xto do so. 
  180. X.PP
  181. XTo communicate with the project library, the reserve command either accesses
  182. Xa distant object base directory, or connects to a local (unix domain) or
  183. Xremote (internet domain) \fIlibrary server\fR. The place where a project's
  184. Xcentral library resides is identified by an entry in a projects database.
  185. XThis database is either \fI~/af_projects\fR or a default file such
  186. Xas \fI/usr/local/lib/af_projects\fR. The name of the project a requesting
  187. Xprogrammer is currently working on should be defined in the programmer's
  188. Xshell environment by the \fIAF_PROJECT\fR variable.
  189. X.PP
  190. XThis command is currently not implemented.
  191. X.PP
  192. XThis option is not available for objects in binary pools.
  193. X.RE
  194. X.IP "\fB\-unreserve\fR"
  195. Xcancels a previously issued \fB\-reserve\fR request. As with the
  196. X\fB\-lock\fR request, \fB\-unreserve\fR can be used by the \fIlibrary
  197. Xadministrator\fR to forcefully cancel an update reservation by any
  198. Xprogrammer. Programmers who are subject to forced cancellations will
  199. Xbe notified by a mail message.
  200. X.RS
  201. X.PP
  202. XThis command is currently not implemented.
  203. X.PP
  204. XThis option is not available for objects in binary pools.
  205. X.RE
  206. X.IP "\fB\-delete\fR"
  207. Xremoves the specified version objects from the object base, provided
  208. Xthe objects' status is \fIsaved\fR. Any other status indicates that
  209. Xsome kind of project interaction concerning this object might be in
  210. Xprogress. If the programmer wants to delete such a version object
  211. Xanyway, he has to \fB\-unpromote\fR the respective object's status to
  212. X\fIsaved\fR before it can actually be deleted.
  213. X.IP "\fB\-symbolic\fI\ <uniquename>"
  214. Xassigns the name \fIuniquename\fR to the specified version. The symbolic
  215. Xname works as an alias for the version number, so it must be different
  216. Xfrom any other symbolic name assigned to any version object in a particular
  217. Xobject history. It is, however, possible to assign the same symbolic
  218. Xname to version objects in \fIdifferent object histories\fR. An object
  219. Xhistory is usually denoted by a name, similarly to a file's name.
  220. X.RS
  221. X.PP
  222. XThe use of symbolic names is a simple but effective way to associate component
  223. Xmembers of a \fIsystem configuration\fR. Typical symbolic names will
  224. Xlook something like \fIMysystem_Release_4.22(vax)\fR, indicating that 
  225. Xversion objects with this name are part of release 4.22 of the system
  226. Xin question.
  227. X.RE
  228. X.IP "\fB\-promote\fR"
  229. Xassigns the next-higher value to the specified objects' \fIstate\fR attribute.
  230. XThere are six states that an object instance can be in: \fIbusy, saved,
  231. Xproposed, published, accessed, \fRand\fI frozen\fR. Version states are
  232. Xintended to relate to visibility and operational restrictions (see for
  233. Xexample \fB\-delete\fR) within a complex project environment.
  234. X.RS
  235. X.PP
  236. XDue to the current lack of project library support, the version states
  237. Xhave very little actual functionality. Implemented to its full extent,
  238. Xcertain state transitions may only be triggered by appropriately
  239. Xauthorized users. The transitions \fIbusy\(->saved\fR and 
  240. X\fIsaved\(->proposed\fR will be triggered by regular programmers, whereas
  241. Xthe remaining transitions have to be initiated by the \fIproject 
  242. Xadministrator\fR. 
  243. X.PP
  244. XEach transition corresponds to a specific action or interaction within
  245. Xa general software project communication scheme. As these actions/interactions
  246. Xwill be functionally supported by the project support system currently
  247. Xunder development, the explicit manipulation of object states will no
  248. Xlonger be necessary (except, perhaps for manual adjusting of ill situations).
  249. X.PP
  250. XThe following actions relate to the state transitions:
  251. X.IP "\fIsave\fR"
  252. X(\fIbusy\(->saved\fR, performed by programmer)
  253. X.IP "\fIsbmt\fR"
  254. X(\fIsaved\(->proposed\fR, performed by programmer)
  255. X.IP "\fIunsbmt\fR"
  256. X(\fIproposed\(->saved\fR, performed by programmer)
  257. X.IP "\fIaccpt\fR"
  258. X(\fIproposed\(->published\fR, performed by project administrator)
  259. X.IP "\fIrject\fR"
  260. X(\fIproposed\(->proposed\fR, performed by project administrator)
  261. X.IP "\fIaccs\fR"
  262. X(\fIpublished\(->accessed\fR, performed by any project member)
  263. X.IP "\fIrelease\fR"
  264. X(\fIaccessed\(->frozen\fR, performed by project administrator)
  265. X.PP
  266. XThis option is not available for objects in binary pools.
  267. X.RE
  268. X.IP "\fB\-unpromote\fR"
  269. Xreverses a state transition carried out through a prior \fB\-promote\fR.
  270. XThe same remarks about functional embedding (and thus \fIhiding\fR
  271. Xthe state transitions) of state transitions made for \fB\-promote\fR 
  272. Xhold for \fB\-unpromote\fR.
  273. X.RS
  274. X.PP
  275. XThis option is not available for objects in binary pools.
  276. X.RE
  277. X.IP "\fB\-chmod \fI<mode>\fR"
  278. Xchanges the access permission code of the specified version objects to
  279. Xthe supplied three-octal-digit \fImode\fR. Currently, the access
  280. Xpermissions are centered around UNIX' notions of \fIowner, group,\fR and 
  281. X\fIworld\fR
  282. Xaccess as well as the access categories \fIread, write,\fR and \fIexecute\fR.
  283. XThese
  284. Xpermissions are inherited upon \fBsave\fR from the permissions of the
  285. Xfile representing the \fIbusy object\fR of an AFS history. See
  286. X\fBchmod\fR(2) for details.
  287. X.IP "\fB\-chown \fI<user>\fR"
  288. Xsets \fIuser\fR the owner of an entire object history. This option
  289. Xis not supported on BSD type systems, as only the superuser may
  290. Xchange the owner of a file.
  291. X.IP "\fB\-chaut \fI<user>\fR"
  292. Xsets \fIuser\fR the author of a particular revision. Normally, the
  293. Xauthor of a revision is considered the user who \fIsaved\fR or \fIsubmitted\fR
  294. Xthat revision. However, as certain permissions are tied to the author
  295. Xattribute of a revision, circumstances may occur that make it necessary
  296. Xto change the author.
  297. X.IP "\fB\-set \fR[\fIdescription \fR| \fInote\fR | \fIintent\fR]"
  298. Xallows to set or modify the \fIdescriptive text\fR for an AFS history object
  299. X(i.e. an entire version history), the \fInote\fR usually describing the
  300. Xdifferences of a version object with respect to its preceding version, or
  301. Xan entry describing a planned change.
  302. X(Re-) setting the change intention may be appropriate, if a previously
  303. Xset change intent has been consumed by a \fBsbmt\fR command that 
  304. Xretained the lock on an object history.
  305. X.RS
  306. X.nr Ii \n(.i
  307. X.PP
  308. X\fBvadm\fR will check the caller's environment for the \fIEDITOR\fR
  309. Xvariable and invoke the program identified therein. If the \fIEDITOR\fR
  310. Xvariable is not set, the system's default editor will be activated.
  311. XThe user may write an arbitrary length descriptive or note entry using
  312. Xthe editor. When the user leaves the editor, the resulting text is
  313. Xstored with the object history or the specified version objects.
  314. X.PP
  315. XThis option is not available for objects in binary pools.
  316. X.RE
  317. X.PP
  318. X\fB\-setc\fI\ commentstring\fR
  319. X.nr Ci \n(.i
  320. X.in \n(Iiu
  321. Xsets \fIcommentstring\fR as the (sequence of) character(s) that opens a 
  322. Xcommentline within the formalism of the document.
  323. XThis commentstring will be prepended to the lines of the log history
  324. Xwhen the \fC$__log$\fR attribute is expanded within the text of a revision.
  325. X.PP
  326. X\fB\-setuda\fI <attrname=\fR[\fI@\fR]\fIstring>\fR
  327. X.nr Ci \n(.i
  328. X.in \n(Iiu
  329. Xsets the user defined attribute \fIattrname\fR to the value \fIstring\fR
  330. Xfor all specified version objects. If the first character of \fIstring\fR
  331. Xis an at-sign, the rest of \fIstring\fR is taken to be the \fIname of a file\fR
  332. Xthe contents of which will be taken as the value of the attribute. User
  333. Xdefined attributes may be of arbitrary length. Any sequence of ASCII
  334. Xcharacters \- with the exception of \e01 (control-A) \- is allowed to make
  335. Xup an attribute value.
  336. X.sp \n()Pu
  337. XIf \fIattrname\fR was already set to some value, the previous value
  338. Xwill be replaced by the newly specified one.
  339. X.in \n(Ciu
  340. X.IP "\fB\-unsetuda\fI <attrname>\fR" \w'\fB\-unpromote++\fR'u
  341. Xdeletes the user defined attribute \fIattrname\fR from the set of attributes
  342. Xassociated with the specified version objects.
  343. X.IP "\fB\-setattrs\fI <filename>\fR"
  344. Xreads names and values of user defined attributes from the file \fIfilename\fR.
  345. XThe entries in the attribute file are of the form \fINAME=VALUE\fR. \fINAME\fR
  346. Xmust be an alphanumeric string (no spaces) imediately followed by the equal
  347. Xsign. The value may be an arbitrary ASCII string with the exception of 
  348. Xcontrol-A and newline characters. There is exactly one attribute definition
  349. Xper line. The file's last character must be a newline character.
  350. X.RS
  351. X.PP
  352. XThis way to attach attributes was introduced to allow quick attachment
  353. Xof a large number of attributes to version objects. This is \fInot\fR
  354. Xthe primary user interface for doing this. Unfortunately, \fBvadm\fR 
  355. Xreacts ungracefully if the described convention is not followed.
  356. X.PP
  357. XPreviously assigned values of user defined attributes are overridden by
  358. Xthe values defined in the attributefile.
  359. X.RE
  360. X.SH SEE ALSO
  361. Xsave(1), retrv(1), rsrv(1), sbmt(1), vl(1), shape(1), 
  362. Xaf_intro(3), af_archive(5)
  363. X.PP
  364. XRecommended reading: A. Mahler, A. Lampen, \fI\(lqAn Integrated
  365. XToolkit for Engineering Software Configurations\(rq\fR, Proceedings of
  366. Xthe ACM SIGSOFT/SIGPLAN Software Engineering Symposium on Practical
  367. XSoftware Development Environments, November 1988, Boston Mass. (to
  368. Xbe published).
  369. X.SH BUGS
  370. XI'm afraid that there might be quite a lot of flaws around. Consistent 
  371. Xhandling of permissions is an especially error prone subject. Please report
  372. Xany bugs to the authors.
  373. X.SH AUTHOR
  374. XUli Pralle and Axel Mahler
  375. X.br
  376. XTechnical University Berlin
  377. X.sp
  378. X\fIUUCP:\fR        axel@coma.uucp (unido!coma!axel)
  379. X.br
  380. X        uli@coma.uucp (unido!coma!uli)
  381. X.br
  382. X\fIBITNET:\fR    axel@db0tui62
  383. X.br
  384. X        uli@db0tui62
  385. X
  386. END_OF_FILE
  387. if test 16429 -ne `wc -c <'man/man1/vadm.1'`; then
  388.     echo shar: \"'man/man1/vadm.1'\" unpacked with wrong size!
  389. fi
  390. # end of 'man/man1/vadm.1'
  391. fi
  392. if test -f 'man/man3/afintro.3' -a "${1}" != "-c" ; then 
  393.   echo shar: Will not clobber existing file \"'man/man3/afintro.3'\"
  394. else
  395. echo shar: Extracting \"'man/man3/afintro.3'\" \(16204 characters\)
  396. sed "s/^X//" >'man/man3/afintro.3' <<'END_OF_FILE'
  397. X...
  398. X... Copyright (C) 1989, 1990 W. Koch, A. Lampen, A. Mahler, W. Obst,
  399. X...  and U. Pralle
  400. X... 
  401. X... This software is published on an as-is basis. There is ABSOLUTELY NO
  402. X... WARRANTY for any part of this software to work correctly or as described
  403. X... in the manuals. We do not accept any liability for any kind of damage
  404. X... caused by use of this software, such as loss of data, time, money, or 
  405. X... effort.
  406. X... 
  407. X... Permission is granted to use, copy, modify, or distribute any part of
  408. X... this software as long as this is done without asking for charge, and
  409. X... provided that this copyright notice is retained as part of the source
  410. X... files. You may charge a distribution fee for the physical act of
  411. X... transferring a copy, and you may at your option offer warranty
  412. X... protection in exchange for a fee.
  413. X... 
  414. X... Direct questions to: Tech. Univ. Berlin
  415. X...              Wilfried Koch
  416. X...              Sekr. FR 5-6 
  417. X...              Franklinstr. 28/29
  418. X...              D-1000 Berlin 10, West Germany
  419. X... 
  420. X...              Tel: +49-30-314-22972
  421. X...              E-mail: shape@coma.uucp or shape@db0tui62.bitnet
  422. X... 
  423. X.TH AF_INTRO 3 "" \n(dy.\n(mo.\n(yr
  424. X.SH NAME
  425. Xaf_intro \(em introduction to AFS library functions and error codes
  426. X.SH SYNOPSIS
  427. X#include <afs.h>
  428. X.SH DESCRIPTION
  429. XThe following manual pages (named AF_*) describe the library functions
  430. Xof the \fIAttribute Filesystem\fR (AFS).
  431. X.PP
  432. XAFS is an extension to the \s-1UNIX\s+1
  433. Xfilesystem interface that allows the storage of files as complex of
  434. Xcontent data and an arbitrary number of associated attributes.
  435. XThese are called \fIattributed software objects\fR (ASOs).
  436. XAFS has a built-in version
  437. Xcontrol system that manages \fIlines of development\fR. A line of
  438. Xdevelopment consists of a \fIbusy object\fR and a number of saved
  439. Xversions. The busy object is an ordinary alterable \s-1UNIX\s+1 file.
  440. XIt can be accessed via AFS \fIand\fR \s-1UNIX\s+1
  441. Xfilesytem operations.  Versions come
  442. Xinto being by making a copy of the current state of the busy object.
  443. XThey can be stored as source objects or as derived objects.
  444. X.PP
  445. XSource objects are typically composed manually (e.g. by use of a text
  446. Xeditor). AFS stores source objects as immutable objects. Once saved,
  447. Xthey cannot be modified any longer. Saved ASOs are stored in archive
  448. Xfiles (like SCCS and RCS). AFS maintains two archive files for each
  449. Xline of development of source objects \- one holding the attributes
  450. Xand the other holding the data.  Normally, archives are stored in a
  451. Xsubdirectory called AFS (see \fIaf_setarchpath\fR for an exception to
  452. Xthis rule).  To save disk space, the versions in an archive are stored
  453. Xas deltas (differences to the previous version).
  454. X.PP
  455. XDerived objects
  456. Xare typically derived automatically (e.g. by a compiler) from a source
  457. Xobject and thus be reproducible at any time. They are kept in a
  458. X\fIderived object pool\fR (or \fIbinary pool\fR),
  459. Xa data store of limited size that is
  460. Xadministered in a cache fashion. The oldest (access date) derived
  461. Xobjects get removed if space runs short in the derived object pool.
  462. XDerived objects are stored physically unchanged. The attributes for
  463. Xderived objects are stored in a \fIndbm\fR database residing in the
  464. XAFS subdirectory. The maximum number of objects stored in a binary pool
  465. Xcan be given by setting the environment variable AFSBPSIZ to the
  466. Xappropriate value (default is 64).
  467. X.PP
  468. XAFS makes no assumptions
  469. Xwhether a copy of a busy object shall be stored as source object or as
  470. Xderived object. The application has to decide that by calling the
  471. Xappropriate function (see \fIAF_VERSIONS\fR).
  472. X.PP
  473. XThe main datatypes for AFS applications are:
  474. X.IP \(bu 0.2i
  475. XThe \fIobject key\fR that uniquely
  476. Xidentifies a software object. The structure of this type can be
  477. Xdifferent in different implementations of AFS. Consequently,
  478. Xapplication programs should handle this type as opaque type and should
  479. Xnot access single fields.
  480. X.IP \(bu
  481. X\fISet descriptors\fR represent a
  482. Xset of object keys. A set descriptor contains information about the
  483. Xnumber of keys in the set and a pointer to a list of object keys (see
  484. X\fIAF_SETS\fR).
  485. X.IP \(bu
  486. XAn \fIAttribute buffer\fR is capable to hold
  487. Xall attributes of a software object (standard attributes and user
  488. Xdefined attributes). Attribute buffers have two different purposes.
  489. XFirst, they can hold a retrieve pattern, i.e. they may be (partially)
  490. Xfilled with \fIdesired\fR attribute values and then be passed as
  491. Xargument to a retrieve operation (\fIAF_RETRIEVE\fR). Second, an
  492. Xattribute buffer is used to return all attributes of an identified ASO
  493. Xon demand (see \fIAF_ATTRS\fR).
  494. X.RE
  495. X.PP
  496. XMost of the AFS calls have
  497. Xone or more error returns.  An error is indicated by a return value
  498. Xthat is either \-1 or a nil pointer, depending on the type of the
  499. Xfunction.  If one of the functions returns with an error, the variable
  500. X\fIaf_errno\fR is set to indicate the appropriate error number.
  501. X\fIAf_errno\fR is not cleared upon successful calls.
  502. X.bp
  503. X.PP
  504. XThe following is a complete collection of the error numbers
  505. Xdefined in \fIafs.h\fR. The first list contains return values
  506. Xindicating \(lqnormal\(rq errors like unplausible arguments passed to
  507. Xan AFS function or permission problems. The error codes listed in the
  508. Xsecond list point to serious trouble, which can either be an internal
  509. Xerror in AFS or a corrupted archive file. The occurrence of an
  510. Xserious problem is recorded in an error protocol
  511. X(\fI/usr/adm/AFSerrlog\fR). On machines without \fIsyslog (3)\fR
  512. Xfacility, the error protocol is located in a \fI/tmp/AFSerrlog\fR.
  513. X.IP " -2  AF_ESYSERR Error during execution of syslib-command or syscall"
  514. XA called syslib function or syscall returned with an error
  515. Xcondition. See \fIerrno\fR for a more precise error specification.
  516. X.IP " -3  AF_EACCES permission denied"
  517. XAn attempt was made to perform
  518. Xan operation (e.g. open a file) without appropriate permissions.
  519. X.IP " -4  AF_EARCHANGED archive file has changed since last read"
  520. XOne of the archive files you are operating on has been modified
  521. Xby another process since your process has read it from disk.
  522. XIn this case, AFS refuses to store your changes because this would
  523. Xdestroy the modifications made by the other process.
  524. XIn order to make your desired changes happen, you have to rerun
  525. Xyour application.
  526. X.IP " -5  AF_EARLOCKED archive file is locked for writing"
  527. XAnother process is currently writing one of the archive files
  528. Xyou are operating on. Try again later.
  529. X.IP " -6  AF_EBPFULL no additional space in derived object pool"
  530. XThe AFS is
  531. Xunable to delete an old object from a derived object pool in order to
  532. Xget space for a new one. This error occurs if the concerning derived
  533. Xobject pool is full and all objects stored in this derived object pools
  534. Xare accessed by the current application. Use \fIaf_dropkey\fR or
  535. X\fIaf_dropset\fR to release one or more derived objects.
  536. X.IP "  -7  AF_EBUSY  Specified ASO must not be a busy version"
  537. XSome AFS-operations (eg. \fIaf_snote\fR, \fIaf_svnum\fR) cannot be
  538. Xperformed on ASOs which have the state \fIAF_BUSY\fR. 
  539. X.IP "  -8  AF_EDERIVED  Specified ASO must not be a derived object"
  540. XSome AFS-operations (eg. \fIaf_lock\fR, \fIaf_newgen\fR) cannot be
  541. Xperformed on ASOs stored in derived object pools.
  542. X.IP "  -9  AF_EFORMAT  illegal format of udattr string"
  543. XUser defined attributes must have the form \fIname[=value]\fR.
  544. XSee af_udas (3) for further details.
  545. X.IP "-10  AF_EINVKEY invalid object key"
  546. XAn invalid object key (eg. nil pointer) was passed to an AFS-function.
  547. X.IP "-11  AF_EINVSET invalid set descriptor"
  548. XAn invalid set descriptor (eg. nil pointer) was passed to an AFS-function.
  549. X.IP "-12  AF_EINVUSER invalid user"
  550. XAn invalid user name was passed to an AFS-operation.
  551. X.IP "-13  AF_EINVVNUM Bad version number"
  552. XAn attempt was made to set a version number, that
  553. Xcontradicts the AFS version numbering philosophy, to an ASO.
  554. XYou cannot change the version number of an ASO into a version
  555. Xnumber that is \(lqsmaller\(rq than the one given by the system.
  556. X.IP "-14  AF_ELOC invalid location of archive file"
  557. XAn archive file has been moved without updating the \fIhost\fR and
  558. X\fIpathname\fR attribute.
  559. X.IP "-15  AF_EMISC miscellaneous errors"
  560. XThis error code is set when an error occurs that does not fit in any
  561. Xof the other error categories.
  562. XSee your error logging file (\fI/usr/adm/AFSerrlog\fR of \fI/tmp/AFSerrlog\fR)
  563. Xfor a detailed description of the error.
  564. X\fIAf_perror\fR also gives a diagnostic message explaining the error.
  565. X.IP "-16  AF_EMODE invalid mode"
  566. XThe functions \fIaf_svar\fR and \fIaf_sudattrs\fR require a change mode.
  567. XThis error condition complains about an invalid mode given to one
  568. Xof these two functions. See \fIaf_udattrs\fR for further
  569. Xdetails.
  570. X.IP "-17  AF_ENOAFSDIR  AFS subdirectory missing or not writable"
  571. XThere is no place where AFS can create it's archive files.
  572. XEither a global archive path should be defined (see \fIaf_setarchpath\fR)
  573. Xor a subdirectory named \(lqAFS\(rq should be present and writable.
  574. X.IP "-18  AF_ENOKEY  key does not exist in set"
  575. XA specified key that shall be removed from a keyset does not exist
  576. Xin the concerning set.
  577. X.IP "-19  AF_ENOPOS  invalid position in set"
  578. XA specified position in a keyset (keysets are organized as arrays
  579. Xof object keys) lies beyond the bounds of the concerning set.
  580. X.IP "-20  AF_ENOREV  specified revision does not exist"
  581. XA revision - uniquely identified by a set of attributes (eg.
  582. X\fIaf_getkey\fR) - does not exist in the current search space.
  583. X.IP "-21  AF_ENOTBUSY  specified ASO is not busy version"
  584. XSome AFS-operations (eg. af_setbusy (3)) require the key of a busy ASO
  585. Xas input parameter. If you pass key of a non-busy ASO, the
  586. Xfunction sets this error code. 
  587. X.IP "-22  AF_ENOTDERIVED  specified ASO is no derived object"
  588. XAn attempt was made to restore an object that in not stored in a
  589. Xderived object pool.
  590. X.IP "-23  AF_ENOTLOCKED  spec. ASO is not locked or locked by another user"
  591. XAn AFS-operation cannot be performed because the specified ASO
  592. Xis either not locked (see \fIaf_lock\fR) or it is locked by
  593. Xanother user.
  594. X.IP "-24  AF_ENOTREGULAR  specified ASO is no regular file"
  595. XWith this error number the AFS refuses to generate versions of
  596. Xnon-regular \s-1UNIX\s+1 files such as directories, special files and sockets.
  597. X.IP "-25  AF_ENOTVERS  specified ASO has no versions"
  598. XTypically, this error occurs if an operation that requires at least
  599. Xone saved revision (eg. af_newgen (3)) is applied on a versionless file.
  600. X.IP "-26  AF_ENOUDA  user defined attribute does not exist"
  601. XA user defined attribute with the given name does not exist.
  602. X.IP "-27  AF_ESAVED  saved versions cannot be modified"
  603. XAn attempt was made to open a non-busy version with write access.
  604. X.IP "-28  AF_ESTATE  invalid state transition"
  605. XThe \fIAttribute Filesystem\fR's built in revision-states model allows
  606. Xonly well defined revision state changes. See af_states (3) for further
  607. Xdetails.
  608. X.IP "-29  AF_ETOOLONG  String too long"
  609. XA given string that shall be set as the value of a string attribute
  610. X(eg. \fIaf_variant\fR) is too long.
  611. X.IP "-30  AF_EUDASNUM too many user defined attributes"
  612. XDue to the
  613. Xfact, that an attribute buffer can only hold a limited number of user
  614. Xdefined attributes, AFS complains if the number of user defined
  615. Xattributes attached to an ASO exceeds this limit. The constant
  616. X\fIAF_MAXUDAS\fR defined in \fIafs.h\fR defines the maximum number of
  617. Xuser defined attributes.
  618. X.IP "-31  AF_EWRONGSTATE wrong state"
  619. XSome AFS-operations can only be performed on ASOs with a specific version
  620. Xstate.
  621. X.RE
  622. X.PP
  623. XThe error codes indicating real trouble:
  624. X.IP "-32  AF_EDELTA Error during delta operation"
  625. XSome error occurred during
  626. Xinvocation of the delta processor.
  627. X.IP "-33  AF_EINCONSIST Archive file inconsistent"
  628. XThe data in the archive file are corrupted. This
  629. Xmay have happened by editing the archive file or by malfunction of an
  630. XAFS-operation.  Please inform your local trouble shooting service, go
  631. Xto your favorite pub and order a beer.
  632. X.IP "-34  AF_EINTERNAL internal error"
  633. XPlease inform your local trouble shooting service, go to your
  634. Xfavorite pub and order two beers.
  635. X.IP "-35  AF_ENOAFSFILE No AFS file"
  636. XArchive file missing.
  637. X.RE
  638. X.SH LIST OF FUNCTIONS
  639. X.ta 1.4i 2.8i
  640. X\fIName    Appears on Page    Description\fR
  641. X.sp
  642. Xaf_access    af_misc.3    test accessibility of ASO
  643. X.br
  644. Xaf_afname    af_misc.3    get ASO name from \s-1UNIX\s+1 path
  645. X.br
  646. Xaf_afpath    af_misc.3    get ASO syspath from \s-1UNIX\s+1 path
  647. X.br
  648. Xaf_aftype    af_misc.3    get ASO type from \s-1UNIX\s+1 path
  649. X.br
  650. Xaf_bpfind    af_retr.3    find derived objects by attributes
  651. X.br
  652. Xaf_chauthor    af_perm.3    change author of ASO
  653. X.br
  654. Xaf_chmod    af_perm.3    change access permissions of ASO
  655. X.br
  656. Xaf_chowner    af_perm.3    change owner of ASO
  657. X.br
  658. Xaf_cleanup    af_misc.3    do cleanup
  659. X.br
  660. Xaf_close    af_files.3    close ASO
  661. X.br
  662. Xaf_copyset    af_setops.3    copy sets
  663. X.br
  664. Xaf_crkey    af_files.3    create object key for \s-1UNIX\s+1\-file
  665. X.br
  666. Xaf_diff    af_setops.3    build difference between two sets of object keys
  667. X.br
  668. Xaf_dropkey    af_retrieve.3    drop object key
  669. X.br
  670. Xaf_dropset    af_sets.3    drop set of object keys
  671. X.br
  672. Xaf_find    af_retrieve.3    find ASOs by attributes
  673. X.br
  674. Xaf_gattrs    af_attrs.3    get all attributes of ASO
  675. X.br
  676. Xaf_getkey    af_retrieve.3    get key by unique attributes
  677. X.br
  678. Xaf_initattrs    af_retrieve.3    initialize attribute buffer
  679. X.br
  680. Xaf_initset    af_sets.3    initialize set
  681. X.br
  682. Xaf_intersect    af_setops.3    build intersection between two sets of object keys
  683. X.br
  684. Xaf_link    af_files.3    create a link between two ASOs
  685. X.br
  686. Xaf_lock    af_lock.3    set lock on ASO 
  687. X.br
  688. Xaf_newgen    af_versions.3    increase generation number of ASO
  689. X.br
  690. Xaf_nrofkeys    af_sets.3    return number of keys in set of object keys
  691. X.br
  692. Xaf_open    af_files.3    open ASO
  693. X.br
  694. Xaf_perror    af_misc.3    report AFS- or system error
  695. X.br
  696. Xaf_rauthor    af_perm.3    return author
  697. X.br
  698. Xaf_restore    af_files.3    restore derived ASO
  699. X.br
  700. Xaf_rgen    af_attr.3    return generation number of ASO
  701. X.br
  702. Xaf_rm    af_files.3    remove ASO
  703. X.br
  704. Xaf_rname    af_attrs.3    return name of ASO
  705. X.br
  706. Xaf_rnote    af_note.3    read note attribute 
  707. X.br
  708. Xaf_rowner    af_perm.3    return owner of ASO
  709. X.br
  710. Xaf_rrev    af_attr.3    return revision number of ASO
  711. X.br
  712. Xaf_rstate    af_versions.3    return version state of ASO
  713. X.br
  714. Xaf_rsyspath    af_attrs.3    return system path of ASO
  715. X.br
  716. Xaf_rtype    af_attrs.3    return type of ASO
  717. X.br
  718. Xaf_rudattr    af_udattrs.3    return user defined attribute
  719. X.br
  720. Xaf_rvariant    af_variant.3    return variant attribute
  721. X.br
  722. Xaf_savebinary    af_versions.3    save derived object
  723. X.br
  724. Xaf_saverev    af_versions.3    save busy version of source object
  725. X.br
  726. Xaf_setaddkey    af_sets.3    add key to set of object keys
  727. X.br
  728. Xaf_setarchpath    af_misc.3    set path for location of archives
  729. X.br
  730. Xaf_setbusy    af_versions.3    set version busy
  731. X.br
  732. Xaf_sgetkey    af_sets.3    get key from set of object keys
  733. X.br
  734. Xaf_setposrmkey    af_sets.3    remove key (id. by position) from set of object keys
  735. X.br
  736. Xaf_setrmkey    af_sets.3    remove key from set of object keys
  737. X.br
  738. Xaf_snote    af_note.3    set note attribute
  739. X.br
  740. Xaf_sortset    af_setops.3    sort set of object keys
  741. X.br
  742. Xaf_sstate    af_versions.3    set version state
  743. X.br
  744. Xaf_subset    af_setops.3    build subset of set of object keys
  745. X.br
  746. Xaf_sudattr    af_udattrs.3    set user defined attribute
  747. X.br
  748. Xaf_svariant    af_variant.3    set variant attribute
  749. X.br
  750. Xaf_svnum    af_versions.3    set version number
  751. X.br
  752. Xaf_testlock    af_lock.3    see if ASO is locked
  753. X.br
  754. Xaf_union    af_setops.3    build union of two sets of object keys
  755. X.br
  756. Xaf_unlock    af_lock.3    remove lock from ASO
  757. X.br
  758. Xaf_version    af_misc.3    return identification of current AFS version
  759. X.br
  760. X.SH FILES
  761. X/usr/adm/AFSerrlog (/tmp/AFSerrlog)
  762. X.SH SEE ALSO
  763. Xintro (2), intro (3)
  764. X.br
  765. XA. Lampen and A. Mahler, \(lqAn Object Base for Attributed
  766. XSoftware Objects,\(rq
  767. X.br
  768. X\fIProceedings of the Autumn '88 EUUG Conference\fR (Cascais, 3-7 October)
  769. X.br
  770. XEuropean UNIX system User Group, London 1988
  771. X.SH BUGS
  772. XThe built in archive file locking to prevent concurrent updates
  773. Xis very simple and my lead to confusing situations.
  774. XIt may happen that changes will not be saved to disk.
  775. XSee the error conditions \fIAF_EARCHANGED\fR and \fIAF_EARLOCKED\fR
  776. Xfor more details
  777. X.PP
  778. XThis is a draft version of the AFS-Manual.
  779. XIt may still be a bit vague or even uncomplete every here and there.
  780. XIf you have questions or suggestions, please mail them to the author.
  781. XNevertheless, I hope this manual will provide enough information
  782. Xto enable you to write AFS-applications. Happy hackin'!
  783. X.SH AUTHOR
  784. XAndreas Lampen, TU Berlin
  785. X.br
  786. X.ta 0.7i
  787. XUUCP:    unido!coma!andy
  788. X.br
  789. XBITNET:    andy@db0tui62
  790. END_OF_FILE
  791. if test 16204 -ne `wc -c <'man/man3/afintro.3'`; then
  792.     echo shar: \"'man/man3/afintro.3'\" unpacked with wrong size!
  793. fi
  794. # end of 'man/man3/afintro.3'
  795. fi
  796. if test -f 'src/vc/dosave.c' -a "${1}" != "-c" ; then 
  797.   echo shar: Will not clobber existing file \"'src/vc/dosave.c'\"
  798. else
  799. echo shar: Extracting \"'src/vc/dosave.c'\" \(16567 characters\)
  800. sed "s/^X//" >'src/vc/dosave.c' <<'END_OF_FILE'
  801. X/*
  802. X * Copyright (C) 1989, 1990 W. Koch, A. Lampen, A. Mahler, W. Obst,
  803. X *  and U. Pralle
  804. X * 
  805. X * This software is published on an as-is basis. There is ABSOLUTELY NO
  806. X * WARRANTY for any part of this software to work correctly or as described
  807. X * in the manuals. We do not accept any liability for any kind of damage
  808. X * caused by use of this software, such as loss of data, time, money, or 
  809. X * effort.
  810. X * 
  811. X * Permission is granted to use, copy, modify, or distribute any part of
  812. X * this software as long as this is done without asking for charge, and
  813. X * provided that this copyright notice is retained as part of the source
  814. X * files. You may charge a distribution fee for the physical act of
  815. X * transferring a copy, and you may at your option offer warranty
  816. X * protection in exchange for a fee.
  817. X * 
  818. X * Direct questions to: Tech. Univ. Berlin
  819. X *              Wilfried Koch
  820. X *              Sekr. FR 5-6 
  821. X *              Franklinstr. 28/29
  822. X *              D-1000 Berlin 10, West Germany
  823. X * 
  824. X *              Tel: +49-30-314-22972
  825. X *              E-mail: shape@coma.uucp or shape@db0tui62.bitnet
  826. X */
  827. X#ifndef lint
  828. Xstatic char *AFSid = "$Header: dosave.c[3.21] Thu Feb 23 18:13:30 1989 axel@coma published $";
  829. X#ifdef CFFLGS
  830. Xstatic char *ConfFlg = CFFLGS;
  831. X    /* should be defined from within Makefile */
  832. X#endif
  833. X#endif
  834. X/*
  835. X * Log for /u/shape/dist-tape/src/vc/dosave.c[3.8]
  836. X *     Thu Feb 23 18:13:30 1989 axel@coma save $
  837. X *  Intention for change:
  838. X *  This is still a test. A minute ago, I was able to set an intention
  839. X *  but now I doubt, that I'll be allowed to set a user defined attribute
  840. X *  to the bus
  841. X *  dosave.c[3.9] Thu Feb 23 18:13:30 1989 axel@coma save $
  842. X *  Intention for change:
  843. X *  This is still a test. A minute ago, I was able to set an intention
  844. X *  but now I doubt, that I'll be allowed to set a user defined attribute
  845. X *  to the bus
  846. X *  dosave.c[3.15] Thu Feb 23 18:13:30 1989 axel@coma published $
  847. X *  --- empty log message ---
  848. X *  dosave.c[3.19] Thu Feb 23 18:13:30 1989 axel@coma published $
  849. X *  --- empty log message ---
  850. X *  dosave.c[3.20] Thu Feb 23 18:13:30 1989 axel@coma save $
  851. X *  --- empty log message ---
  852. X *  dosave.c[3.21] Thu Feb 23 18:13:30 1989 axel@coma published $
  853. X *  --- empty log message ---
  854. X */
  855. X
  856. X#include <strings.h>
  857. X#include <stdio.h>
  858. X#include <pwd.h>
  859. X#include "afs.h"
  860. X#include "save.h"
  861. X#include <sys/types.h>
  862. X#include <sys/stat.h>
  863. X#include "project.h"
  864. X#include "locks.h"
  865. X
  866. Xextern unsigned int options;
  867. Xextern char tfname[], vcomment[], atr_fname[], symname[];
  868. Xextern int newvnum;
  869. Xextern struct Transaction ThisTransaction;
  870. X
  871. XSaveAFile (fname, proj) char *fname; Project *proj; {
  872. X/*
  873. X * Save working file with the given name in the project location (syspath)
  874. X * determined by proj. Check for changes before saving.
  875. X * Attributes are also derived from the proj-context.
  876. X * Unless QUIETPLEASE is set, the user will be prompted for a note 
  877. X * describing the changes to be saved.
  878. X * On the locking strategy:
  879. X * An author can save a busy version, only if he holds a lock (update
  880. X * privilege) for the document history. When an archive is newly
  881. X * created from a (busy) file, such a lock is assumed to be set.
  882. X * Upon save operations - which are conceptually local to a user context -
  883. X * the lock is kept. A lock can be released by submitting a version
  884. X * to the project and explicitly giving up the lock (option). After that,
  885. X * no more 'saves' are possible even though the user is in unix sense still
  886. X * owner of his local archive-file. This is so because we guarantee object
  887. X * consistency in a project among several databases.
  888. X * Locks on certain documents can be obtained through means of 'reserve'
  889. X * which is a User <--> Project transaction. Locally created documents
  890. X * are placed under project discipline (or configuration control) the
  891. X * first time they are submitted -- even if they have not been reserved
  892. X * yet. Locks have token-character, i.e. they may be passed around, but
  893. X * never ever be duplicated.
  894. X */
  895. X /*
  896. X  *  NOTE: use of variant attribute in af_getkey is not yet functional.
  897. X  *        The parameter, however, is necessary to occupy the slot.
  898. X  *        Implementation of variant selection may make it necessary
  899. X  *        to add another parameter to this procedure.
  900. X  */
  901. X  char spath[MAXNAMLEN], origpath[MAXNAMLEN], name[MAXNAMLEN], 
  902. X  *afname, *aftype, *afvariant = NULL, str[80], messg[80], *note, 
  903. X  *getnote(), *gettxt(), *vnum(), *getattr(), *as;
  904. X  int truth = TRUE;
  905. X  Af_attrs reqattrs, busyattrs, sattrs;
  906. X  Af_key busy, lastsave, skey, *newkey, ngkey, tmpkey;
  907. X  Af_set junkset;
  908. X
  909. X  if (!fname) return;
  910. X  
  911. X  af_initattrs (&reqattrs);
  912. X  getsyspath (fname, proj, spath, origpath, name); 
  913. X               /* splits name and pathname prefix */
  914. X
  915. X  afname = af_afname (name);
  916. X  aftype = af_aftype (name);
  917. X  /* give a little feedback ... */
  918. X  if (spath[0]) {
  919. X    (void)sprintf (messg, "[%s]%s:", spath, name);
  920. X  }
  921. X  else {
  922. X    (void)sprintf (messg, "%s:", name);
  923. X  }
  924. X  logmsg (messg);
  925. X  
  926. X  if (options & SYMNSET) {
  927. X    af_initattrs (&sattrs);
  928. X    (void)strcpy (sattrs.af_syspath, spath);
  929. X    (void)strcpy (sattrs.af_name, afname);
  930. X    (void)strcpy (sattrs.af_type, aftype);
  931. X    (void)sprintf (str, "%s=%s", SYMNAME, symname);
  932. X    sattrs.af_udattrs[0] = str;
  933. X    sattrs.af_udattrs[1] = NULL;
  934. X    af_find (&sattrs, &junkset);
  935. X    if (af_nrofkeys(&junkset)) {
  936. X      af_setgkey (&junkset, 0, &tmpkey);
  937. X      (void)sprintf (messg, "symbolic name %s already in use by %s[%s]", 
  938. X           symname, fname, vnum(&tmpkey));
  939. X      logerr (messg);
  940. X      af_dropset (&junkset);
  941. X      af_dropkey (&tmpkey);
  942. X      abort_this (FALSE);
  943. X    }
  944. X    else {
  945. X      af_cleanup ();        /* ??? */
  946. X    }
  947. X  }
  948. X  if (fail(af_getkey (spath, afname, aftype, AF_BUSYVERS, 
  949. X              AF_BUSYVERS, afvariant, &busy))) {
  950. X    (void)sprintf (messg, "%s[busy]", fname);
  951. X    af_perror (messg);
  952. X    abort_this (TRUE);
  953. X  }
  954. X
  955. X  if (fail(af_gattrs (&busy, &busyattrs))) {
  956. X    (void)sprintf (messg, "Cannot access attributes of %s.", name);
  957. X    af_perror (messg);
  958. X    af_dropkey (&busy);
  959. X    abort_this(TRUE);
  960. X  }
  961. X  if (fail(af_getkey (spath, afname, aftype, AF_LASTVERS,
  962. X              AF_LASTVERS, afvariant, &lastsave))) {
  963. X    logmsg ("creating archive");
  964. X    if (options & TXTFSET) {
  965. X      note = gettxt (tfname);
  966. X    }
  967. X    else {
  968. X      note = getnote ("How about describing the purpose of this document ?", 
  969. X              truth, TRUE, (char *)NULL);
  970. X    }
  971. X    if (lockeruid(vc_lock_g(&busy, (Uid_t)getuid())) != (Uid_t)getuid()) {
  972. X      af_perror ("cannot lock archive");
  973. X      af_dropkey (&busy);
  974. X      abort_this (TRUE);
  975. X    }
  976. X    if (fail(af_saverev (&busy, &skey))) {
  977. X      af_perror (fname);
  978. X      af_dropkey (&busy);
  979. X      abort_this(TRUE);
  980. X    }
  981. X    newkey = &skey;
  982. X    ThisTransaction.tr_done = TRUE;
  983. X    if (options & SUBMIT) {
  984. X      af_sstate (newkey, AF_PROPOSED);
  985. X      af_sstate (newkey, AF_PUBLISHED);
  986. X    }
  987. X    (void)sprintf (messg, "saved version %s", vnum (newkey));
  988. X    logmsg (messg);
  989. X  }    /* This was handling of newly created archive */
  990. X  else {
  991. X#ifdef PROJIMPL
  992. X    if (!mylock (&busy, proj)) /* { */ /* -- emacs c-mode */
  993. X#else
  994. X      if (!mylock (&busy, (Project *)NULL)) {
  995. X#endif
  996. X    (void)sprintf (messg, "%s not saved.", fname);
  997. X    logmsg (messg);
  998. X    af_dropkey (&busy);
  999. X    abort_this (FALSE);
  1000. X      }
  1001. X    if (changed (&busy, &lastsave, &truth)) { 
  1002. X      /* Version alias problem: copy or ref */
  1003. X      if (options & TXTFSET) {
  1004. X    note = gettxt (tfname);
  1005. X      }
  1006. X      else if (options & MSGSET) {
  1007. X    note = vcomment;
  1008. X      }
  1009. X      else {
  1010. X    char *intent = (char *)0;
  1011. X    if (options & (LCKGIVEUP | SUBMIT))
  1012. X      intent = af_rudattr (&busy, INTENT);
  1013. X    note = getnote ("Do you want to comment your modifications ?", truth, 
  1014. X            FALSE, intent);
  1015. X    if (intent) free (intent);
  1016. X    af_sudattr (&busy, AF_REMOVE, INTENT);
  1017. X      }
  1018. X      if (fail(af_saverev (&busy, &skey))) {
  1019. X    af_perror (fname);
  1020. X    af_dropkey (&busy);
  1021. X    abort_this(TRUE);
  1022. X      }
  1023. X      newkey = &skey;
  1024. X      ThisTransaction.tr_done = TRUE;
  1025. X      af_sudattr (newkey, AF_REMOVE, INTENT);
  1026. X      if (options & NEWGEN) {
  1027. X    if (myproject(proj)) {
  1028. X      af_newgen (newkey, &ngkey);
  1029. X      (void)sprintf (messg, 
  1030. X           "saved version %s (aliassed by ",
  1031. X           vnum (newkey));
  1032. X      (void)sprintf (messg, "%s%s due to new generation)", messg, vnum(&ngkey)); 
  1033. X      logmsg (messg);
  1034. X      af_dropkey (newkey);
  1035. X      newkey = &ngkey;
  1036. X      if (options & SUBMIT)
  1037. X        setpublished (newkey);
  1038. X    }
  1039. X    else {
  1040. X      logmsg ("You must be project-admin to increase generation number.");
  1041. X    }
  1042. X      }
  1043. X      else {
  1044. X    (void)sprintf (messg, "saved version %s", vnum (newkey));
  1045. X    logmsg (messg);
  1046. X    if (options & SUBMIT) 
  1047. X      setpublished (newkey);
  1048. X      }
  1049. X    }
  1050. X    else {
  1051. X      if (options & SUBMIT) {
  1052. X    char *intent = (char *)0;
  1053. X    intent = af_rudattr (&busy, INTENT);
  1054. X    note = getnote ("Do you want to comment your modifications ?", truth,
  1055. X            FALSE, intent);
  1056. X    if (intent) free (intent);
  1057. X    af_sudattr (&busy, AF_REMOVE, INTENT);
  1058. X    setpublished (&lastsave);
  1059. X    (void)sprintf 
  1060. X      (messg, "%s set to state \"published\" (no changes to be saved)",
  1061. X       fname);
  1062. X    logmsg (messg);
  1063. X    newkey = &lastsave;
  1064. X      }
  1065. X      else {
  1066. X    (void)sprintf (messg, "%s not saved.", fname);
  1067. X    logmsg (messg);
  1068. X    af_dropkey (&busy);
  1069. X    abort_this(FALSE);
  1070. X      }
  1071. X    }
  1072. X  }
  1073. X  /* If we get here, something has been saved -- set note */
  1074. X  if (fail(af_snote (newkey, note))) {
  1075. X    af_perror ("");
  1076. X  }
  1077. X  if (options & SYMNSET) {
  1078. X    (void)sprintf (str, "%s=%s", SYMNAME, symname);
  1079. X    as = str;
  1080. X    af_sudattr (newkey, AF_ADD, as);
  1081. X  }
  1082. X  if (options & SETVNUM) {
  1083. X    if (!(mkvno(vnum(newkey)) == newvnum)) { /* do nothing */
  1084. X      if (af_svnum (newkey, gen(newvnum), rev(newvnum)) < 0) {
  1085. X    (void)sprintf (messg, "version number %d.%d too small for %s.",
  1086. X         gen(newvnum), rev(newvnum), fname );
  1087. X    logerr (messg);
  1088. X      }
  1089. X    }
  1090. X  }
  1091. X  if (options & ATTRDEF) {
  1092. X    as = getattr (atr_fname, proj, aftype, REWIND);
  1093. X    af_sudattr (newkey, AF_ADD, as);
  1094. X    while (as=getattr (atr_fname, proj, aftype, NEXT)) {
  1095. X      af_sudattr (newkey, AF_ADD, as);
  1096. X    }
  1097. X  }
  1098. X  if (options & LCKGIVEUP) {
  1099. X    if ((lockeruid(vc_unlock_g(&busy))) != (Uid_t)getuid()) {
  1100. X      af_perror ("af_unlock: foul");
  1101. X    }
  1102. X  }
  1103. X  /* right before we are done, release the version lock on new version */
  1104. X  (void)vc_unlock_v(newkey);
  1105. X  af_dropkey (newkey);
  1106. X  af_dropkey (&busy);
  1107. X}
  1108. X
  1109. Xchanged (new, old, realtruth) Af_key *new, *old; int *realtruth; {
  1110. X/*
  1111. X * Return true if new and old are actually different OR deposit is
  1112. X * forced OR if user says 'yes' when asked whether an unchanged version
  1113. X * shall be saved anyway.
  1114. X * As AFS is still in the tests, this is programmed very defensively.
  1115. X */
  1116. X  FILE *newf, *oldf;
  1117. X  Af_attrs newat, oldat;
  1118. X  char *news, *olds, *malloc(), messg[80];
  1119. X
  1120. X  *realtruth = TRUE;  /* initially assume that something has act. changed */
  1121. X  if (fail(af_gattrs (new, &newat))) {
  1122. X    af_perror ("busy-version");
  1123. X  }
  1124. X  if (fail(af_gattrs (old, &oldat))) {
  1125. X    af_perror ("lastsaved-version");
  1126. X  }
  1127. X  if (newat.af_size != oldat.af_size) {
  1128. X    return TRUE;
  1129. X  }
  1130. X  else { /* lets have a closer look at 'em */
  1131. X    if ((news = malloc ((unsigned)newat.af_size)) == NULL) {
  1132. X      (void)sprintf (messg, "Can't malloc %d bytes.", newat.af_size);
  1133. X      logmsg (messg);
  1134. X      abort_this(TRUE);
  1135. X    }
  1136. X    if ((olds = malloc ((unsigned)oldat.af_size)) == NULL) {
  1137. X      (void)sprintf (messg, "Can't malloc %d bytes.", oldat.af_size);
  1138. X      logmsg (messg);
  1139. X      free (news);
  1140. X      abort_this(TRUE);
  1141. X    }
  1142. X    if ((newf = af_open (new, "r")) == NULL) {
  1143. X      af_perror ("busy-version");
  1144. X      free (news);
  1145. X      free (olds);
  1146. X      abort_this(TRUE);
  1147. X    }
  1148. X    if ((oldf = af_open (old, "r")) == NULL) {
  1149. X      af_perror ("lastsaved-version");
  1150. X      free (news);
  1151. X      free (olds);
  1152. X      af_close (newf);
  1153. X      abort_this(TRUE);
  1154. X    }
  1155. X#ifdef ULTRIX_2_0
  1156. X    if (fread (news, sizeof (char), (unsigned)newat.af_size, newf) == NULL)
  1157. X#else
  1158. X    if (fread (news, sizeof (char), (int)newat.af_size, newf) == NULL) 
  1159. X#endif
  1160. X      {
  1161. X      logmsg ("Couldn't read busy version.");
  1162. X      free (news);
  1163. X      free (olds);
  1164. X      af_close (newf);
  1165. X      af_close (oldf);
  1166. X      abort_this (TRUE);
  1167. X    }
  1168. X#ifdef ULTRIX_2_0
  1169. X    if (fread (olds, sizeof (char), (unsigned)oldat.af_size, oldf) == NULL) 
  1170. X#else
  1171. X    if (fread (olds, sizeof (char), (int)oldat.af_size, oldf) == NULL) 
  1172. X#endif
  1173. X      {
  1174. X      logmsg ("Couldn't read lastsaved version.");
  1175. X      free (news);
  1176. X      free (olds);
  1177. X      af_close (newf);
  1178. X      af_close (oldf);
  1179. X      abort_this (TRUE);
  1180. X    }
  1181. X    af_close (newf);
  1182. X    af_close (oldf);
  1183. X    free (news);
  1184. X    free (olds);
  1185. X    if (bcmp (olds, news, (int)newat.af_size)) {
  1186. X      return TRUE;
  1187. X    }
  1188. X    else {  /* Hmmm, looks like nothing has changed ... */
  1189. X      *realtruth = FALSE; /* return value may be a lie */
  1190. X      if (options & FORCE) {
  1191. X    return TRUE;
  1192. X      }
  1193. X      else {
  1194. X    if (options & QUIETPLEASE) {
  1195. X      return FALSE;
  1196. X    }
  1197. X    if (isatty (fileno (stdin)) && isatty (fileno (stdout))) {
  1198. X      (void)sprintf (messg, "There are no changes with respect to the previously saved version.\nSave anyway ?");
  1199. X      return !ask_confirm (messg, "no");
  1200. X    }
  1201. X    else return FALSE;
  1202. X      }
  1203. X    }
  1204. X  }
  1205. X}
  1206. X
  1207. Xchar *gettxt (fname) char *fname; {
  1208. X  static char *txt = EMPTYNOTE;
  1209. X  FILE *txtfil;
  1210. X  struct stat statbuf;
  1211. X  static int firsttime = TRUE;
  1212. X
  1213. X  if (firsttime) {
  1214. X    firsttime = FALSE;
  1215. X    if ((txtfil = fopen (fname, "r")) == NULL) {
  1216. X      logerr ("no descriptive text file");
  1217. X    }
  1218. X    else {
  1219. X      if (fstat (fileno(txtfil), &statbuf) == -1) {
  1220. X    perror ("couldn't stat");
  1221. X      }
  1222. X      else {
  1223. X    txt = malloc ((unsigned)statbuf.st_size);
  1224. X    if (!txt) {
  1225. X      logerr ("not enough memory for descriptive text.");
  1226. X      txt = EMPTYNOTE;
  1227. X    }
  1228. X    else {
  1229. X      (void)fread (txt, sizeof (char), (Size_t)statbuf.st_size, txtfil);
  1230. X      (void)fclose (txtfil);
  1231. X    }
  1232. X      }
  1233. X    }
  1234. X  }
  1235. X  return txt;
  1236. X}
  1237. X
  1238. Xchar *getnote (prompt, changeflg, force, intent) char *prompt, *intent; {
  1239. X  char *tmpname, *mktemp(), *edname, cmd[128], *getenv(), messg[80];
  1240. X  static char *notetxt;
  1241. X  FILE *tmpfil;
  1242. X  struct stat statbuf;
  1243. X  static int firsttime = TRUE;
  1244. X
  1245. X  if ((options & QUIETPLEASE) ||
  1246. X      (!(isatty(fileno(stdin))))) {
  1247. X    if (intent) goto retintent;
  1248. X    else return EMPTYNOTE;
  1249. X  }
  1250. X  if ((!force) && (!firsttime) && notetxt) {
  1251. X    if (ask_confirm ("Use previous log message ?", "yes")) {
  1252. X      return notetxt;
  1253. X    }
  1254. X    else {
  1255. X      free (notetxt);
  1256. X    }
  1257. X  }
  1258. X  firsttime = FALSE;
  1259. X  if (changeflg) {
  1260. X    if (!ask_confirm (prompt, "yes"))
  1261. X      if (intent) goto retintent;
  1262. X      else return EMPTYNOTE;
  1263. X  }
  1264. X  else {
  1265. X    if (ask_confirm ("The new version is unmodified. Comment it anyway ?", 
  1266. X             "no"))
  1267. X      if (intent) goto retintent;
  1268. X      else return EMPTYNOTE;
  1269. X  }
  1270. X  tmpname = mktemp ("/tmp/afsXXXXXX");
  1271. X  Register (tmpname, TYPEF);
  1272. X  if (intent) {
  1273. X    FILE *tfd;
  1274. X    tfd = fopen (tmpname, "w");
  1275. X    if (fwrite (intent, strlen (intent), sizeof (char), tfd) != 
  1276. X    strlen (intent)) {
  1277. X      logerr ("write failure on tmp-file");
  1278. X    }
  1279. X    (void)fclose (tfd);
  1280. X  }
  1281. X  if (edname = getenv ("EDITOR")) {
  1282. X    (void)sprintf (cmd, "%s %s", edname, tmpname);
  1283. X    (void)sprintf (messg, "starting up %s ...", edname);
  1284. X    logmsg (messg);
  1285. X    if (system (cmd) == NOSHELL) {
  1286. X      logerr ("couldn't execute shell");
  1287. X    }
  1288. X    else {
  1289. X      if ((tmpfil = fopen (tmpname, "r")) == NULL) {
  1290. X    logerr ("empty logentry");
  1291. X    return EMPTYNOTE;
  1292. X      }
  1293. X      else {
  1294. X    (void)unlink (tmpname);
  1295. X    UnRegister (tmpname, TYPEF);
  1296. X    if (fstat (fileno(tmpfil), &statbuf) == -1) {
  1297. X      perror ("couldn't stat");
  1298. X    }
  1299. X    else {
  1300. X      notetxt = malloc ((unsigned)statbuf.st_size);
  1301. X      if (!notetxt) {
  1302. X        logerr ("not enough memory for note text.");
  1303. X      }
  1304. X      (void)fread (notetxt, sizeof (char), (Size_t)statbuf.st_size, 
  1305. X               tmpfil);
  1306. X      (void)fclose (tmpfil);
  1307. X      return notetxt;
  1308. X    }
  1309. X      }
  1310. X    }
  1311. X  }
  1312. X  logerr ("You must set the EDITOR environment variable to write a note");
  1313. X  return EMPTYNOTE;   /* maybe we should try to read from stdin */
  1314. X retintent:
  1315. X  notetxt = malloc ((unsigned)(strlen (intent) + 1));
  1316. X  (void)strcpy (notetxt, intent);
  1317. X  return notetxt;
  1318. X}
  1319. X
  1320. Xsetpublished (key) Af_key *key; {
  1321. X  /* set specified version to state 'published' */
  1322. X
  1323. X  int sdiff, oldstate = af_rstate (key);
  1324. X  register int i;
  1325. X
  1326. X  if (sdiff = (AF_PUBLISHED - oldstate)) {
  1327. X    if (sdiff > 0)
  1328. X      for (i = 1; i <= sdiff; i++) {
  1329. X    if ((lockeruid(vc_lock_v(key, (Uid_t)getuid()))) != (Uid_t)getuid()) {
  1330. X      logerr ("can't change state to published -- locked");
  1331. X      return;
  1332. X    }
  1333. X    af_sstate (key, oldstate+i);
  1334. X    (void)vc_unlock_v(key);
  1335. X      }
  1336. X    else /* sdiff must be < 0 */
  1337. X      for (i = 1; i <= abs(sdiff); i++) {
  1338. X    if ((lockeruid(vc_lock_v(key, (Uid_t)getuid()))) != (Uid_t)getuid()) {
  1339. X      logerr ("can't change state to published -- locked");
  1340. X      return;
  1341. X    }
  1342. X    af_sstate (key, oldstate-i);
  1343. X    (void)vc_unlock_v(key);
  1344. X      }
  1345. X  }
  1346. X  /* else: state already is published */
  1347. X}
  1348. END_OF_FILE
  1349. if test 16567 -ne `wc -c <'src/vc/dosave.c'`; then
  1350.     echo shar: \"'src/vc/dosave.c'\" unpacked with wrong size!
  1351. fi
  1352. # end of 'src/vc/dosave.c'
  1353. fi
  1354. echo shar: End of archive 17 \(of 33\).
  1355. cp /dev/null ark17isdone
  1356. MISSING=""
  1357. 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
  1358.     if test ! -f ark${I}isdone ; then
  1359.     MISSING="${MISSING} ${I}"
  1360.     fi
  1361. done
  1362. if test "${MISSING}" = "" ; then
  1363.     echo You have unpacked all 33 archives.
  1364.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1365. else
  1366.     echo You still need to unpack the following archives:
  1367.     echo "        " ${MISSING}
  1368. fi
  1369. ##  End of shell archive.
  1370. exit 0
  1371.