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

  1. Subject:  v19i035:  A software configuration management system, Part22/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 35
  8. Archive-name: shape/part22
  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 22 (of 33)."
  19. # Contents:  man/man1/vcintro.1 src/vc/vadm.c
  20. # Wrapped by rsalz@papaya.bbn.com on Thu Jun  1 19:27:14 1989
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'man/man1/vcintro.1' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'man/man1/vcintro.1'\"
  24. else
  25. echo shar: Extracting \"'man/man1/vcintro.1'\" \(23895 characters\)
  26. sed "s/^X//" >'man/man1/vcintro.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: vcintro.1[1.1] Thu Feb 23 18:14:37 1989 axel@coma published $
  55. X... 
  56. X... Log for /u/shape/dist-tape/src/vc/vcintro.1[1.0]
  57. X...     Thu Feb 23 18:14:37 1989 axel@coma published $
  58. X...  --- empty log message ---
  59. X...  vcintro.1[1.1] Thu Feb 23 18:14:37 1989 axel@coma published $
  60. X...  --- empty log message ---
  61. X...
  62. X.UC
  63. X.TH VCINTRO 1 vcintro \n(dy.\n(mo.\n(yr
  64. X.SH NAME
  65. Xvcintro \- introduction to the version control system of the shape toolkit
  66. X.SH DESCRIPTION
  67. XThe version control commands of the shape toolkit are useful to manage
  68. Xmultiple revisions of \fIsource objects\fR (usually ASCII text files
  69. Xbut not limited to) as well as multiple instances of \fIderived
  70. Xobjects\fR (usually produced by compiling one ore more source
  71. Xobjects).  The version control system allows the storing, retrieval,
  72. Xlogging, and identification of revisions. All objects are stored in an
  73. Xobject base that resides in a subdirectory with the name \fIAFS\fR.
  74. X.PP
  75. XConsequent use of version control is the prerequisite for
  76. Xconfiguration management and software maintenance.  Using the version
  77. Xcontrol system also eases cooperation within a programmer team, and even
  78. Xsupports individual working styles, such as saving intermediate work
  79. Xresults that may be backed up to, if modifications turn out to be
  80. Xunsatisfying.
  81. X.PP
  82. XThe following introductory overview of shape's version control system 
  83. Xuses a terminology that tries to be as intuitive as possible. However, as
  84. Xterminology is quite different from the well known notions of the UNIX
  85. Xfilesystem, you might eventually find yourself confused. If this is the
  86. Xcase, go to the end of this manual and read the section about the 
  87. Xobject base and related terminology.
  88. X.PP
  89. XThe basic user interface consists of a number of simple commands.
  90. XThe novice user only needs to know three of them: \fBsave\fR, \fBretrv\fR,
  91. Xand \fBvl\fR. \fBsave\fR stores the contents of a specified
  92. Xfile as a \fIversion\fR in the object base. \fBretrv\fR, short for
  93. X\(lqretrieve\(rq, retrieves versions from the object base. \fBvl\fR,
  94. Xshort for \(lqversion list\(rq, lists the contents of the object base.
  95. XWhile these three commands may suffice to serve the needs of single-programmer
  96. Xprojects, shape's version control system also
  97. Xoffers more sophisticated support for larger projects that
  98. Xemploy programmer teams.
  99. X.PP
  100. X\fBFunctions of the version control system\fR
  101. X.IP \(bu 0.2i
  102. XStorage and retrieval of multiple revisions of design objects.
  103. XAll revisions are stored in a space efficient manner. Changes
  104. Xno longer destroy possibly worthwhile status of the original,
  105. Xbecause previous revisions remain accessible. Revisions can
  106. Xbe retrieved from the object base according to revision numbers, 
  107. Xsymbolic names, states, and arbitrary attribute patterns.
  108. X.IP \(bu
  109. XBuilt in automatic status model for revisions. Each revision
  110. Xis in one of the states \fIbusy, saved, proposed, published, accessed, \fRor
  111. X\fIfrozen\fR, according to its quality and access status. State
  112. Xtransitions happen (semi-) automatically upon invocation of certain
  113. Xcommands (\fBsave\fR, \fBsbmt\fR, \fBaccpt\fR, \fBrjct\fR, \fBrelease\fR).
  114. XThis status model helps to organize larger, multi-programmer projects.
  115. X.IP \(bu
  116. XMaintenance of a complete history of changes. Besides the contents of each
  117. Xrevision, the version control system stores the author, date and time
  118. Xof the save operation, and a log message summarizing the changes as
  119. Xattributes of the newly created version object. The version control
  120. Xsystem distinguishes saving of intermediate work status and
  121. Xsubmitting final work results to the project. In the latter case,
  122. Xthe log message is initialized with the description of the planned
  123. Xchange which is acquired upon reservation of the update privilege for
  124. Xthe design object.
  125. X.IP \(bu
  126. XResolution of access conflicts. When two or more programmers whish
  127. Xto modify the same design object, the version control system
  128. Xalerts the programmers and prevents them from mutually corrupt each
  129. Xother's modifications.
  130. X.IP \(bu
  131. XComprehensive support for configuration control. Revisions can be
  132. Xassigned symbolic names that typically are shared among all component
  133. Xrevisions of a configuration. Moreover, the version control system
  134. Xis fully integrated with \fBshape\fR, the configuration identification
  135. Xand building tool.
  136. X.IP \(bu
  137. XAutomatic identification of each revision with name, version number, 
  138. Xsave date, author etc. The identification is like a stamp that can
  139. Xbe embedded at an appropriate place in the contents of a design object.
  140. XThe identification makes it simple to determine which revisions have
  141. Xbeen included in a given configuration.
  142. X.sp 3p
  143. X.PP
  144. X\fBGetting started with the shape toolkit\fR
  145. X.PP
  146. XBefore you can use any of the version control facilities, you should
  147. Xcreate a subdirectory \fIAFS\fR in order to have an initial location
  148. Xfor the version object base.
  149. XNow, suppose you have a file \(lqxyzzy.c\(rq that you whish to put under version
  150. Xcontrol. To do this, just invoke the \fBsave\fR command
  151. X.DS
  152. X\fCsave xyzzy.c\fR
  153. X.DE
  154. XThis command creates an entry for \(lqxyzzy.c\(rq in the object base. Before
  155. Xthe first version of a design object is created, \fBsave\fR asks
  156. Xfor a short description of the object's purpose. This description
  157. Xshould be a synopsis of the contents. All later \fBsave\fR commands
  158. Xwill ask for a log, which should describe the changes that 
  159. Xhave been made. If you issue the command \fBvl\fR, you should get 
  160. Xsomething like
  161. X.DS
  162. X.nf
  163. X\fCxyzzy.c    xyzzy.c[1.0]\fR
  164. X.fi
  165. X.DE
  166. Xindicating, that you now have a busy version and a
  167. Xrevision 1.1 of of \(lqxyzzy.c\(rq. After saving a revision of a file,
  168. Xone automatically owns a \fIlock\fR for the entire object history.
  169. XA locks represents the exclusive privilege to add new revisions
  170. Xto the object history. This makes sure that no other author in a project
  171. Xyou are working on, can interfere with your work. 
  172. X.PP
  173. XYou may retrieve revisions from the object base with the \fBretrv\fR command.
  174. X.DS
  175. X\fCretrv xyzzy.c\fR
  176. X.DE
  177. Xfetches the latest revision of \(lqxyzzy.c\(rq from the object base
  178. Xand installs it in the current working directory. As this operation
  179. Xmight overwrite a current busy version, \fBretrv\fR asks for permission
  180. Xto do so. In case you just want to have a look at the saved revision
  181. Xwithout overwriting the busy version you should rather type
  182. X.DS
  183. X\fCvcat xyzzy.c\fR
  184. X.DE
  185. Xthan invoke \fBretrv\fR. The \fBvcat\fR command simply prints the 
  186. Xcontents of the revision on the screen (standard output). As is the
  187. Xcase with \fBvl\fR, this command also tries to resemble regular UNIX
  188. Xcommands that do similar things. 
  189. X.PP
  190. XJust retrieving a revision from the object base is not sufficient
  191. Xif you whish to modify that revision and save it back into the 
  192. Xobject base at a later time. Precisely, \fBretrv\fR in its plain
  193. Xform doesn't set a lock on the object history, which is necessary
  194. Xin order to add a new revision to it. Accordingly, the access
  195. Xmode of the file containing the retrived revision is set to \fIread only\fR.
  196. XIf you whish to create a new revision on the basis of some saved
  197. Xversion in the object base, you should retrieve it with
  198. X.DS
  199. X\fCretrv -lock xyzzy.c\fR
  200. X.DE
  201. XIf \(lqxyzzy.c\(rqs object history is not locked by anybody else,
  202. X\fBretrv\fR will ask for a description of the changes you plan to
  203. Xmake, and installs the retrieved revision as busy version in the
  204. Xdirectory containing the object base (this is necessary to keep
  205. Xthe defined relationship between the busy version and the corresponding
  206. Xobject history). It may happen from time to time that you applied
  207. Xchanges to a (supposedly) busy version of a design object without
  208. Xholding a lock for it. In this case you probably don't want your
  209. Xchanges to be overwritten by a newly installed busy version created
  210. Xby \fCretrv -lock\fR. Instead, invoke
  211. X.DS
  212. X\fCvadm -lock xyzzy.c\fR
  213. X.DE
  214. XThis command tries to set the necessary lock subsequently. If, however,
  215. Xsome other author has locked the object history in the meantime, you
  216. Xare in limbo. To get out of this dilemma is only possible by using
  217. Xhuman interaction. Locking assures that you, and only you, can save
  218. Xthe next update of a design object, and avoids nasty problems if 
  219. Xseveral people are working on the same project, possibly on the same
  220. Xdesign object. Even if an object history is locked, revisions can
  221. Xstill be retrieved for reading, compiling etc. All that locking 
  222. Xprevents is a save operation by anybody but the locker.
  223. X.PP
  224. X\fBvadm\fR is a general purpose command, used to manipulate the 
  225. Xversion object base in various ways. If any of the simpler commands
  226. X(\fBsave\fR, \fBretrv\fR, and \fBvl\fR) can't serve a particular need
  227. Xthat you might have in mind (delete revisions, change the state or
  228. Xother attributes of a revision, modify logentries etc.), 
  229. X\fBvadm\fR probably can. Check the manual pages for details. 
  230. X.PP
  231. XAfter having used version control commands for a while, you might
  232. Xhave quite a lot of revisions in each object history. The \fBvl\fR
  233. Xcommand might print something like
  234. X.DS
  235. X.nf
  236. X\fCefg.c        fgh.c        fgh.c[1.3]    xyz.c[1.1]
  237. Xefg.c[1.0]    fgh.c[1.0]    fgh.c[1.4]    xyz.c[1.2]
  238. Xefg.c[1.1]    fgh.c[1.1]    xyz.c        xyzzy.c
  239. Xefg.c[1.2]    fgh.c[1.2]    xyz.c[1.0]    xyzzy.c[1.0]\fR
  240. X.fi
  241. X.DE
  242. XWhile most version control commands by default access the most recent revision
  243. Xit is possible to reference any revision by explicitly specifying 
  244. Xits respective revision number. This can be done in either of two 
  245. Xways, common to all version control commands. The command option
  246. X\fI-V<version>\fR specifies an explicit default revision number.
  247. XFor example, the command:
  248. X.DS
  249. X.nf
  250. X\fCvl -l -V 1.2 
  251. X.fi 
  252. X.DE
  253. Xprints more detailed information about revision 1.2 of all object 
  254. Xhistories:
  255. X.DS
  256. X.nf
  257. X\fC-rw-r--r-- s axel@coma       437 Nov  2 01:21:46 1988 efg.c[1.2]
  258. X-rw-r--r-- P axel@coma      1027 Oct 26 22:04:33 1988 fgh.c[1.2]
  259. X-rw-r--r-- s axel@coma       731 Nov  1 02:01:34 1988 xyz.c[1.2]\fR
  260. X.fi
  261. X.DE
  262. XThe other notational convention understood by all version control
  263. Xcommands is the \fIbound version notation\fR. The revision number
  264. Xis simply specified as an extension to the object name, enclosed
  265. Xin brackets. For example, the command:
  266. X.DS
  267. X\fCvl -l efg.c[1.2] fgh.c[1.1] xyz.c[1.3] xyzzy.c[1.0]\fR
  268. X.DE
  269. Xprints
  270. X.DS
  271. X.nf
  272. X\fC-rw-r--r-- s axel@coma       437 Nov  2 01:21:46 1988 efg.c[1.2]
  273. X-rw-r--r-- s axel@coma       726 Oct 26 22:04:30 1988 fgh.c[1.1]
  274. X-rw-r--r-- s axel@coma       727 Nov  1 02:25:51 1988 xyz.c[1.3]
  275. X-rw-r--r-- s axel@coma       391 Nov  8 19:21:11 1988 xyzzy.c[1.0]\fR
  276. X.fi
  277. X.DE
  278. XThe long format of the version list command is similar to ls(1)
  279. Xlong format file information. The information printed in this
  280. Xformat is (from left to right): file
  281. X\fIaccess permissions\fR of the busy version (when saved), revision
  282. X\fIstatus\fR (b = busy, s = saved, p = proposed, P = published, a = accessed,
  283. Xf = frozen), network userid of the \fIowner\fR of the object history,
  284. Xoriginal \fIsize\fR of the revision (revsions are actually 
  285. Xstored as differences to the previous revision), \fIdate
  286. Xand time\fR when the revision was saved, and \fIname\fR, \fItype\fR
  287. X(represented as name suffix), \fIgeneration-\fR, and \fIrevision number\fR
  288. X(to either side of the dot). All these informations are examples for
  289. Xindividual \fIattributes\fR of version objects. Many other
  290. Xattributes are stored for each version object that can be examined 
  291. Xby \fBvl\fR. Check the manual for details.
  292. X.PP
  293. XKeeping track of \fIconfigurations\fR, composed of particular versions
  294. Xmany different objects, is easy with the shapetools version control
  295. Xsystem. While the ultimate tool to create, maintain, and
  296. Xoperate with configurations within this toolkit is \- of course \-
  297. Xthe \fBshape\fR program, the version control system allows to
  298. Xassociate different objects in a configuration, and is able to
  299. Xreinstall a given configuration from the object base. Saving a simple
  300. Xconfiguration, consisting of all the current instances of the 
  301. Xbusy versions can be done by invoking 
  302. X.DS
  303. X\fCsave -n conf1 efg.c fgh.c xyz.c xyzzy.c -m "versions work together"\fR
  304. X.DE
  305. XProvided all necessary locks are (or can be) set \fBsave\fR will
  306. Xprint something like:
  307. X.DS
  308. X.nf
  309. X\fCefg.c:
  310. Xsaved version 1.3
  311. Xfgh.c:
  312. Xsaved version 1.5
  313. Xxyz.c:
  314. Xsaved version 1.4
  315. Xxyzzy.c:
  316. Xsaved version 1.1
  317. Xdone.\fR
  318. X.fi
  319. X.DE
  320. XEach newly created version is assigned the name of the configuration
  321. Xas \fIsymbolic name\fR attribute (\fB\-n\fR option). The text
  322. Xsupplied with the \fB\-m\fR (short for \fImessage\fR) is taken
  323. Xas logentry for the evolving versions, so \fBsave\fR won't prompt
  324. Xfor a descriptive log. The specified symbolic name is an \fIalias\fR
  325. Xfor the version number. No single symbolic name may be assigned to more
  326. Xthan one version in an object history. A single version may be 
  327. Xassigned any number of symbolic names, however.
  328. XThe elements of the configuration just saved may be identified any
  329. Xtime, for example by invoking
  330. X.DS
  331. X\fCvl -l -n conf1\fR
  332. X.DE
  333. Xresulting in the following version list:
  334. X.DS
  335. X.nf
  336. X\fC-rw-r--r-- s axel@coma       302 Nov  8 23:31:15 1988 efg.c[1.3]
  337. X-rw-r--r-- s axel@coma      2060 Nov  8 23:31:17 1988 fgh.c[1.5]
  338. X-rw-r--r-- s axel@coma      1089 Nov  8 23:31:20 1988 xyz.c[1.4]
  339. X-rw-r--r-- s axel@coma       749 Nov  8 23:32:24 1988 xyzzy.c[1.1]\fR
  340. X.fi
  341. X.DE
  342. XThe symbolic name of a version may be used anyplace where a version
  343. Xnumber might be used. So, an entire configuration can be reinstalled
  344. Xwith the command:
  345. X.DS
  346. X\fCretrv -V conf1 efg.c fgh.c xyz.c xyzzy.c
  347. X.DE
  348. X.PP
  349. X\fBIdentification of object code
  350. X.PP
  351. XIt is good practice to insert a piece of information into
  352. Xthe source code of program modules that will allow to identify the 
  353. Xsource object versions, a given piece of object code has been 
  354. Xcompiled from. In C programs for example, such a piece of information typically
  355. Xlooks sort of
  356. X.DS
  357. X\fCstatic char *RCSID = "$Header: vcintro.1,v 3.0 88/11/09 23:12:21 axel Exp $";\fR
  358. X.DE
  359. Xor 
  360. X.DS
  361. X\fCstatic char *SCCSID = "@(#)xyzzy.c 1.2  8/11/88";\fR
  362. X.DE
  363. XThe two examples displayed above show the standard identification string
  364. Xformat used by the \fIRCS\fR and \fISCCS\fR source control systems
  365. Xrespectively. The cryptic character sequences serve as magic cookies
  366. Xfor special identification programs which extract tehese strings
  367. Xfrom the compiled objects or executable programs (\fBident\fR and \fBwhat\fR).
  368. Xshape's version control system has some special support for this kind
  369. Xof code identification. If you insert the line
  370. X.DS
  371. X\fCstatic char *AFSID = "$\&__Header$";\fR
  372. X.DE
  373. Xin the source of the program modules, the version control system will
  374. Xexpand this expression into
  375. X.DS
  376. X\fCstatic char *AFSID= 
  377. X    "$Header: vcintro.1,v 3.0 88/11/09 23:12:21 axel Exp $";\fR
  378. X.DE
  379. Xallowing to identify compiled objects with the \fBident\fR command.
  380. XThe sequence \fC$_\&_Header$\fR is an \fIattribute citation expression\fR.
  381. XWhen a version is retrieved from the object base, attribute citations are 
  382. X\fIsubstituted\fR by the value of the cited attribute. In the given example,
  383. Xthe magic string \fI$_\&_\fR indicates the (possible) beginning of an
  384. Xattribute citation. The string that immediately follows the citation 
  385. Xmarker is taken to be the \fIname of an attribute\fR of the version
  386. Xobject under consideration. Each object in the object base has a
  387. Xnumber of standard attributes and may additionally have
  388. Xany number of so called \fIuser defined attributes\fR attributes (see
  389. Xbelow). A \(lq$\(rq charakter or white space immediately following
  390. Xthe attribute name delimits an attribute citation. If no attribute with
  391. Xthe specified name is associated with an object version, the whole
  392. Xcitation will be ignored, i.e. treated as ordinary text.
  393. X.PP
  394. X\(lqHeader\(rq is one of two \fIpseudo attributes\fR that each version
  395. Xobject has in addition to its regular attributes. While \(lqHeader\(rq
  396. Xexpands into a string that displays a number of a version's attributes
  397. Xall at once (\fIname, type, version, savedate, author, \fRand\fI state\fR), 
  398. Xthe \(lqLog\(rq pseudo-attribute pops in the complete log history
  399. Xof the respective version. This is useful to add some kind of development 
  400. Xdocumentation to a particular version. To prevent the inserted log text
  401. Xfrom causing syntax errors, each inserted line is preceded by a
  402. X\fIcomment leader\fR symbol, which is stored in another attribute. In
  403. Xorder to use this feature properly, the comment leader symbol must 
  404. Xbe explicitly set for each design object that has a syntax requiring
  405. Xcomments to be marked. For C language objects, this can be done with
  406. X.DS
  407. X\fCvadm -setc " * " xyzzy.c\fR
  408. X.DE
  409. XIt is a good idea to use a utility program, such as \fBafsit\fR,
  410. Xto insert proper object identification and log attributes automatically.
  411. XThe lines that \fBafsit\fR adds to C files look like
  412. X.DS
  413. X\fCstatic char *AFSid = "$Header: vcintro.1[1.1] Thu Feb 23 18:14:37 1989 axel@coma published $";
  414. X
  415. X/*
  416. X * Log for /u/shape/dist-tape/src/vc/vcintro.1[1.0]
  417. X...     Thu Feb 23 18:14:37 1989 axel@coma published $
  418. X...  --- empty log message ---
  419. X...  vcintro.1[1.1] Thu Feb 23 18:14:37 1989 axel@coma published $
  420. X...  --- empty log message ---
  421. X */\fR
  422. X.DE
  423. X.sp 5p
  424. X\fBSetting up a project\fR
  425. X.PP
  426. XThe shape toolkit is very useful for organizing programming projects
  427. Xemploying programmer teams. The version control system's \fIlocking
  428. Xmechanism\fR makes it easy to prevent problems with concurring updates
  429. Xof the same design objects. If a programmer plans to modify an object
  430. Xhe reserves the \fIupdate privilege\fR by setting a lock on this object.
  431. XHaving done this, no other programmer is allowed to save any modifications
  432. Xinto the object base. Locks should, however, be used with care. Locking
  433. Xall object histories without having a serious intention of modifying 
  434. Xthem, may prevent the other team members from doing their work. The
  435. Xversion control system provides means for resolving deadlock situations
  436. Xwhen objects are locked and the lockholder is not present to give up
  437. Xthe lock when somebody else needs it.
  438. X.PP
  439. XWithin a project, there are three basic roles that a programmer
  440. Xmay play in respect to a design object: \fIowner\fR of the entire
  441. Xdesign object (i.e. all of its versions), \fIauthor\fR of a particular
  442. Xversion, and \fIlocker\fR of the object history. All three roles
  443. Xmay be played by different people for each design object. The network
  444. Xuserids of the people who play these roles are recorded as attributes
  445. Xof each version object in the object base.
  446. X.PP
  447. XThe following project organzation pattern has proven to be useful
  448. Xfor medium sized programming projects. 
  449. X.IP 1)
  450. XCreate a designated userid to be the \fIproject owner\fR. The project
  451. Xowner will be the owner of all design objects that are part of the project.
  452. XCreate a special entry for the project, the \fIproject group\fR
  453. Xin the \fI/etc/group\fR file.
  454. XThe central object base for a project will be installed as an AFS
  455. Xsubdirectory in the project owners homedirectory. The AFS directory
  456. Xshould have the group ID of the project group, and be made
  457. Xgroup-writable.
  458. XThe project owner's home directory 
  459. Xwill also be referred to as \fIproject home\fR. The project home should
  460. Xbe the \fIintegration area\fR, i.e. the place, where the \fIpublished\fR
  461. Xwork results of the various team members are collected and integrated 
  462. Xinto the product that is subject of the project.
  463. X.IP 2)
  464. XAll programmers who are member of the project team should create 
  465. Xa special directory that is dedicated to the project. In this directory,
  466. Xthere should be a \fIsymbolic link\fR, called AFS, that points to the
  467. XAFS subdirectory in the project home. By using this mechanism, all 
  468. Xteam members \fIshare\fR the same object base. It should be made sure
  469. Xthat each team member \- also called \fIauthor\fR \- is member of
  470. Xthe project group (the UNIX group). This is necessary in order to
  471. Xgrant all authors write access to the object base.
  472. X.PP
  473. XIn a project setup of this kind, the status attribute of version
  474. Xobjetcs begins to have real meaning. \fIsaved\fR means that a possibly
  475. Xintermediate version of the object was created as (kind of) backup.
  476. X\fIproposed\fR means that a version is in a \fIresult\fR state and
  477. Xproposed by the author to be assigned official status. \fIpublished\fR
  478. Xmeans, that a version has public status, indicating that it might
  479. Xand should be used by the other authors. In the current version
  480. Xof the shapetools, state transitions are managed informally. No special
  481. X\fImanagement permission\fR is necessary to promote a particular version
  482. Xfrom one state to another. It is also possible, that authors access
  483. Xversions of other authors that have an unpublished status.
  484. X.PP
  485. XAccessing and selecting particular versions in a dynamic but 
  486. Xwell controlled and organized fashion is best be done with the
  487. X\fBshape\fR tool. Basic version control can only supply the very
  488. Xbasic means for sophisticated technical project support. Particular
  489. Xmanagement  policies for projects require more effort. However, the
  490. Xproposed scheme has been proven to work well for medium sized projects.
  491. XUnfortunately, this particular scheme can only be realized on BSD type
  492. Xsystems, as the System V derivates of UNIX mostly don't support symbolic
  493. Xlinks, and also have a different group permission philosophy.
  494. X.PP
  495. X.sp 5p
  496. X\fBThe object base and related terminology
  497. X.PP
  498. XThe principal structures in the object base are \fIobject
  499. Xhistories\fR, \fIindividual objects\fR (also called \fIobject
  500. Xversions\fR), and \fIderived objects\fR. An object history is a set of
  501. Xsubsequent revisions of a \fIconceptual object\fR (e.g. program
  502. Xmodule, documentation, graphics, paper etc.) that result from
  503. Xrepeatedly saving the contents of a conceptual object's \fIbusy
  504. Xversion\fR. The busy version is a regular UNIX file that can be
  505. Xmanipulated by any program that operates on files (editors, compilers,
  506. Xformatters etc.).  Unlike the busy version, object versions are immutable.
  507. XObject histories are represented in a space efficient manner that only
  508. Xkeeps the \fIdifferences\fR between two adjacent versions (\fIdeltas\fR).
  509. X
  510. XEach object in the object base is a complex of \fIcontents\fR and
  511. Xassociated \fIattributes\fR. Attributes are the usual file attributes
  512. X(of the busy version) known from the filesystem (e.g. name, type, size,
  513. Xowner, access privileges etc.) plus any number of arbitrary \fIuser
  514. Xdefined attributes\fR of the form \fI<name>=<value>\fR, where \fIname\fR
  515. Xis a single word (no whithespace) and \fIvalue\fR can be any string
  516. Xthat does not contain control-A characters (\'\\01\').
  517. X
  518. X\fIDerived objects\fR reside in a part of the object base which is
  519. Xcalled \fIderived object pool\fR. The derived object pool serves to
  520. Xmaintain multiple instances of compiled objects in parallel that
  521. Xresult \- for instance \- from compiling different versions of the
  522. Xsame conceptual object. The derived object pool has a fixed size
  523. Xand is administered as a cache. The size of a binary pool is 64 by default
  524. Xbut may be set via the environment variable \fIAFSBPSIZ\fR. A good 
  525. Xestimate for the derived object pool size is two times the number
  526. Xof the compilable source objects.
  527. END_OF_FILE
  528. if test 23895 -ne `wc -c <'man/man1/vcintro.1'`; then
  529.     echo shar: \"'man/man1/vcintro.1'\" unpacked with wrong size!
  530. fi
  531. # end of 'man/man1/vcintro.1'
  532. fi
  533. if test -f 'src/vc/vadm.c' -a "${1}" != "-c" ; then 
  534.   echo shar: Will not clobber existing file \"'src/vc/vadm.c'\"
  535. else
  536. echo shar: Extracting \"'src/vc/vadm.c'\" \(22191 characters\)
  537. sed "s/^X//" >'src/vc/vadm.c' <<'END_OF_FILE'
  538. X/*
  539. X * Copyright (C) 1989, 1990 W. Koch, A. Lampen, A. Mahler, W. Obst,
  540. X *  and U. Pralle
  541. X * 
  542. X * This software is published on an as-is basis. There is ABSOLUTELY NO
  543. X * WARRANTY for any part of this software to work correctly or as described
  544. X * in the manuals. We do not accept any liability for any kind of damage
  545. X * caused by use of this software, such as loss of data, time, money, or 
  546. X * effort.
  547. X * 
  548. X * Permission is granted to use, copy, modify, or distribute any part of
  549. X * this software as long as this is done without asking for charge, and
  550. X * provided that this copyright notice is retained as part of the source
  551. X * files. You may charge a distribution fee for the physical act of
  552. X * transferring a copy, and you may at your option offer warranty
  553. X * protection in exchange for a fee.
  554. X * 
  555. X * Direct questions to: Tech. Univ. Berlin
  556. X *              Wilfried Koch
  557. X *              Sekr. FR 5-6 
  558. X *              Franklinstr. 28/29
  559. X *              D-1000 Berlin 10, West Germany
  560. X * 
  561. X *              Tel: +49-30-314-22972
  562. X *              E-mail: shape@coma.uucp or shape@db0tui62.bitnet
  563. X */
  564. X#ifndef lint
  565. Xstatic char *AFSid = "$Header: vadm.c[3.12] Thu Feb 23 18:14:05 1989 axel@coma published $";
  566. X#ifdef CFFLGS
  567. Xstatic char *ConfFlg = CFFLGS;
  568. X    /* should be defined from within Makefile */
  569. X#endif
  570. X#endif
  571. X/*
  572. X * Log for /u/shape/dist-tape/src/vc/vadm.c[3.6]
  573. X *     Thu Feb 23 18:14:05 1989 axel@coma published $
  574. X *  --- empty log message ---
  575. X *  vadm.c[3.9] Thu Feb 23 18:14:05 1989 axel@coma published $
  576. X *  --- empty log message ---
  577. X *  vadm.c[3.10] Thu Feb 23 18:14:05 1989 axel@coma save $
  578. X *  --- empty log message ---
  579. X *  vadm.c[3.11] Thu Feb 23 18:14:05 1989 axel@coma save $
  580. X *  --- empty log message ---
  581. X *  vadm.c[3.12] Thu Feb 23 18:14:05 1989 axel@coma published $
  582. X *  --- empty log message ---
  583. X */
  584. X
  585. X#include <pwd.h>
  586. X#include <stdio.h>
  587. X#include <signal.h>
  588. X#include <strings.h>
  589. X
  590. X#include "afs.h"
  591. X#include "afsapp.h"
  592. X#include "vadm.h"
  593. X#include "ParseArgs.h"
  594. X
  595. Xextern char *malloc();
  596. X
  597. X/* forward declarations */
  598. X/*
  599. X * Options (e.g. -V, -from, or -to) and actions (-delete, -set, etc.)
  600. X * are parse at the same time by calling function ParseArgs().
  601. X */
  602. X
  603. X/* option */
  604. Xextern int handle_binary_option ();
  605. Xextern int handle_help_option ();        /* handler for option -h */
  606. Xextern int handle_version_option ();        /* handler for -V option */
  607. Xextern int handle_from_option ();        /* handler for -from option */
  608. Xextern int handle_to_option ();            /* handler for -to option */
  609. Xextern int handle_no_option ();            /* handler for -no option */
  610. Xextern int handle_quiet_option ();
  611. Xextern int handle_R_option ();
  612. Xchar debug_on = 0;
  613. Xextern int handle_d_option ();
  614. X
  615. X/* actions */
  616. Xextern int handle_reserve_action ();
  617. Xextern int handle_unreserve_action ();
  618. Xextern int handle_symname_action ();
  619. Xextern int handle_setc_action ();
  620. Xextern int handle_delete_action ();
  621. Xextern int handle_promote_action ();
  622. Xextern int handle_unpromote_action ();
  623. Xextern int handle_change_action ();
  624. Xextern int handle_lock_action ();
  625. Xextern int handle_unlock_action ();
  626. Xextern int handle_chmod_action ();
  627. Xextern int handle_chown_action ();
  628. Xextern int handle_chaut_action ();
  629. Xextern int handle_set_action ();
  630. Xextern int handle_setuda_action ();
  631. Xextern int handle_unsetuda_action ();
  632. Xextern int handle_setattrs_action ();
  633. X
  634. X/* Global variables */
  635. XOptDesc argdesc[] = {    /* known options,actions and its handler */
  636. X  { "version", OPT_IS_SWITCH, handle_R_option },
  637. X  { "b", OPT_IS_SWITCH, handle_binary_option },
  638. X  { "h", OPT_HAS_OPT_ARG, handle_help_option },
  639. X  { "V", OPT_HAS_ARG, handle_version_option},
  640. X  { "from", OPT_HAS_ARG, handle_from_option },
  641. X  { "to", OPT_HAS_ARG, handle_to_option },
  642. X  { "no", OPT_HAS_ARG, handle_no_option },
  643. X  { "q", OPT_IS_SWITCH, handle_quiet_option },
  644. X  { "debug", OPT_IS_SWITCH, handle_d_option },
  645. X  { "reserve", OPT_IS_SWITCH, handle_reserve_action},
  646. X  { "unreserve", OPT_IS_SWITCH, handle_unreserve_action},
  647. X  { "symbolic", OPT_HAS_ARG, handle_symname_action},
  648. X  { "setc", OPT_HAS_ARG, handle_setc_action},
  649. X  { "delete", OPT_IS_SWITCH, handle_delete_action},
  650. X  { "promote", OPT_IS_SWITCH, handle_promote_action },
  651. X  { "unpromote", OPT_IS_SWITCH, handle_unpromote_action },
  652. X  { "lock", OPT_IS_SWITCH, handle_lock_action },
  653. X  { "unlock", OPT_IS_SWITCH, handle_unlock_action },
  654. X  { "chmod", OPT_HAS_ARG, handle_chmod_action },
  655. X  { "chown", OPT_HAS_ARG, handle_chown_action },
  656. X  { "chaut", OPT_HAS_ARG, handle_chaut_action },
  657. X  { "set", OPT_HAS_ARG, handle_set_action },
  658. X  { "setuda", OPT_HAS_ARG, handle_setuda_action },
  659. X  { "unsetuda", OPT_HAS_ARG, handle_unsetuda_action },
  660. X  { "setattrs", OPT_HAS_ARG, handle_setattrs_action },
  661. X  { "change", OPT_HAS_ARG, handle_change_action },
  662. X  { (char *) NULL, NULL, NULL }
  663. X};
  664. X
  665. Xunsigned int options = 0;    /* given options */
  666. Xunsigned int actions = 0;    /* given actions */
  667. Xchar *progname;            /* program's name */
  668. Xstruct vc_vlist *vlist = (struct vc_vlist*) NULL;
  669. X     /* versions to be processed */
  670. Xstruct vc_vlist *vcur = (struct vc_vlist*) NULL;
  671. Xint def_vnum;
  672. Xint to_option_pending = 0;    /* if -from is given, -to is expected later */
  673. Xint from_option_pending = 0;    /* if -to is given before any -from, -from is
  674. X                 * pending. If -to is followed by -V, any
  675. X                 * from-pending is rejected.*/ 
  676. Xchar *symname = NULL;        /* symbolic name -symname arg */
  677. Xchar *csym =  NULL;             /* comment leader symbol */
  678. Xint newmode;
  679. XAf_user newauthor; /* arguments of the resp. actions */
  680. Xchar *TakeFromFile = NULL;      /* Filename, where uda-val will be taken
  681. X                   from (see handle_setuda_action) */
  682. Xchar Attrfile[128];             /* Name of file where attribute definitions
  683. X                   will be taken from */
  684. Xchar udaname[AF_UDANAMLEN];     /* Name of uda to be set */
  685. Xchar udaval[256];               /* String val to which udaname will be set */
  686. Xstruct Transaction ThisTransaction;
  687. Xstatic char buf[100];
  688. Xchar **environment;
  689. Xjmp_buf here;
  690. X
  691. X/**/
  692. Xmain (ac, av, ev)
  693. X     int ac;
  694. X     char **av, **ev;
  695. X{
  696. X  int nac;            /* ac after parsing */
  697. X  char **nav, *cp;        /* av after parsing */
  698. X  int retcode = 0;        /* return value */
  699. X  register int i, j;
  700. X  
  701. X  progname = (cp = rindex (av[0], '/')) ? ++cp : av[0];
  702. X  /* make prog-name available to entire program */
  703. X  environment = ev;        /*  */
  704. X  CatchSigs();
  705. X  if (setjmp (ThisTransaction.tr_env)) return 1; 
  706. X  InitVcontrol ();
  707. X  if (ParseArgs (ac, av, &nac, &nav, argdesc)) {
  708. X    (void)sprintf (buf, "BTW, try \"%s -h\" for more information or rtfm.",
  709. X         progname);
  710. X    logmsg (buf);
  711. X    exit (1);            /* error detected  */
  712. X  }
  713. X  /* Look for identical arguments -- zero out twins */
  714. X  for ( i = 0; i < nac; i++)
  715. X    for (j = i+1; j < nac; j++)
  716. X      if (!strcmp (nav[i], nav[j])) nav[j][0] = '\0';
  717. X
  718. X  if (debug_on)
  719. X    DumpVlist ();
  720. X  
  721. X  if (!nac) {
  722. X    if (actions)        /* if an action is given */
  723. X      logmsg ("Filenames missing.");
  724. X    else
  725. X      logmsg ("An action and filenames missing.");
  726. X
  727. X    ShortUsage ();
  728. X    exit (1);
  729. X  }
  730. X
  731. X  if (!ActionsPlausible ()) exit (1); /* no chance to do anything */
  732. X
  733. X  switch (actions) {
  734. X  case Varg_set_note:
  735. X    retcode = DoSetNote (vlist, nac, nav);
  736. X    break;
  737. X  case Varg_change_note:
  738. X    retcode = DoChangeNote (vlist, nac, nav);
  739. X    break;
  740. X  case Varg_set_description:
  741. X    retcode = DoSetDescription (vlist, nac, nav);
  742. X    break;
  743. X  case Varg_change_description:
  744. X    retcode = DoChangeDescription (vlist, nac, nav);
  745. X    break;
  746. X  case Varg_set_intent:
  747. X    retcode = DoSetIntent (nac, nav);
  748. X    break;
  749. X  case Varg_setc_symbol:
  750. X    retcode = DoSetCommentSymbol (nac, nav, csym);
  751. X    break;
  752. X  case Varg_delete:
  753. X    retcode = DoDelete (vlist, nac, nav);
  754. X    break;
  755. X  case Varg_promote:
  756. X    retcode = DoPromote (vlist, nac, nav);
  757. X    break;
  758. X  case Varg_unpromote:
  759. X    retcode = DoUnpromote (vlist, nac, nav);
  760. X    break;
  761. X  case Varg_lock:
  762. X  case Varg_reserve:
  763. X    retcode = DoReserve (nac, nav);
  764. X    break;
  765. X  case Varg_unlock:
  766. X  case Varg_unreserve:
  767. X    retcode = DoUnreserve (nac, nav);
  768. X    break;
  769. X  case Varg_chmod:
  770. X    retcode = DoChmod (vlist, nac, nav);
  771. X    break;
  772. X  case Varg_chown:
  773. X    retcode = DoChown (nac, nav);
  774. X    break;
  775. X  case Varg_chaut:
  776. X    retcode = DoChaut (vlist, nac, nav);
  777. X    break;
  778. X  case Varg_symname:
  779. X    retcode = DoSymname (vlist, nac, nav, symname);
  780. X    break;
  781. X  case Varg_setuda:
  782. X    retcode = DoSetUda (vlist, nac, nav);
  783. X    break;
  784. X  case Varg_unsetuda:
  785. X    retcode =DoUnsetUda (vlist, nac, nav);
  786. X    break;
  787. X  case Varg_setattrs:
  788. X    retcode = DoSetAttrs (vlist, nac, nav);
  789. X    break;
  790. X  default:
  791. X    logerr ("Ooops, You have requested more than one action.\
  792. X Please try again");
  793. X    logmsg ("with only *one* action at a time.");
  794. X    retcode = 1;
  795. X    break;
  796. X  }
  797. X  
  798. X  if (retcode)
  799. X    logmsg ("terminated.");
  800. X  else
  801. X    logmsg ("done.");
  802. X  return (retcode);
  803. X}
  804. X
  805. X/**/
  806. Xint ActionsPlausible ()
  807. X{
  808. X  if (actions) {
  809. X    return 1;
  810. X  }
  811. X  else {
  812. X    logmsg ("Action missing.");
  813. X    ShortUsage ();
  814. X    return 0;
  815. X  }
  816. X}
  817. X
  818. X/**/
  819. Xint InitVcontrol ()
  820. X{
  821. X  if ((vlist = (struct vc_vlist*) malloc (sizeof (struct vc_vlist))) == NULL) {
  822. X    vctl_abort ("malloc vc_vlist");
  823. X  }
  824. X
  825. X  vlist->from_version_set = vlist->to_version_set = NULL;
  826. X  vlist->from_generation =  NULL;
  827. X  vlist->from_revision =  NULL;
  828. X  vlist->to_generation = NULL;
  829. X  vlist->to_revision = NULL;
  830. X  
  831. X  vlist->next = NULL;
  832. X  vcur = vlist;
  833. X}
  834. X
  835. X/**************************
  836. X *     Action handlers    *
  837. X *************************/
  838. X/**/
  839. X/*ARGSUSED*/
  840. Xint handle_reserve_action (act, arg)
  841. X     char *act, *arg;
  842. X{
  843. X  if (IsOptionSet (Vopt_binary)) {
  844. X    logerr ("Can't reserve or unreserve binary.");
  845. X    exit (1);
  846. X  }
  847. X  SetAction(Varg_reserve);    /* macro */
  848. X  if (IsActionSet(Varg_unreserve)) {
  849. X    logerr ("You already mentioned \"unreserve\", so what do you want ?");
  850. X    return 1;
  851. X  }
  852. X  return 0;
  853. X}
  854. X
  855. X/*ARGSUSED*/
  856. Xint handle_unreserve_action (act, arg)
  857. X     char *act, *arg;
  858. X{
  859. X  if (IsOptionSet (Vopt_binary)) {
  860. X    logerr ("Can't reserve or unreserve binary.");
  861. X    exit (1);
  862. X  }
  863. X  SetAction(Varg_unreserve);
  864. X  if (IsActionSet(Varg_reserve)) {
  865. X    logerr ("You already mentioned \"reserve\", so what do you want ?");
  866. X    return 1;
  867. X  }
  868. X  return 0;
  869. X}
  870. X
  871. X/*ARGSUSED*/
  872. Xint handle_symname_action (act, arg)
  873. X     char *act, *arg;
  874. X{
  875. X  SetAction(Varg_symname);
  876. X  symname = arg;
  877. X  return 0;
  878. X}
  879. X
  880. X/*ARGSUSED*/
  881. Xint handle_setc_action (act, arg)
  882. X     char *act, *arg;
  883. X{
  884. X  csym = arg;
  885. X  if (strlen (csym) > (CLEADMAXLEN-(strlen(CLEAD)+2))) {
  886. X    logerr ("Specified comment leader symbol is too long");
  887. X    return 1;
  888. X  }
  889. X  SetAction(Varg_setc_symbol);
  890. X  return 0;
  891. X}  
  892. X
  893. X/*ARGSUSED*/
  894. Xint handle_delete_action (act, arg)
  895. X     char *act, *arg;
  896. X{
  897. X  SetAction(Varg_delete);
  898. X  return 0;
  899. X}
  900. X
  901. X/*ARGSUSED*/
  902. Xint handle_promote_action (act, arg)
  903. X     char *act, *arg;
  904. X{
  905. X  if (IsOptionSet (Vopt_binary)) {
  906. X    logerr ("Can't promote status of binary.");
  907. X    exit (1);
  908. X  }
  909. X  SetAction(Varg_promote);
  910. X  if (IsActionSet(Varg_unpromote)) {
  911. X    logerr ("You already mentioned \"unpromote\", so what do you want ?");
  912. X    return 1;
  913. X  }
  914. X  return 0;
  915. X}
  916. X
  917. X/*ARGSUSED*/
  918. Xint handle_unpromote_action (act, arg)
  919. X     char *act, *arg;
  920. X{
  921. X  if (IsOptionSet (Vopt_binary)) {
  922. X    logerr ("Can't unpromote status of binary.");
  923. X    exit (1);
  924. X  }
  925. X  SetAction(Varg_unpromote);
  926. X  if (IsActionSet(Varg_promote)) {
  927. X    logerr ("You already mentioned \"promote\", so what do you want ?");
  928. X    return 1;
  929. X  }
  930. X  return 0;
  931. X}
  932. X
  933. X/*ARGSUSED*/
  934. Xint handle_change_action (act, arg)
  935. X     char *act, *arg;
  936. X{
  937. X  char messg[80];
  938. X  if (IsOptionSet (Vopt_binary)) {
  939. X    (void)sprintf (messg, "Can't change %s of binaries. Sorry.", 
  940. X         arg ? arg : "note or description" );
  941. X    logerr (messg);
  942. X    exit (1);
  943. X  }
  944. X  if (!strcmp (arg, "note")) {
  945. X    SetAction(Varg_change_note);
  946. X    return 0;
  947. X  }
  948. X  if (!strcmp (arg, "description")) {
  949. X    SetAction(Varg_change_description);
  950. X    return 0; 
  951. X  }
  952. X  logerr ("Change what, eh? - Note or description?");
  953. X  return 1;
  954. X}
  955. X
  956. X/*ARGSUSED*/
  957. Xint handle_lock_action (act, arg) char *act, *arg; {
  958. X  if (IsOptionSet (Vopt_binary)) {
  959. X    logerr ("Can't lock or unlock binary.");
  960. X    exit (1);
  961. X  }
  962. X  if (IsActionSet (Varg_unlock)) {
  963. X    logerr ("Can't lock and unlock at the same time.");
  964. X    exit (1);
  965. X  }
  966. X  SetAction (Varg_lock);
  967. X  return 0;
  968. X}
  969. X
  970. X/*ARGSUSED*/
  971. Xint handle_unlock_action (act, arg) char *act, *arg; {
  972. X  if (IsOptionSet (Vopt_binary)) {
  973. X    logerr ("Can't lock or unlock binary.");
  974. X    exit (1);
  975. X  }
  976. X  if (IsActionSet (Varg_lock)) {
  977. X    logerr ("Can't lock and unlock at the same time.");
  978. X    exit (1);
  979. X  }
  980. X  SetAction (Varg_unlock);
  981. X  return 0;
  982. X}
  983. X
  984. X/*ARGSUSED*/
  985. Xint handle_chmod_action (act, arg) char *act, *arg; {
  986. X  register int mode = 0;
  987. X  char messg[80], ciph, err = 0;
  988. X  register char *cp = arg;
  989. X
  990. X  if (strlen (arg) > 4) err++;
  991. X  else 
  992. X    while (ciph = *cp++) { 
  993. X      ciph -= '0';
  994. X      if ((ciph > 7) || (ciph < 0)) err++;
  995. X      else {
  996. X    mode <<= 3;  
  997. X    mode += ciph;
  998. X      }
  999. X    }
  1000. X  if (err) {
  1001. X    (void)sprintf (messg, "invalid mode \"%s\".", arg);
  1002. X    logerr (messg);
  1003. X    exit (1);
  1004. X  }
  1005. X  SetAction (Varg_chmod);
  1006. X  newmode = mode;
  1007. X  return 0;
  1008. X}
  1009. X
  1010. X/*ARGSUSED*/
  1011. Xint handle_chown_action (act, arg) char *act, *arg; {
  1012. X  char messg[80];
  1013. X
  1014. X  if (IsOptionSet (Vopt_binary)) {
  1015. X    logerr ("Can't change owner of binary.");
  1016. X    exit (1);
  1017. X  }
  1018. X  if (getpwnam (arg) == NULL) {
  1019. X    (void)sprintf (messg, "%s is not a valid userid on this machine.", arg);
  1020. X    logerr (messg);
  1021. X    exit (1);
  1022. X  }
  1023. X  SetAction (Varg_chown);
  1024. X/*  newowner = opw->pw_uid; */
  1025. X  return 0;
  1026. X}
  1027. X
  1028. X/*ARGSUSED*/
  1029. Xint handle_chaut_action (act, arg) char *act, *arg; {
  1030. X  char messg[80], hostname[MAXHOSTNAMELEN];
  1031. X  
  1032. X  if (IsOptionSet (Vopt_binary)) {
  1033. X    logerr ("Can't change author of binary.");
  1034. X    exit (1);
  1035. X  }
  1036. X  if (getpwnam (arg) == NULL ) {
  1037. X    (void)sprintf (messg, "%s is not a valid userid on this machine.", arg);
  1038. X    logerr (messg);
  1039. X    exit (1);
  1040. X  }
  1041. X  SetAction (Varg_chaut);
  1042. X  (void) strcpy (newauthor.af_username, arg);
  1043. X  (void) gethostname (hostname, MAXHOSTNAMELEN);
  1044. X  (void) strcpy (newauthor.af_userhost, hostname);
  1045. X  return 0;
  1046. X}
  1047. X
  1048. X/*ARGSUSED*/
  1049. Xint handle_setuda_action (act, arg) char *act, *arg; {
  1050. X  char *cp;
  1051. X  register int i;
  1052. X
  1053. X  if (cp=index(arg, '=')) {
  1054. X    if (arg == cp) { /* No attribute name */
  1055. X      logerr ("No attribute name given");
  1056. X      exit (1);
  1057. X    }
  1058. X    if (*(cp+1) == '@') { /* the attribute value will be taken from file */
  1059. X      TakeFromFile = malloc (128);
  1060. X      if (TakeFromFile == NULL) {
  1061. X    logerr ("Can't allocate memory for filename");
  1062. X    exit (1);
  1063. X      }
  1064. X      (void)sscanf (cp+1, "@%s", TakeFromFile); /* ignore evtly. trailing junk */
  1065. X      if (TakeFromFile ? TakeFromFile[0] ? 0 : 1 : 1) {
  1066. X    /* condition holds if no filename specified */
  1067. X    TakeFromFile = NULL;
  1068. X    (void)strcpy (udaval, "@");
  1069. X      }
  1070. X    }
  1071. X    else { /* attribute value will be taken literally */
  1072. X      (void)strcpy (udaval, cp+1);
  1073. X      for (i=0; udaval[i]; i++) {
  1074. X    if (udaval[i] == 1) { /* cntl-A not allowed */
  1075. X      logerr ("Invalid char (cntl-A) in attribute value");
  1076. X      exit (1);
  1077. X    }
  1078. X      }
  1079. X    }
  1080. X    if ((cp-arg) > AF_UDANAMLEN) {
  1081. X      logerr ("Attributename too long");
  1082. X      exit (1);
  1083. X    }
  1084. X    (void)strncpy (udaname, arg, cp-arg);
  1085. X    udaname[cp-arg] = '\0';
  1086. X    SetAction (Varg_setuda);
  1087. X  }
  1088. X  else { /* No '=' in arg */
  1089. X    logerr ("Illegal format of attribute expression");
  1090. X    exit (1);
  1091. X  }
  1092. X  return 0; /* OK */
  1093. X}
  1094. X
  1095. X/*ARGSUSED*/
  1096. Xint handle_unsetuda_action (act, arg)
  1097. X     char *act, *arg; {
  1098. X       (void)strcpy (udaname, arg);
  1099. X       SetAction (Varg_unsetuda);
  1100. X       return 0;
  1101. X     }
  1102. X
  1103. X/*ARGSUSED*/
  1104. Xint handle_setattrs_action (act, arg)
  1105. X     char *act, *arg; {
  1106. X
  1107. X       SetAction (Varg_setattrs);
  1108. X       (void)strcpy (Attrfile, arg);
  1109. X       return 0;
  1110. X     }
  1111. X
  1112. X/*ARGSUSED*/
  1113. Xint handle_set_action (act, arg)
  1114. X     char *act, *arg;
  1115. X{
  1116. X  char messg[80];
  1117. X
  1118. X  if (IsOptionSet (Vopt_binary)) {
  1119. X    (void)sprintf (messg, "Can't set %s on binaries. Sorry.", 
  1120. X         arg ? arg : "note or description" );
  1121. X    logerr (messg);
  1122. X    exit (1);
  1123. X  }
  1124. X  if (!strcmp (arg, "note")) {
  1125. X    SetAction(Varg_set_note);
  1126. X    return 0;
  1127. X  }
  1128. X  if (!strcmp (arg, "description")) {
  1129. X    SetAction(Varg_set_description);
  1130. X    return 0; 
  1131. X  }
  1132. X  if (!strcmp (arg, "intent")) {
  1133. X    SetAction(Varg_set_intent);
  1134. X    return 0;
  1135. X  }
  1136. X  logerr ("Set what, eh? - note, description, or intent ?");
  1137. X  return 1;
  1138. X}
  1139. X
  1140. X/**************************
  1141. X *     Option handlers    *
  1142. X *************************/
  1143. X
  1144. X/*ARGSUSED*/
  1145. Xint handle_binary_option (opt, arg) char *opt, *arg; {
  1146. X  if (IsActionSet (Varg_reserve | Varg_unreserve | Varg_promote | 
  1147. X           Varg_unpromote | Varg_change_note | 
  1148. X           Varg_change_description | Varg_set_description | 
  1149. X           Varg_set_note | Varg_lock | Varg_unlock | Varg_chown | 
  1150. X           Varg_chaut)) {
  1151. X    logerr ("This action request is not supported for binaries.");
  1152. X    exit (1);
  1153. X  }
  1154. X  SetOption (Vopt_binary);
  1155. X  return 0;
  1156. X}
  1157. X
  1158. X#ifdef NEVER_SET_THIS
  1159. Xint handle_version_option (opt, arg)
  1160. X     char *opt, *arg;
  1161. X{
  1162. X  struct vc_vlist *vtmp;
  1163. X  int generation = 0, revision = 0;
  1164. X  
  1165. X  if ((vcur->from_version_set) || (vcur->to_version_set)) {
  1166. X    /* if any -to num pending, report error */
  1167. X    if (to_option_pending) {
  1168. X      (void)sprintf (buf, "\"-to <version number>\" expected. Got \"-%s %s\"",
  1169. X           opt, arg);
  1170. X      logerr (buf);
  1171. X      return 1;
  1172. X    }
  1173. X
  1174. X    if (from_option_pending) {
  1175. X      from_option_pending = 0;    /* vctl -to 3.4 -from 5.6 -to 6.7 */
  1176. X                /* means: from 1.0 to 3.4 and from 5.6 to */
  1177. X                /* 6.7 */
  1178. X    }
  1179. X    if ((vtmp = (struct vc_vlist*)malloc (sizeof (struct vc_vlist))) == NULL)
  1180. X      vctl_abort ("malloc,2 vc_vlist");
  1181. X
  1182. X    vcur->next = vtmp;
  1183. X    vcur = vtmp;
  1184. X  }
  1185. X
  1186. X  generation = GetGenerationNumber (arg);
  1187. X  revision = GetRevisionNumber (arg);
  1188. X  
  1189. X  vcur->from_generation = generation;
  1190. X  vcur->from_revision = revision;
  1191. X  vcur->to_generation = generation;
  1192. X  vcur->to_revision = revision;
  1193. X  vcur->from_version_set = vcur->to_version_set = 1;
  1194. X  vcur->next = NULL;
  1195. X
  1196. X  if ((revision < 0) || (generation <= 0)) {
  1197. X    (void)sprintf (buf, "%s version number %s.",
  1198. X         *arg ? "bad" : "missing",
  1199. X         *arg ? arg : "");
  1200. X    logerr (buf);
  1201. X    return 1;
  1202. X  }
  1203. X  return 0;
  1204. X}
  1205. X#endif
  1206. X
  1207. X/*ARGSUSED*/
  1208. Xint handle_version_option (opt, arg)
  1209. X     char *opt, *arg;
  1210. X{
  1211. X  def_vnum = mkvno (arg);
  1212. X  if (IsOptionSet(Vopt_version) || 
  1213. X      (vlist->from_generation + vlist->to_generation) ) {
  1214. X    logerr ("Set only one default version or version range.");
  1215. X    return 1;
  1216. X  }
  1217. X  SetOption(Vopt_version);
  1218. X  return 0;
  1219. X}
  1220. X
  1221. X/**/
  1222. Xint handle_from_option (opt, arg)
  1223. X     char *opt, *arg;
  1224. X{
  1225. X  struct vc_vlist *vtmp;
  1226. X  
  1227. X  if (IsOptionSet(Vopt_version)) {
  1228. X    logerr ("Set only one default version or version range.");
  1229. X    return 1;
  1230. X  }
  1231. X  if (vcur->from_version_set) {    /* need a new entry in vlist */
  1232. X    if ((vtmp = (struct vc_vlist*)malloc (sizeof (struct vc_vlist))) == NULL)
  1233. X      vctl_abort ("malloc,3 vc_vlist");
  1234. X    
  1235. X    vcur->next = vtmp;
  1236. X    vcur = vtmp;
  1237. X    vcur->to_generation = vcur->to_revision = NULL;
  1238. X    vcur->to_version_set = NULL;
  1239. X    vcur->next = NULL;
  1240. X  }
  1241. X
  1242. X  vcur->from_version_set = 1;
  1243. X  vcur->from_generation = GetGenerationNumber (arg);
  1244. X  vcur->from_revision = GetRevisionNumber (arg);
  1245. X
  1246. X  if (to_option_pending) {
  1247. X    (void)sprintf (buf, "\"-to <version number>\" expected. Got \"-%s %s\"",
  1248. X         opt, arg);
  1249. X    logerr (buf);
  1250. X    return 1;
  1251. X  }
  1252. X  else {
  1253. X    if (!from_option_pending)
  1254. X      /* e.g.: -to is followed by -from then no -to is pending */
  1255. X      to_option_pending++;
  1256. X  }
  1257. X
  1258. X  if ((vcur->from_revision < 0) || (vcur->from_generation <= 0)) {
  1259. X    (void)sprintf (buf, "%s version number %s.",
  1260. X         *arg ? "bad" : "missing",
  1261. X         *arg ? arg : "");
  1262. X    logerr (buf);
  1263. X    return 1;
  1264. X  }
  1265. X
  1266. X  from_option_pending = 0;
  1267. X  return 0;
  1268. X}
  1269. X
  1270. X/**/
  1271. Xint handle_to_option (opt, arg)
  1272. X     char *opt, *arg;
  1273. X{
  1274. X  struct vc_vlist *vtmp;
  1275. X  
  1276. X  if (IsOptionSet(Vopt_version)) {
  1277. X    logerr ("Set only one default version or version range.");
  1278. X    return 1;
  1279. X  }
  1280. X  if (vcur->to_version_set) {
  1281. X    if ((vtmp = (struct vc_vlist*) malloc (sizeof (struct vc_vlist))) == NULL)
  1282. X      vctl_abort ("malloc,4 vc_vlist");
  1283. X
  1284. X    vcur->next = vtmp;
  1285. X    vcur = vtmp;
  1286. X    vcur->from_generation = vcur->from_revision = NULL;
  1287. X    vcur->from_version_set = NULL;
  1288. X    vcur->next = NULL;
  1289. X  }
  1290. X
  1291. X  vcur->to_generation = GetGenerationNumber (arg);
  1292. X  vcur->to_revision = GetRevisionNumber (arg);
  1293. X  vcur->to_version_set = 1;
  1294. X
  1295. X  if (from_option_pending) {
  1296. X    (void)sprintf (buf, "\"-from <version number>\" expected. Got \"-%s %s\"",
  1297. X         opt, arg);
  1298. X    logerr (buf);
  1299. X    return 1;
  1300. X  }
  1301. X  else {
  1302. X    if (!to_option_pending)    /* -to followd by -from then no -from is
  1303. X                 * pending */
  1304. X      from_option_pending++;
  1305. X  }
  1306. X  
  1307. Xif ((vcur->to_revision < 0) || (vcur->to_generation <= 0)) {
  1308. X    (void)sprintf (buf, "%s version number %s.",
  1309. X         *arg ? "bad" : "missing",
  1310. X         *arg ? arg : "");
  1311. X    logerr (buf);
  1312. X    return 1;
  1313. X  }
  1314. X
  1315. X  to_option_pending = 0; 
  1316. X  return 0;
  1317. X}
  1318. X
  1319. X/**/
  1320. Xint handle_no_option (opt, arg)
  1321. X     char *opt, *arg;
  1322. X{
  1323. X  if (*arg) {
  1324. X    if (!strcmp ("confirm", arg)) {
  1325. X      SetOption(Vopt_no_confirm);
  1326. X      return 0;
  1327. X    }
  1328. X    else {
  1329. X      (void)sprintf (buf, "Hmmm, I don't know that. What's up with \"-%s %s\"?", opt, arg);
  1330. X      logerr (buf);
  1331. X      return 1;
  1332. X    }
  1333. X  }
  1334. X  else {
  1335. X    (void)sprintf (buf, "Hey You, please tell me more about \"-%s\".\
  1336. X That sounds familiar to me.", opt);
  1337. X    logerr (buf);
  1338. X    return 1;
  1339. X  }
  1340. X}
  1341. X
  1342. X/*ARGSUSED*/
  1343. Xint handle_quiet_option (o, a) char *o, *a; {
  1344. X  SetOption(Vopt_quiet);
  1345. X  return 0;
  1346. X}
  1347. X
  1348. X/**/
  1349. XShortUsage ()
  1350. X{
  1351. X  pa_ShortUsage (progname, argdesc, "files ...");
  1352. X}
  1353. X
  1354. X/*ARGSUSED*/
  1355. Xint handle_help_option (opt, arg)
  1356. X     char *opt, *arg;
  1357. X{
  1358. X  if (*arg) {
  1359. X    logerr ("long help not yet implemented.");
  1360. X  }
  1361. X  else {
  1362. X    ShortUsage ();
  1363. X  }
  1364. X
  1365. X  exit (1);            /* no way to proceed */
  1366. X}
  1367. X
  1368. X/*ARGSUSED*/
  1369. Xhandle_R_option (o, a) char *o, *a; {
  1370. X  extern char *version();
  1371. X
  1372. X  printf ("This is %s version %s.\n", progname, version ());
  1373. X  printf ("AFS version %s.\n", af_version());
  1374. X  exit (0);
  1375. X}
  1376. X
  1377. X/**/
  1378. Xvctl_abort (message)
  1379. X     char *message;
  1380. X{
  1381. X  perror (message);
  1382. X  exit (1);
  1383. X}
  1384. X
  1385. X/*ARGSUSED*/
  1386. Xint handle_d_option (opt, arg)
  1387. X     char *opt, *arg;
  1388. X{
  1389. X  debug_on++;
  1390. X}
  1391. X
  1392. XDumpVlist ()
  1393. X{
  1394. X  struct vc_vlist *vtmp;
  1395. X  int f_gen, f_rev, t_gen, t_rev;
  1396. X  
  1397. X  for (vtmp = vlist; vtmp; vtmp = vtmp->next) {
  1398. X    f_gen = vtmp->from_generation;
  1399. X    f_rev = vtmp->from_revision;
  1400. X    t_gen = vtmp->to_generation;
  1401. X    t_rev = vtmp->to_revision;
  1402. X
  1403. X    if ( (f_gen == t_gen) && (f_rev == f_rev))
  1404. X      fprintf (stderr, "-V%d.%d\n", f_gen, f_rev);
  1405. X    else
  1406. X      fprintf (stderr, "-from %d.%d -to %d.%d\n", f_gen, f_rev, t_gen, t_rev);
  1407. X  }
  1408. X}
  1409. X
  1410. END_OF_FILE
  1411. if test 22191 -ne `wc -c <'src/vc/vadm.c'`; then
  1412.     echo shar: \"'src/vc/vadm.c'\" unpacked with wrong size!
  1413. fi
  1414. # end of 'src/vc/vadm.c'
  1415. fi
  1416. echo shar: End of archive 22 \(of 33\).
  1417. cp /dev/null ark22isdone
  1418. MISSING=""
  1419. 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
  1420.     if test ! -f ark${I}isdone ; then
  1421.     MISSING="${MISSING} ${I}"
  1422.     fi
  1423. done
  1424. if test "${MISSING}" = "" ; then
  1425.     echo You have unpacked all 33 archives.
  1426.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1427. else
  1428.     echo You still need to unpack the following archives:
  1429.     echo "        " ${MISSING}
  1430. fi
  1431. ##  End of shell archive.
  1432. exit 0
  1433.