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

  1. Subject:  v19i027:  A software configuration management system, Part14/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 27
  8. Archive-name: shape/part14
  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 14 (of 33)."
  19. # Contents:  src/afs/afcompar.c src/shape/macro.c src/vc/vadm_note.c
  20. #   src/vc/vadm_reserve.c
  21. # Wrapped by rsalz@papaya.bbn.com on Thu Jun  1 19:27:04 1989
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f 'src/afs/afcompar.c' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'src/afs/afcompar.c'\"
  25. else
  26. echo shar: Extracting \"'src/afs/afcompar.c'\" \(12396 characters\)
  27. sed "s/^X//" >'src/afs/afcompar.c' <<'END_OF_FILE'
  28. X/*
  29. X * Copyright (C) 1989, 1990 W. Koch, A. Lampen, A. Mahler, W. Obst,
  30. X *  and U. Pralle
  31. X * 
  32. X * This software is published on an as-is basis. There is ABSOLUTELY NO
  33. X * WARRANTY for any part of this software to work correctly or as described
  34. X * in the manuals. We do not accept any liability for any kind of damage
  35. X * caused by use of this software, such as loss of data, time, money, or 
  36. X * effort.
  37. X * 
  38. X * Permission is granted to use, copy, modify, or distribute any part of
  39. X * this software as long as this is done without asking for charge, and
  40. X * provided that this copyright notice is retained as part of the source
  41. X * files. You may charge a distribution fee for the physical act of
  42. X * transferring a copy, and you may at your option offer warranty
  43. X * protection in exchange for a fee.
  44. X * 
  45. X * Direct questions to: Tech. Univ. Berlin
  46. X *              Wilfried Koch
  47. X *              Sekr. FR 5-6 
  48. X *              Franklinstr. 28/29
  49. X *              D-1000 Berlin 10, West Germany
  50. X * 
  51. X *              Tel: +49-30-314-22972
  52. X *              E-mail: shape@coma.uucp or shape@db0tui62.bitnet
  53. X */
  54. X/*
  55. X *    Shape/AFS
  56. X *
  57. X *    afcompar.c -- attribute comparison routines 
  58. X *
  59. X *    Author: Andreas Lampen, TU-Berlin (andy@coma.UUCP)
  60. X *                      (andy@db0tui62.BITNET)
  61. X *
  62. X *    $Header: afcompar.c[1.4] Wed Feb 22 16:27:23 1989 andy@coma published $
  63. X *
  64. X *    EXPORT:
  65. X *      af_cmpatime -- compare dates of last access
  66. X *      af_cmpauthor -- compare authors
  67. X *      af_cmpctime -- compare dates of last status change
  68. X *      af_cmpgen -- compare generation numbers
  69. X *      af_cmphost -- compare hosts
  70. X *      af_cmphuman -- compare name, type, gen, rev, variant
  71. X *      af_cmplocker -- compare lockers
  72. X *      af_cmpltime -- compare date of last lock change
  73. X *      af_cmpmode -- compare protections
  74. X *      af_cmpmtime -- compare dates of last modification
  75. X *      af_cmpname -- compare names
  76. X *      af_cmpowner -- compare owners
  77. X *      af_cmprev -- compare revision numbers
  78. X *      af_cmpsize -- compare file sizes
  79. X *      af_cmpstate -- compare states
  80. X *      af_cmpsvtime -- compare dates of saving
  81. X *      af_cmpspath -- compare syspaths
  82. X *      af_cmptype -- compare types
  83. X *      af_cmpvariant -- compare variant attributes
  84. X *      af_cmpversion -- compare version numbers (gen.rev)
  85. X *
  86. X *      af_cmpfuncts -- list of names of all compare functions
  87. X *      af_attrlist -- list of attribute names
  88. X *      af_udaname -- global variable holding the name of the
  89. X *                    user defined attribute used for sorting
  90. X *      af_cmpuda -- compare user defined attributes
  91. X */
  92. X
  93. X#include <stdio.h>
  94. X#include <string.h>
  95. X#ifdef SUNOS_4_0
  96. X#include <strings.h>
  97. X#endif
  98. X
  99. X#include "typeconv.h"
  100. X#include "afsys.h"
  101. X#include "afs.h"
  102. X
  103. X/*================================================================
  104. X *      af_cmpatime -- compare dates of last access
  105. X *
  106. X *================================================================*/
  107. X
  108. XEXPORT int af_cmpatime (key1, key2)
  109. X     Af_key *key1, *key2;
  110. X{
  111. X  return (VATTR(key1).af_atime - VATTR(key2).af_atime);
  112. X}
  113. X
  114. X/*================================================================
  115. X *      af_cmpauthor -- compare authors
  116. X *
  117. X *================================================================*/
  118. X
  119. XEXPORT af_cmpauthor (key1, key2)
  120. X     Af_key *key1, *key2;
  121. X{
  122. X  int res;
  123. X
  124. X  if (!(res = strcmp (NOTNIL(VATTR(key1).af_auname),
  125. X              NOTNIL(VATTR(key2).af_auname))))
  126. X    return (strcmp (NOTNIL(VATTR(key1).af_auhost),
  127. X            NOTNIL(VATTR(key2).af_auhost)));
  128. X  else
  129. X    return (res);
  130. X}
  131. X
  132. X/*================================================================
  133. X *      af_cmpctime -- compare dates of last status change
  134. X *
  135. X *================================================================*/
  136. X
  137. XEXPORT af_cmpctime (key1, key2)
  138. X     Af_key *key1, *key2;
  139. X{
  140. X  return (VATTR(key1).af_ctime - VATTR(key2).af_ctime);
  141. X}
  142. X
  143. X/*================================================================
  144. X *      af_cmpgen -- compare generation numbers
  145. X *
  146. X *================================================================*/
  147. X
  148. XEXPORT af_cmpgen (key1, key2)
  149. X     Af_key *key1, *key2;
  150. X{
  151. X  return (VATTR(key1).af_gen - VATTR(key2).af_gen);
  152. X}
  153. X
  154. X/*================================================================
  155. X *      af_cmphost -- compare hostnames
  156. X *
  157. X *================================================================*/
  158. X
  159. XEXPORT af_cmphost (key1, key2)
  160. X     Af_key *key1, *key2;
  161. X{
  162. X  return (strcmp (CATTR(key1).af_host, CATTR(key2).af_host));
  163. X}
  164. X
  165. X/*================================================================
  166. X *      af_cmphuman -- compare name, type, gen, rev, variant
  167. X *
  168. X *================================================================*/
  169. X
  170. XEXPORT af_cmphuman (key1, key2)
  171. X     Af_key *key1, *key2;
  172. X{
  173. X  int diff;
  174. X
  175. X  if (!(diff = strcmp (VATTR(key1).af_name, VATTR(key2).af_name)) &&
  176. X      !(diff = strcmp (NOTNIL(VATTR(key1).af_type),
  177. X               NOTNIL(VATTR(key2).af_type))) &&
  178. X      !(diff = VATTR(key1).af_gen - VATTR(key2).af_gen) &&
  179. X      !(diff = VATTR(key1).af_rev - VATTR(key2).af_rev))
  180. X    {
  181. X      return (strcmp (NOTNIL(VATTR(key1).af_variant),
  182. X              NOTNIL(VATTR(key2).af_variant)));
  183. X    }
  184. X  return (diff);
  185. X}
  186. X
  187. X/*================================================================
  188. X *      af_cmplocker -- compare lockers
  189. X *
  190. X *================================================================*/
  191. X
  192. XEXPORT af_cmplocker (key1, key2)
  193. X     Af_key *key1, *key2;
  194. X{
  195. X  int res;
  196. X
  197. X  if (!(res = strcmp (NOTNIL(VATTR(key1).af_lckname),
  198. X              NOTNIL(VATTR(key2).af_lckname))))
  199. X    return (strcmp (NOTNIL(VATTR(key1).af_lckhost),
  200. X            NOTNIL(VATTR(key2).af_lckhost)));
  201. X  else
  202. X    return (res);
  203. X}
  204. X
  205. X/*================================================================
  206. X *      af_cmpltime -- compare dates of last lock change
  207. X *
  208. X *================================================================*/
  209. X
  210. XEXPORT af_cmpltime (key1, key2)
  211. X     Af_key *key1, *key2;
  212. X{
  213. X  return (VATTR(key1).af_ltime - VATTR(key2).af_ltime);
  214. X}
  215. X
  216. X/*================================================================
  217. X *      af_cmpmode -- compare protections
  218. X *
  219. X *================================================================*/
  220. X
  221. XEXPORT af_cmpmode (key1, key2)
  222. X     Af_key *key1, *key2;
  223. X{
  224. X  return (VATTR(key1).af_mode - VATTR(key2).af_mode);
  225. X}
  226. X
  227. X/*================================================================
  228. X *      af_cmpmtime -- compare dates of last modification
  229. X *
  230. X *================================================================*/
  231. X
  232. XEXPORT af_cmpmtime (key1, key2)
  233. X     Af_key *key1, *key2;
  234. X{
  235. X  return (VATTR(key1).af_mtime - VATTR(key2).af_mtime);
  236. X}
  237. X
  238. X/*================================================================
  239. X *      af_cmpname -- compare names
  240. X *
  241. X *================================================================*/
  242. X
  243. XEXPORT af_cmpname (key1, key2)
  244. X     Af_key *key1, *key2;
  245. X{
  246. X  return (strcmp (VATTR(key1).af_name, VATTR(key2).af_name));
  247. X}
  248. X
  249. X/*================================================================
  250. X *      af_cmpowner -- compare owners
  251. X *
  252. X *================================================================*/
  253. X
  254. XEXPORT af_cmpowner (key1, key2)
  255. X     Af_key *key1, *key2;
  256. X{
  257. X  int res;
  258. X
  259. X  if (!(res = strcmp (CATTR(key1).af_ownname, CATTR(key2).af_ownname)))
  260. X    return (strcmp (CATTR(key1).af_ownhost, CATTR(key2).af_ownhost));
  261. X  else
  262. X    return (res);
  263. X}
  264. X
  265. X/*================================================================
  266. X *      af_cmprev -- compare revision numbers
  267. X *
  268. X *================================================================*/
  269. X
  270. XEXPORT af_cmprev (key1, key2)
  271. X     Af_key *key1, *key2;
  272. X{
  273. X  return (VATTR(key1).af_rev - VATTR(key2).af_rev);
  274. X}
  275. X
  276. X/*================================================================
  277. X *      af_cmpsize -- compare file size
  278. X *
  279. X *================================================================*/
  280. X
  281. XEXPORT af_cmpsize (key1, key2)
  282. X     Af_key *key1, *key2;
  283. X{
  284. X  return (VATTR(key1).af_fsize - VATTR(key2).af_fsize);
  285. X}
  286. X
  287. X/*================================================================
  288. X *      af_cmpstate -- compare states
  289. X *
  290. X *================================================================*/
  291. X
  292. XEXPORT af_cmpstate (key1, key2)
  293. X     Af_key *key1, *key2;
  294. X{
  295. X  return (VATTR(key1).af_state - VATTR(key2).af_state);
  296. X}
  297. X
  298. X/*================================================================
  299. X *      af_cmpsvtime -- compare dates of saving
  300. X *
  301. X *================================================================*/
  302. X
  303. XEXPORT af_cmpsvtime (key1, key2)
  304. X     Af_key *key1, *key2;
  305. X{
  306. X  return (VATTR(key1).af_stime - VATTR(key2).af_stime);
  307. X}
  308. X
  309. X/*================================================================
  310. X *      af_cmpspath -- compare syspaths
  311. X *
  312. X *================================================================*/
  313. X
  314. XEXPORT af_cmpspath (key1, key2)
  315. X     Af_key *key1, *key2;
  316. X{
  317. X  return (strcmp (CATTR(key1).af_syspath, CATTR(key2).af_syspath));
  318. X}
  319. X
  320. X/*================================================================
  321. X *      af_cmptype -- compare types
  322. X *
  323. X *================================================================*/
  324. X
  325. XEXPORT af_cmptype (key1, key2)
  326. X     Af_key *key1, *key2;
  327. X{
  328. X  return (strcmp (NOTNIL(VATTR(key1).af_type),
  329. X          NOTNIL(VATTR(key2).af_type)));
  330. X}
  331. X
  332. X/*================================================================
  333. X *      af_cmpvariant -- compare variant attribute
  334. X *
  335. X *================================================================*/
  336. X
  337. XEXPORT af_cmpvariant (key1, key2)
  338. X     Af_key *key1, *key2;
  339. X{
  340. X  return (strcmp (NOTNIL(VATTR(key1).af_variant),
  341. X          NOTNIL(VATTR(key2).af_variant)));
  342. X}
  343. X
  344. X/*================================================================
  345. X *      af_cmpversion -- compare version numbers (gen.rev)
  346. X *
  347. X *================================================================*/
  348. X
  349. XEXPORT af_cmpversion (key1, key2)
  350. X     Af_key *key1, *key2;
  351. X{
  352. X  if (VATTR(key1).af_gen == VATTR(key2).af_gen)
  353. X    return (VATTR(key1).af_rev - VATTR(key2).af_rev);
  354. X  else
  355. X    return (VATTR(key1).af_gen - VATTR(key2).af_gen);
  356. X}
  357. X
  358. X/*===============================================================
  359. X *      af_cmpfuncts -- array of comparison functions
  360. X *
  361. X *===============================================================*/
  362. X
  363. Xstruct cmpfun { int (*func) (); };
  364. X
  365. XEXPORT struct cmpfun af_cmpfuncts[] = { af_cmpatime,
  366. X                      af_cmpauthor,
  367. X                      af_cmpctime,
  368. X                      af_cmpgen,
  369. X                      af_cmphost,
  370. X                      af_cmphuman,
  371. X                      af_cmplocker,
  372. X                      af_cmpltime,
  373. X                      af_cmpmode,
  374. X                      af_cmpmtime,
  375. X                      af_cmpname,
  376. X                      af_cmpowner,
  377. X                      af_cmprev,
  378. X                      af_cmpsize,
  379. X                      af_cmpstate,
  380. X                      af_cmpsvtime,
  381. X                      af_cmpspath,
  382. X                      af_cmptype,
  383. X                      af_cmpvariant,
  384. X                      af_cmpversion,
  385. X                    };
  386. X
  387. X
  388. X/*===============================================================
  389. X *      af_attrlist -- list of attribute names
  390. X *                     (in alphabetical order)
  391. X *
  392. X *===============================================================*/
  393. X
  394. XEXPORT char *af_attrlist[] = { AF_ATTATIME,
  395. X                 AF_ATTAUTHOR,
  396. X                 AF_ATTCTIME,
  397. X                 AF_ATTGEN,
  398. X                 AF_ATTHOST,
  399. X                 AF_ATTHUMAN,
  400. X                 AF_ATTLOCKER,
  401. X                 AF_ATTLTIME,
  402. X                 AF_ATTMODE,
  403. X                 AF_ATTMTIME,
  404. X                 AF_ATTNAME,
  405. X                 AF_ATTOWNER,
  406. X                 AF_ATTREV,
  407. X                 AF_ATTSIZE,
  408. X                 AF_ATTSTATE,
  409. X                 AF_ATTSTIME,
  410. X                 AF_ATTSPATH,
  411. X                 AF_ATTTYPE,
  412. X                 AF_ATTVARIANT,
  413. X                 AF_ATTVERSION,
  414. X                };
  415. X
  416. X/*================================================================
  417. X *      af_cmpuda -- compare user defined attributes
  418. X *
  419. X *================================================================*/
  420. X
  421. XEXPORT char af_udaname[AF_UDANAMLEN];
  422. X
  423. XEXPORT af_cmpuda (key1, key2)
  424. X     Af_key *key1, *key2;
  425. X{
  426. X  char *uda1, *uda2, *vallist1, *vallist2, *af_symlookup();
  427. X
  428. X  uda1 = af_symlookup (&(VATTR(key1).af_uhtab), af_udaname,
  429. X               (Af_revlist *)0, (Af_revlist **)0);
  430. X  uda2 = af_symlookup (&(VATTR(key2).af_uhtab), af_udaname,
  431. X               (Af_revlist *)0, (Af_revlist **)0);
  432. X
  433. X  if (uda1 == (char *)0)
  434. X    {
  435. X      if (uda2 == (char *)0)
  436. X    return (0); /* equal */
  437. X      else
  438. X    return (1); /* key1 is "greater" than key2 */
  439. X    }
  440. X  else
  441. X    {
  442. X      if (uda2 == (char *)0)
  443. X    return (-1); /* key2 is "greater" than key1 */
  444. X    }
  445. X
  446. X  /* see if ther are values */
  447. X  vallist1 = index (uda1, AF_UDANAMDEL);
  448. X  vallist2 = index (uda2, AF_UDANAMDEL);
  449. X
  450. X  if (vallist1 == (char *)0)
  451. X    {
  452. X      if (vallist2 == (char *)0)
  453. X    return (0); /* equal */
  454. X      else
  455. X    return (1); /* key1 is "greater" than key2 */
  456. X    }
  457. X  else
  458. X    {
  459. X      if (vallist2 == (char *)0)
  460. X    return (-1); /* key2 is "greater" than key1 */
  461. X    }
  462. X
  463. X  /* compare values of user defined attributes */
  464. X  /* this is a simple textual comparison up to now */
  465. X  return (strcmp (vallist1, vallist2));
  466. X}
  467. X
  468. END_OF_FILE
  469. if test 12396 -ne `wc -c <'src/afs/afcompar.c'`; then
  470.     echo shar: \"'src/afs/afcompar.c'\" unpacked with wrong size!
  471. fi
  472. # end of 'src/afs/afcompar.c'
  473. fi
  474. if test -f 'src/shape/macro.c' -a "${1}" != "-c" ; then 
  475.   echo shar: Will not clobber existing file \"'src/shape/macro.c'\"
  476. else
  477. echo shar: Extracting \"'src/shape/macro.c'\" \(12566 characters\)
  478. sed "s/^X//" >'src/shape/macro.c' <<'END_OF_FILE'
  479. X/*
  480. X * Copyright (C) 1989, 1990 W. Koch, A. Lampen, A. Mahler, W. Obst,
  481. X *  and U. Pralle
  482. X * 
  483. X * This software is published on an as-is basis. There is ABSOLUTELY NO
  484. X * WARRANTY for any part of this software to work correctly or as described
  485. X * in the manuals. We do not accept any liability for any kind of damage
  486. X * caused by use of this software, such as loss of data, time, money, or 
  487. X * effort.
  488. X * 
  489. X * Permission is granted to use, copy, modify, or distribute any part of
  490. X * this software as long as this is done without asking for charge, and
  491. X * provided that this copyright notice is retained as part of the source
  492. X * files. You may charge a distribution fee for the physical act of
  493. X * transferring a copy, and you may at your option offer warranty
  494. X * protection in exchange for a fee.
  495. X * 
  496. X * Direct questions to: Tech. Univ. Berlin
  497. X *              Wilfried Koch
  498. X *              Sekr. FR 5-6 
  499. X *              Franklinstr. 28/29
  500. X *              D-1000 Berlin 10, West Germany
  501. X * 
  502. X *              Tel: +49-30-314-22972
  503. X *              E-mail: shape@coma.uucp or shape@db0tui62.bitnet
  504. X */
  505. X#ifndef lint
  506. Xstatic char *RCSid = "$Header: macro.c,v 3.2 89/02/20 16:25:49 wolfgang Exp $";
  507. X#endif
  508. X#ifndef lint
  509. Xstatic char *ConfFlg = CFFLGS;    /* should be defined from within Makefile */
  510. X#endif
  511. X/*
  512. X * $Log:    macro.c,v $
  513. X * Revision 3.2  89/02/20  16:25:49  wolfgang
  514. X * NET-RELEASE
  515. X * 
  516. X * Revision 3.1  89/02/08  12:45:34  wolfgang
  517. X * performance improved.
  518. X * 
  519. X * Revision 3.0  89/01/24  11:35:54  wolfgang
  520. X * New System Generation
  521. X * 
  522. X * Revision 2.19  89/01/03  13:11:05  wolfgang
  523. X * changes done for lint
  524. X * 
  525. X * Revision 2.18  88/12/21  15:03:44  wolfgang
  526. X * changes done for lint
  527. X * 
  528. X * Revision 2.17  88/12/15  16:16:23  wolfgang
  529. X * bug fixed in get_macros (segmantation violation on sissy (SUN))
  530. X * 
  531. X * Revision 2.16  88/11/21  20:56:56  wolfgang
  532. X * changes done for sun
  533. X * 
  534. X * Revision 2.15  88/11/18  15:01:18  wolfgang
  535. X * bug fixed: ::= indicates no longer a macrodef.
  536. X * 
  537. X * Revision 2.14  88/11/04  16:41:58  wolfgang
  538. X * variant macros no are accumulated.
  539. X * 
  540. X * Revision 2.13  88/10/27  16:37:40  wolfgang
  541. X * bugs fixed (new variant handling).
  542. X * 
  543. X * Revision 2.12  88/10/20  13:20:56  wolfgang
  544. X * bug fixed in get_variant_macro.
  545. X * 
  546. X * Revision 2.11  88/10/18  17:41:12  wolfgang
  547. X * new handling for variants implemented. macro expansion changed.
  548. X * 
  549. X * Revision 2.10  88/10/14  17:14:10  wolfgang
  550. X * new procedure: get_variant_macro added and changes don for new
  551. X * handling of variants.
  552. X * 
  553. X * Revision 2.9  88/10/13  12:03:24  wolfgang
  554. X * handle_comments changed: white space is now required after #%.
  555. X * 
  556. X * Revision 2.8  88/09/16  13:30:57  wolfgang
  557. X * getlin changed. In continuation lines one leading TAB is now suppressd.
  558. X * 
  559. X * Revision 2.7  88/09/09  11:40:31  wolfgang
  560. X * little bug fixed.
  561. X * 
  562. X * Revision 2.6  88/09/08  11:57:51  wolfgang
  563. X * handle_comments(line) improved: # are allowed in quotes.
  564. X * 
  565. X * Revision 2.5  88/09/08  11:48:29  wolfgang
  566. X * handle_comments improved: kills commenmts if there are no quotes.
  567. X * 
  568. X * Revision 2.4  88/09/08  10:32:55  wolfgang
  569. X * handle_comments(line) added. Now comments are allowed in rule- and
  570. X * variant-section, respectively.
  571. X * 
  572. X * Revision 2.3  88/09/07  11:22:38  wolfgang
  573. X * get_macros changed; the files are copied into a tmp file which is
  574. X * the input file for yylex.
  575. X * 
  576. X * Revision 2.2  88/08/23  16:33:21  wolfgang
  577. X * In dump() now \t is supressed for generating confid's (im macrodefinitions
  578. X * \t is not allowed as first char.
  579. X * 
  580. X * Revision 2.1  88/08/19  10:17:33  wolfgang
  581. X * This version is part of a release
  582. X * 
  583. X */
  584. X
  585. X#include <stdio.h>
  586. X#include <sys/types.h>
  587. X#include <sys/dir.h>
  588. X#include "macro.h"
  589. X#include "shape.h"
  590. X
  591. Xextern FILE *mkstemp();
  592. Xextern void addhash();
  593. Xextern char *get_variant_macro();
  594. Xextern char *curvar[];
  595. Xextern struct vardef *vardefs[];
  596. Xchar *template = "/tmp/shapeXXXXXX";
  597. XFILE *temp;
  598. X
  599. X
  600. Xchar *curvpath[8] = {NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL};
  601. Xchar *errstring;
  602. Xint macdepth;
  603. Xint variants_active = 0;
  604. X
  605. Xchar *get_next_item(string)
  606. X     char *string;
  607. X{
  608. X  char *p1;
  609. X
  610. X  if ((p1 = index(string,' ')) != NIL)
  611. X    {
  612. X      *p1 = '\0';
  613. X      return string;
  614. X    }
  615. X  else
  616. X    return string;
  617. X}
  618. X
  619. X
  620. Xchar *getlin(file)
  621. X     FILE *file;
  622. X{
  623. X  char line[MAXLINELENGTH];
  624. X  char line2[MAXLINELENGTH];
  625. X  int len = 0;
  626. X  while (fgets(line, MAXLINELENGTH, file))   /* getc ?????  */
  627. X    {
  628. X      len = strlen(line);
  629. X      while ((line[len-2] == '\\') && (line[len-1] == '\n'))
  630. X    {
  631. X      line[len-2] = ' ';
  632. X      line[len-1] = '\0';
  633. X      (void) fgets(line2, MAXLINELENGTH, file);
  634. X      if(line2[0] == '\t')
  635. X        (void) strcat(line,&line2[1]);
  636. X      else
  637. X        (void) strcat(line,line2);
  638. X      len = strlen(line);
  639. X    }
  640. X      len = strlen(line);
  641. X      line[len-1] = '\0';
  642. X      return (line);
  643. X    }
  644. X/*NOTREACHED*/
  645. X}
  646. X
  647. X
  648. Xget_macros(file)
  649. X     FILE *file;
  650. X{
  651. X  FILE *incfile;
  652. X  char *line;
  653. X  char *incp;
  654. X  int inck;
  655. X  char incfilename[MAXNAMLEN];
  656. X  extern char *expandmacro();
  657. X
  658. X  while((line = getlin(file)) != NIL)
  659. X    {
  660. X
  661. X      if((strncmp(line,INCLUDE,7)) == 0)
  662. X    {
  663. X      inck = 7;
  664. X      while ((line[inck] == '\t') || (line[inck] == ' '))
  665. X        inck++;
  666. X      if ((incp = rindex(line+inck,' ')) != NIL)
  667. X        *incp = '\0';
  668. X      if ((incp = rindex(line+inck,'\t')) != NIL)
  669. X        *incp = '\0';
  670. X      if (index(line+inck,'$') != NIL)
  671. X        (void) strcpy(incfilename,expandmacro(line+inck));
  672. X      else
  673. X        (void) strcpy(incfilename,line+inck);
  674. X      if ((incfile = fopen(incfilename,"r")) == NULL)
  675. X        errexit(24,incfilename);
  676. X      else
  677. X        {
  678. X          get_macros(incfile);
  679. X          (void) fclose(incfile);
  680. X        }
  681. X    }
  682. X      else
  683. X    {
  684. X      handle_comments(line);
  685. X      fputs(line,temp);
  686. X      fputs("\n",temp);
  687. X
  688. X      macrodef(line);
  689. X    }
  690. X    }
  691. X}
  692. X
  693. X
  694. Xmacrodef(line)
  695. X     char *line;
  696. X{
  697. X  char *name;
  698. X  char *value;
  699. X  int hashv;
  700. X  char *p1, *p2;
  701. X  char *enventry;
  702. X  char *line2;
  703. X
  704. X  if (!line)
  705. X    return;
  706. X
  707. X  if ((name = malloc(MACRONAM)) == NIL)
  708. X    errexit(10,"malloc");
  709. X  if((value = malloc(MACROVAL)) == NIL)
  710. X    errexit(10,"malloc");
  711. X  if((line2 = malloc(MAXLINELENGTH)) == NIL)
  712. X    errexit(10,"malloc");
  713. X  if (*line != '\t')
  714. X    {
  715. X      p1 = index(line,'=');
  716. X      p2 = index(line,':');
  717. X      
  718. X      if ((p1 != NIL) && (*(p1-1) != ':') && (*(p1-2) != ':'))
  719. X    {
  720. X      if ((p2 == NIL) || (p1 < p2))
  721. X        {
  722. X          *p1 = '\0';
  723. X          p2 = p1;
  724. X          p2--;
  725. X          while((*line == '\t') || (*line == ' '))
  726. X        line++;
  727. X          while((*p2 == ' ') || (*p2 == '\t'))
  728. X        *p2-- = '\0';
  729. X          name = line;
  730. X        }
  731. X      p1++;
  732. X      while((*p1 == '\t') || (*p1 == ' '))
  733. X        p1++;
  734. X      value = p1;
  735. X      if (strcmp(name,IMPORT) != 0)
  736. X        {
  737. X#ifdef DEBUG_MACRO
  738. Xprintf("name=#%s#\nvalue=#%s#\n\n", name, value);
  739. X#endif DEBUG_MACRO
  740. X          hashv = hashval(name);
  741. X          addhash(hashv,name,value);
  742. X              if (strcmp(name,"VPATH") == 0)
  743. X        {
  744. X          insertvpath(value);
  745. X        }
  746. X            }
  747. X      else
  748. X        { 
  749. X          /* get environment variables */
  750. X          while((name = get_next_item(value)) != NIL)
  751. X        {
  752. X          if (strcmp(value,"") == 0)
  753. X            break;
  754. X          value = index(value,'\0');
  755. X          value++;
  756. X          if ((enventry = getenv(name)) != NIL)
  757. X            {
  758. X              (void) strcpy(line2,name);
  759. X              (void) strcat(line2,"=");
  760. X              (void) strcat(line2,enventry);
  761. X              macrodef(line2);
  762. X            }
  763. X        }
  764. X        }
  765. X    }
  766. X    }
  767. X  free(name);
  768. X  free(line2);
  769. X  free(value);
  770. X}
  771. X
  772. Xchar *expandmacro(inpstring)
  773. X     char *inpstring;
  774. X{
  775. X
  776. Xchar name[64];
  777. Xint hashv;
  778. Xchar *p;
  779. Xstruct hash *current = (struct hash *) NIL;
  780. Xint j = 0;
  781. Xint ii = 0;
  782. Xchar *list[100];
  783. Xchar klazu;
  784. Xchar *start;
  785. Xchar newstr[MAXLINELENGTH];
  786. Xchar *string;
  787. Xchar *mist;
  788. Xchar *variant_macro = NIL;
  789. XBool dollar;
  790. Xdollar = FALSE;
  791. Xif (macdepth == 0)
  792. X    errstring = inpstring;
  793. X
  794. Xmacdepth++;
  795. X
  796. Xif (macdepth == 50)
  797. X  errexit(25, errstring);
  798. X
  799. Xnewstr[0] = '\0';
  800. Xif ((string = malloc((unsigned) (strlen(inpstring) + sizeof(char)))) == NIL)
  801. X  errexit(10,"malloc");
  802. X(void) strcpy(string,inpstring);
  803. Xp = string;
  804. X
  805. Xwhile (*p != '\0')
  806. X  {
  807. X    if (*p != '$')
  808. X      {
  809. X    if (dollar == FALSE)
  810. X      {
  811. X        list[ii] = p;
  812. X        ii++;
  813. X        dollar = FALSE;
  814. X      }
  815. X      if (ii > 100)
  816. X      errexit(25, errstring);
  817. X      }
  818. X    while ((*p != '$') && (*p != '\0'))
  819. X      p++;
  820. X    if ( *p == '\0')
  821. X      break;
  822. X    else
  823. X      {
  824. X    if ((*(p+1) == '(') || (*(p+1) == '{'))
  825. X      {
  826. X        klazu = ((*(p+1) == '(') ? ')':'}');
  827. X        *p = '\0';
  828. X        p = p + 2;
  829. X        start = p;
  830. X
  831. X        while(*p != klazu)
  832. X          {
  833. X        p++;
  834. X          }
  835. X        *p = '\0';
  836. X        (void) strcpy(name,start);
  837. X        p++;
  838. X      }
  839. X    else
  840. X      {
  841. X        if ((*(p+1) != '@') && (*(p+1) != '?') &&
  842. X        (*(p+1) != '<') && (*(p+1) != '*') &&
  843. X        (*(p+1) != '$') && (*(p+1) != '+'))
  844. X          {
  845. X        name[0] = *(p+1);
  846. X        name[1] = '\0';
  847. X        *p = '\0';
  848. X        p = p + 2;
  849. X          }
  850. X        else
  851. X          {
  852. X        name[0] = '\0';
  853. X        dollar = TRUE; 
  854. X        p = p + 2;
  855. X          }
  856. X      }
  857. X    if (name[0] != '\0')
  858. X      {
  859. X        dollar = FALSE;
  860. X
  861. X        if(strcmp(curvar[0],""))
  862. X          {
  863. X        variant_macro = get_variant_macro(name);
  864. X        if (strcmp(variant_macro,BLUMENKOHL))
  865. X          {
  866. X            mist = expandmacro(variant_macro);
  867. X            if ((list[ii] =
  868. X             malloc((unsigned)
  869. X                (strlen(mist) + sizeof(char)))) == NIL)
  870. X              errexit(10,"malloc");
  871. X            (void) strcpy(list[ii],mist);
  872. X            ii++;
  873. X            if (ii > 100)
  874. X              errexit(25, errstring);
  875. X          }
  876. X          }
  877. X        if((variant_macro == NIL) || (!strcmp(variant_macro,BLUMENKOHL)))
  878. X          {
  879. X        variant_macro = NIL;
  880. X        hashv = hashval(name);
  881. X        if (hashtab[hashv] != (struct hash *) NIL)
  882. X          {
  883. X            current = hashtab[hashv];
  884. X            while (((strcmp (current->name, name)) != 0) && (current->next != (struct hash *) NIL))
  885. X              current = current->next;
  886. X            
  887. X            if ((strcmp(current->name, name) == 0))
  888. X              {
  889. X            mist = expandmacro(current->entry);
  890. X            if ((list[ii] =
  891. X                 malloc((unsigned) 
  892. X                    (strlen(mist) + sizeof(char)))) == NIL)
  893. X              errexit(10,"malloc");
  894. X            (void) strcpy(list[ii],mist);
  895. X            ii++;
  896. X            if (ii > 100)
  897. X              errexit(25, errstring);
  898. X              }
  899. X          }
  900. X          }
  901. X      }
  902. X      }
  903. X  }
  904. Xfor (j = 0; j < ii; j++)
  905. X     (void) strcat(newstr,list[j]);
  906. Xmacdepth = 0;
  907. Xreturn newstr;
  908. X} /*end expandmacro */
  909. X
  910. X
  911. X
  912. Xhandle_comments(line)
  913. X     char *line;
  914. X{
  915. X  char *p;
  916. X  int i;
  917. X  int q = 0;
  918. X  int dq = 0;
  919. X
  920. X  if (( p = index(line,'#')) == NIL)
  921. X    /* no comment */
  922. X    return;
  923. X  
  924. X  if ((line[0] == '#') && (line[1] != '%'))
  925. X    {
  926. X      /* comment, starting at beginning of line */
  927. X      line[0] = '\0';
  928. X      return;
  929. X    }
  930. X
  931. X  if (((line[0] == '#') && (line[1] == '%')) &&
  932. X      ((line[2] == ' ') || (line[2] == '\t')))
  933. X    return;
  934. X  
  935. X  if (p != NIL)
  936. X    {
  937. X      if((index(line,'\'') == NIL) && (index(line,'\"') == NIL))
  938. X    /* the # is not in quotes */
  939. X    {
  940. X      *p = '\0';
  941. X      return;
  942. X    }
  943. X      else
  944. X    /* maybe no comment */
  945. X    {
  946. X      for(i = 0; line[i] != '\0'; i++)
  947. X        {
  948. X          if(line[i] == '\'')
  949. X        q++;
  950. X          if(line[i] == '\"')
  951. X        dq++;
  952. X          if((line[i] == '#') && ((q % 2) == 0) && ((dq % 2) == 0))
  953. X        {
  954. X          line[i] = '\0';
  955. X          return;
  956. X        }
  957. X        }
  958. X    }
  959. X    }
  960. X}
  961. X
  962. X
  963. Xchar *get_variant_macro(name)
  964. X     char *name;
  965. X
  966. X     /* get macro value for variant */
  967. X{
  968. Xint i = 0;
  969. Xint k = 0;
  970. Xint j = 0;
  971. X
  972. Xchar *p;
  973. Xchar *p1;
  974. Xchar *p2;
  975. Xchar *p3;
  976. X
  977. Xchar macro[2048];
  978. Xchar retval[1024];
  979. X
  980. Xretval[0] = '\0';
  981. X
  982. Xwhile(strcmp(curvar[i],""))
  983. X  {
  984. X    k = 0;
  985. X    while (vardefs[k] != (struct vardef *) NIL)
  986. X      {
  987. X    if (strcmp(vardefs[k]->name,curvar[i]))
  988. X      k++;
  989. X    else
  990. X      break;
  991. X      }
  992. X
  993. X    if (vardefs[k] != (struct vardef *) NIL)
  994. X      {
  995. X    if ((!strcmp(name,"vpath")) && (vardefs[k]->vpath != NIL))
  996. X      {
  997. X        if (retval[0] == '\0')
  998. X          (void) strcat(retval, vardefs[k]->vpath);
  999. X        else
  1000. X          {
  1001. X        (void) strcat(retval," ");
  1002. X        (void) strcat(retval, vardefs[k]->vpath);
  1003. X          }
  1004. X      }
  1005. X    
  1006. X    if ((!strcmp(name,"vflags")) && (vardefs[k]->vflags != NIL))
  1007. X      {
  1008. X        if (retval[0] == '\0')
  1009. X          (void) strcat(retval,vardefs[k]->vflags);
  1010. X        else
  1011. X          {
  1012. X        (void) strcat(retval," ");
  1013. X        (void) strcat(retval,vardefs[k]->vflags);
  1014. X          }
  1015. X      }
  1016. X
  1017. X    for(j = 0; j < MAXVMACROS; j++)
  1018. X      {
  1019. X        if (vardefs[k]->vmacros[j] == NIL)
  1020. X          {
  1021. X        i++;
  1022. X        break;
  1023. X          }
  1024. X        (void) strcpy(macro,vardefs[k]->vmacros[j]);
  1025. X        if (!strcmp(macro,""))
  1026. X          {
  1027. X        i++;
  1028. X        break;
  1029. X          }
  1030. X        p1 = index(macro,'=');
  1031. X        p2 = index(macro,' ');
  1032. X        p3 = index(macro,'\t');
  1033. X    
  1034. X        if (p2 == NIL)
  1035. X          p2 = p1 + 1;
  1036. X    
  1037. X        if (p3 == NIL)
  1038. X          p3 = p1 + 1;
  1039. X
  1040. X        if (( p1 < p2) && (p1 < p3))
  1041. X          p = p1;
  1042. X        if (( p2 < p1) && (p2 < p3))
  1043. X          p = p2;
  1044. X        if (( p3 < p2) && (p3 < p1))
  1045. X          p = p3;
  1046. X
  1047. X        *p = '\0';
  1048. X        p1++;
  1049. X        
  1050. X        if (!strcmp(name,macro))
  1051. X          {
  1052. X        while((*p1 == ' ') || (*p1 == '\t') || (*p1 == '='))
  1053. X          p1++;
  1054. X        if(retval[0] == '\0')
  1055. X          (void) strcat(retval,p1);
  1056. X        else
  1057. X          {
  1058. X            (void) strcat(retval," ");
  1059. X            (void) strcat(retval,p1);
  1060. X          }
  1061. X          }
  1062. X      }
  1063. X      }
  1064. X    else
  1065. X      i++;
  1066. X  }
  1067. Xif(retval[0] != '\0')
  1068. X  return(retval);
  1069. Xelse
  1070. X  return(BLUMENKOHL);
  1071. X}
  1072. END_OF_FILE
  1073. if test 12566 -ne `wc -c <'src/shape/macro.c'`; then
  1074.     echo shar: \"'src/shape/macro.c'\" unpacked with wrong size!
  1075. fi
  1076. # end of 'src/shape/macro.c'
  1077. fi
  1078. if test -f 'src/vc/vadm_note.c' -a "${1}" != "-c" ; then 
  1079.   echo shar: Will not clobber existing file \"'src/vc/vadm_note.c'\"
  1080. else
  1081. echo shar: Extracting \"'src/vc/vadm_note.c'\" \(12678 characters\)
  1082. sed "s/^X//" >'src/vc/vadm_note.c' <<'END_OF_FILE'
  1083. X/*
  1084. X * Copyright (C) 1989, 1990 W. Koch, A. Lampen, A. Mahler, W. Obst,
  1085. X *  and U. Pralle
  1086. X * 
  1087. X * This software is published on an as-is basis. There is ABSOLUTELY NO
  1088. X * WARRANTY for any part of this software to work correctly or as described
  1089. X * in the manuals. We do not accept any liability for any kind of damage
  1090. X * caused by use of this software, such as loss of data, time, money, or 
  1091. X * effort.
  1092. X * 
  1093. X * Permission is granted to use, copy, modify, or distribute any part of
  1094. X * this software as long as this is done without asking for charge, and
  1095. X * provided that this copyright notice is retained as part of the source
  1096. X * files. You may charge a distribution fee for the physical act of
  1097. X * transferring a copy, and you may at your option offer warranty
  1098. X * protection in exchange for a fee.
  1099. X * 
  1100. X * Direct questions to: Tech. Univ. Berlin
  1101. X *              Wilfried Koch
  1102. X *              Sekr. FR 5-6 
  1103. X *              Franklinstr. 28/29
  1104. X *              D-1000 Berlin 10, West Germany
  1105. X * 
  1106. X *              Tel: +49-30-314-22972
  1107. X *              E-mail: shape@coma.uucp or shape@db0tui62.bitnet
  1108. X */
  1109. X#ifndef lint
  1110. Xstatic char *AFSid = "$Header: vadm_note.c[3.10] Thu Feb 23 18:14:13 1989 axel@coma published $";
  1111. X#ifdef CFFLGS
  1112. Xstatic char *ConfFlg = CFFLGS;
  1113. X    /* should be defined from within Makefile */
  1114. X#endif
  1115. X#endif
  1116. X/*
  1117. X * Log for /u/shape/dist-tape/src/vc/vadm_note.c[3.4]
  1118. X *     Thu Feb 23 18:14:13 1989 axel@coma published $
  1119. X *  --- empty log message ---
  1120. X *  vadm_note.c[3.6] Thu Feb 23 18:14:13 1989 axel@coma published $
  1121. X *  --- empty log message ---
  1122. X *  vadm_note.c[3.7] Thu Feb 23 18:14:13 1989 axel@coma save $
  1123. X *  --- empty log message ---
  1124. X *  vadm_note.c[3.8] Thu Feb 23 18:14:13 1989 axel@coma save $
  1125. X *  --- empty log message ---
  1126. X *  vadm_note.c[3.9] Thu Feb 23 18:14:13 1989 axel@coma save $
  1127. X *  --- empty log message ---
  1128. X *  vadm_note.c[3.10] Thu Feb 23 18:14:13 1989 axel@coma published $
  1129. X *  --- empty log message ---
  1130. X */
  1131. X
  1132. X#include <stdio.h>
  1133. X#include <strings.h>
  1134. X#include <afs.h>
  1135. X#include "vadm.h"
  1136. X#include "afsapp.h"
  1137. X#include "locks.h"
  1138. X#include "vc_sysdep.h"
  1139. X
  1140. X/* Externals */
  1141. Xextern int af_errno;
  1142. Xextern jmp_buf here;        /* reentrance point after we caught a sig */
  1143. Xextern char *malloc (), *getenv();
  1144. Xextern char **environment;    /* pointer to our environment */
  1145. Xextern struct Transaction ThisTransaction;
  1146. Xextern char *get_from_stdin();    /* read a text from stdin */
  1147. Xextern int call_editor();    /* returns a text */
  1148. Xextern char *FindProgram(), *FindFile();
  1149. Xextern unsigned int options;
  1150. Xextern int def_vnum;
  1151. X
  1152. X/* locals */
  1153. Xstatic char buf[100];        /* buffer for error messages */
  1154. Xstatic char *editor;        /* user's favorite editor*/
  1155. X
  1156. X/**/
  1157. Xstatic
  1158. Xint determine_defaults ()
  1159. X{
  1160. X  /*
  1161. X   * Returns 0 on error (editor not found, editor not executable, and so).
  1162. X   * 1 on success.
  1163. X   */
  1164. X  char *neweditor;
  1165. X  int ask_default = 0;        /* if env-editor is not available */
  1166. X                /* user if he/she want's default editor */
  1167. X
  1168. X  /* examine user's favorite editor, if any */
  1169. X  if ((editor = getenv (EDITOR_ENV_NAME)) == NULL)
  1170. X    editor = DEFAULT_EDITOR;
  1171. X
  1172. X  if (!index (editor, '/'))
  1173. X    if ((neweditor = FindFile (editor)) == NULL) {
  1174. X      (void)sprintf (buf, "Sorry, your favorite editor %s is not available on this machine.",
  1175. X             editor);
  1176. X      logmsg (buf);
  1177. X      ask_default++;
  1178. X    }
  1179. X    else
  1180. X      editor = neweditor;
  1181. X  
  1182. X  /* is editor executable ? */
  1183. X  if (!ask_default && !FileExecutable (editor)) {
  1184. X   (void)sprintf (buf, "Sorry, your favorite editor %s is not executable.",
  1185. X         editor);
  1186. X    logmsg (buf);
  1187. X    ask_default++;
  1188. X  }
  1189. X  
  1190. X  if (ask_default) {
  1191. X    /* if default editor not available resign. */
  1192. X    if (strcmp (editor, DEFAULT_EDITOR)) {
  1193. X      (void)sprintf (buf, "Do you accept default editor %s ?", DEFAULT_EDITOR);
  1194. X      if (ask_confirm (buf, "yes")) {
  1195. X    editor = DEFAULT_EDITOR;
  1196. X    if (!FileExecutable (editor)) {
  1197. X      logmsg ("Arrg, also default editor is not available. --- I resign.");
  1198. X      return 0;
  1199. X    }
  1200. X      }
  1201. X      else
  1202. X    return 0;        /* user doesn't want */
  1203. X    }
  1204. X    else
  1205. X      return 0;            /* default editor is not available */
  1206. X  }
  1207. X  return 1;
  1208. X}
  1209. X
  1210. X/**/
  1211. Xstatic
  1212. Xint note_ok (newnote, oldnote)
  1213. X     char *newnote, *oldnote;
  1214. X{
  1215. X  /*
  1216. X   * returns 0 if no changes detected, 1 otherwise.
  1217. X   */
  1218. X    
  1219. X  if (!newnote) {
  1220. X    if (ask_confirm ("Description is empty. Save anyway ?", "no"))
  1221. X      return 0;
  1222. X    else
  1223. X      return 1;
  1224. X  }
  1225. X      
  1226. X  if (oldnote && !strcmp (newnote, oldnote)) {
  1227. X    logmsg ("No changes detected.");
  1228. X    return 0;
  1229. X  }
  1230. X
  1231. X  /* newnote contains only layout ? */
  1232. X  while (*newnote) {
  1233. X    switch (*newnote) {
  1234. X    case ' ':
  1235. X    case '\n':
  1236. X    case '\t':
  1237. X      break;
  1238. X    default:
  1239. X      return 1;
  1240. X      break;
  1241. X    }
  1242. X    newnote++;
  1243. X  }
  1244. X
  1245. X  if (ask_confirm ("Description contains only layout. Save anyway?", "no"))
  1246. X    return 0;
  1247. X  else
  1248. X    return 1;
  1249. X}
  1250. X
  1251. X/**/
  1252. Xstatic
  1253. Xint save_it (key, note)
  1254. X     Af_key *key;
  1255. X     char *note;
  1256. X{
  1257. X  af_snote (key, note);
  1258. X  ThisTransaction.tr_done = 1;
  1259. X}
  1260. X
  1261. X/**/
  1262. Xstatic
  1263. Xint save_note_multiple (note, set)
  1264. X     char *note;
  1265. X     Af_set *set;
  1266. X{
  1267. X  int i, rc = 0;
  1268. X
  1269. X  for (i = 0 ; i < set->af_nkeys; i++) {
  1270. X    rc += af_snote (&(set->af_klist[i]), note);
  1271. X  }
  1272. X  if (note) free (note);
  1273. X  return rc;
  1274. X}
  1275. X
  1276. X/**/
  1277. Xstatic
  1278. Xint process_notes (set, change_it)
  1279. X     Af_set *set;
  1280. X     int change_it;
  1281. X{
  1282. X  int i;
  1283. X  char *note, *newnote, *mktemp();
  1284. X  int retcode;            /* retcode from editor */
  1285. X  char tmp_file[20];        /* tmp-file's name */
  1286. X  char name[MAXNAMLEN], nametype[MAXTYPLEN];
  1287. X  
  1288. X  if (!determine_defaults ())    /* that is the editor */
  1289. X    return -1;
  1290. X  
  1291. X  CatchSigs ();
  1292. X
  1293. X  /* read description per file and save if changes. */
  1294. X  for (i = 0; i < set->af_nkeys; i++) {
  1295. X
  1296. X    /* remember this location */
  1297. X    if (setjmp (ThisTransaction.tr_env)) {
  1298. X      if ( i < set->af_nkeys )
  1299. X    continue;
  1300. X      else
  1301. X    return 0;
  1302. X    }
  1303. X
  1304. X    /* construct file name */
  1305. X    (void)sprintf (nametype, "%s", af_rtype(&set->af_klist[i]));
  1306. X    (void)sprintf (name,  "%s%c%s", af_rname(&set->af_klist[i]),
  1307. X         nametype ? '.' : NULL,
  1308. X         nametype ? nametype : NULL);
  1309. X    
  1310. X    ThisTransaction.tr_seqno = i;
  1311. X    (void)strcpy (ThisTransaction.tr_fname, name);
  1312. X    ThisTransaction.tr_done = 0;
  1313. X      
  1314. X    /* print afsname and version */
  1315. X    (void)sprintf (buf, "%s[%d.%d]:", name, af_rgen (&set->af_klist[i]),
  1316. X         af_rrev (&set->af_klist[i]));
  1317. X    logmsg (buf);        /* this file */
  1318. X    
  1319. X    (void)strcpy (tmp_file, mktemp ("/tmp/vctlXXXXXX"));
  1320. X
  1321. X    /* Do we change the old note ? */
  1322. X    if (change_it) {        /* get old note */
  1323. X      note = af_rnote (&set->af_klist[i]);
  1324. X
  1325. X      /* Note "Empty log message" is an empty note  */
  1326. X      if (!strcmp (note, EMPTYNOTE)) {
  1327. X    free (note);
  1328. X    note = NULL;
  1329. X      }
  1330. X    }
  1331. X    else
  1332. X      note = NULL;
  1333. X    
  1334. X    newnote = NULL;
  1335. X    retcode = call_editor (editor, tmp_file, note, &newnote);
  1336. X      
  1337. X    if (retcode == -1) {    /* editor exited abnormally */
  1338. X      if (i == (set->af_nkeys - 1)) {
  1339. X    logmsg ("Description lost.");
  1340. X    return 1;
  1341. X      }
  1342. X      
  1343. X      if (ask_confirm ("Description lost. Continue ?", "no"))
  1344. X    return 1;
  1345. X      else
  1346. X    continue;
  1347. X    }
  1348. X    
  1349. X    if (note_ok (newnote, note)) { /* any changes ? */
  1350. X      save_it (&set->af_klist[i], newnote);
  1351. X      logmsg ("Description saved.");
  1352. X    }
  1353. X    else
  1354. X      logmsg ("Description not saved.");
  1355. X    
  1356. X    if (note)
  1357. X      free (note);
  1358. X    
  1359. X    if (newnote)
  1360. X      free (newnote);
  1361. X  }
  1362. X  return 0;
  1363. X}
  1364. X
  1365. X/**/
  1366. Xprint_erroneous (erroneous, errs)
  1367. X     char **erroneous;
  1368. X     int errs;
  1369. X{
  1370. X  int i, j;
  1371. X  
  1372. X  fprintf (stderr, "No saved versions of");
  1373. X  j = 0;
  1374. X  for (i = 0; i < errs; i++) {
  1375. X    if (++j == errs)
  1376. X      if (errs == 1)
  1377. X    fprintf (stderr, " \"%s\"", erroneous[i]);
  1378. X      else
  1379. X    fprintf (stderr, " and \"%s\"", erroneous[i]);
  1380. X    else
  1381. X      fprintf (stderr, " \"%s\",", erroneous[i]);
  1382. X  }
  1383. X  fprintf (stderr, " found --- skipped\n");
  1384. X}
  1385. X
  1386. X/**/
  1387. Xstatic
  1388. Xint do_note (vlist, ac, av, change_it)
  1389. X     struct vc_vlist *vlist;
  1390. X     int ac;
  1391. X     char **av;
  1392. X     int change_it;
  1393. X{
  1394. X  Af_set set;
  1395. X  int errs;
  1396. X  char **erroneous;
  1397. X  
  1398. X  if (IsOptionSet(Vopt_version)) {
  1399. X    errs = GetKeysByGenRev
  1400. X    (ac,av, gen(def_vnum), rev(def_vnum), &set, 
  1401. X     &erroneous);
  1402. X  }
  1403. X  else {
  1404. X    if (! ((vlist->from_version_set) || vlist->to_version_set))
  1405. X      errs = GetKeysByGenRev 
  1406. X    (ac,av, AF_BUSYVERS, AF_BUSYVERS, &set, &erroneous);
  1407. X    else
  1408. X      errs = GetKeysByName (ac,av, vlist, &set, &erroneous);
  1409. X  }
  1410. X  if (errs)
  1411. X    print_erroneous (erroneous, errs);
  1412. X
  1413. X  /* all given files do not exist ? */
  1414. X  if (!set.af_nkeys) {
  1415. X    logmsg ("Nothing appropriate found.");
  1416. X    return 1;
  1417. X  }
  1418. X
  1419. X  if (af_sortset (&set, AF_ATTHUMAN) == -1) {
  1420. X    af_perror ("Do_note: af_sortset AF_ATTHUMAN");
  1421. X    return 1;
  1422. X  }
  1423. X      
  1424. X  /* If stdin is redirected use text as description for *all* afs files. */
  1425. X  if (!isatty (0)) {        /* 0 == stdin */
  1426. X    /* do not append to old desc. Also we have no special term-char.
  1427. X     * Read until EOF. */
  1428. X    return save_note_multiple (get_from_stdin ((char *)NULL, -1), &set);
  1429. X  }
  1430. X  
  1431. X  /* shall we go on if an error occurs? Ask user. */
  1432. X  if (errs && (!ask_confirm ("Continue anyway ?", "yes")))
  1433. X      return 1;
  1434. X    
  1435. X  return process_notes (&set, change_it);
  1436. X}
  1437. X
  1438. X/**/
  1439. Xint DoSetNote (vlist, ac, av)
  1440. X     struct vc_vlist *vlist;
  1441. X     int ac;
  1442. X     char **av;
  1443. X{
  1444. X  return do_note (vlist, ac, av, 0); /* don't change existing note */
  1445. X}
  1446. X
  1447. X/**/
  1448. Xint DoChangeNote (vlist, ac, av)
  1449. X     struct vc_vlist *vlist;
  1450. X     int ac;
  1451. X     char **av;
  1452. X{
  1453. X  return do_note (vlist, ac, av, 1); /* change existing note */
  1454. X}
  1455. X
  1456. X/**/
  1457. Xstatic
  1458. Xint do_description (vlist, ac, av, change_it)
  1459. X     struct vc_vlist *vlist;
  1460. X     int ac;
  1461. X     char **av;
  1462. X     int change_it;        /* if set, append to old note */
  1463. X{
  1464. X  /*
  1465. X   * Changes an existing description note of the first version (i.e. 1.0)
  1466. X   * of an AFS file. Returns 0 on success, otherwise 1 to indicate an error.
  1467. X   */
  1468. X
  1469. X  Af_set set;
  1470. X  int errs = 0;            /* # of not found afs files */
  1471. X  char **erroneous;
  1472. X  
  1473. X  /* A version list makes no sence. Ignore it, but display warning msg. */
  1474. X  if (vlist->from_version_set || vlist->to_version_set)
  1475. X    logwng ("version specification list ignored.");
  1476. X  
  1477. X  errs = GetKeysByGenRev (ac,av, AF_FIRSTVERS, AF_FIRSTVERS, &set, 
  1478. X              &erroneous);
  1479. X
  1480. X  if (errs)
  1481. X    print_erroneous (erroneous, errs);
  1482. X  
  1483. X  /* all given files do not exist ? */
  1484. X  if (!set.af_nkeys) {
  1485. X    logmsg ("Nothing appropriate found.");
  1486. X    return 1;
  1487. X  }
  1488. X    
  1489. X  if (af_sortset (&set, AF_ATTHUMAN) == -1) {
  1490. X    af_perror ("Do_description: af_sortset AF_ATTHUMAN");
  1491. X    return 1;
  1492. X  }
  1493. X      
  1494. X  /* If stdin is redirected use text as description for *all* afs files. */
  1495. X  if (!isatty (0)) {        /* 0 == stdin */
  1496. X    /* do not append to old desc. Also we have no special term-char.
  1497. X     * Read until EOF. */
  1498. X    return save_note_multiple (get_from_stdin ((char *)NULL, -1), &set);
  1499. X  }
  1500. X    
  1501. X  /* shall we go on if an error occurs? Ask user. */
  1502. X  if (errs && (!ask_confirm ("Continue anyway ?", "yes")))
  1503. X    return 1;
  1504. X
  1505. X  return process_notes (&set, change_it);
  1506. X}
  1507. X
  1508. X/**/
  1509. Xint DoSetDescription (vlist, ac, av)
  1510. X     struct vc_vlist *vlist;
  1511. X     int ac;
  1512. X     char **av;
  1513. X{
  1514. X  return do_description (vlist, ac, av, 0); /* don't change existing note */
  1515. X}
  1516. X
  1517. X/**/
  1518. Xint DoChangeDescription (vlist, ac, av)
  1519. X     struct vc_vlist *vlist;
  1520. X     int ac;
  1521. X     char **av;
  1522. X{
  1523. X  return do_description (vlist, ac, av, 1); /* change to old note */
  1524. X}
  1525. X
  1526. Xint DoSetIntent (ac, av) int ac; char **av; {
  1527. X  /* We must hold the lock for the history, that we wanna change. */
  1528. X  register int i;
  1529. X  int rc, rcsum = 0;
  1530. X  char fname[256], messg[80], *oldintent, *intent, *getintent(), *intattr,
  1531. X       *lockerid();
  1532. X  Af_key thiskey;
  1533. X  Af_user *locker;
  1534. X
  1535. X
  1536. X  for (i=0; i < ac; i++) {
  1537. X    if (setjmp (ThisTransaction.tr_env)) continue;
  1538. X    rc = af_getkey (af_afpath (av[i]), af_afname (av[i]), 
  1539. X            af_aftype (av[i]), AF_BUSYVERS, AF_BUSYVERS,
  1540. X            AF_NONAME, &thiskey);
  1541. X    if (rc < 0) {
  1542. X      (void)sprintf (messg, "can't find busy version for %s.", av[i]);
  1543. X      logerr (messg);
  1544. X      continue;
  1545. X    }
  1546. X    mkvstring (fname, &thiskey);
  1547. X    if (locked(locker=vc_testlock_v(&thiskey))) {
  1548. X      if (lockeruid (locker) == (Uid_t)getuid ()) {
  1549. X    oldintent = af_rudattr (&thiskey, INTENT);
  1550. X    intent = getintent ((char *)NULL, oldintent);
  1551. X    if (oldintent) free (oldintent);
  1552. X    intattr = malloc ((unsigned)(strlen (intent) + strlen (INTENT) +1));
  1553. X    (void)sprintf (intattr, "%s%s", INTENT, intent);
  1554. X    if (fail(af_sudattr (&thiskey, AF_REPLACE, intattr)))
  1555. X      af_sudattr (&thiskey, AF_ADD, intattr);
  1556. X    free (intattr);
  1557. X    af_dropkey (&thiskey);
  1558. X      }
  1559. X      else {
  1560. X    (void)sprintf (messg, "Can't set intent on %s (locked by %s).",
  1561. X         fname, lockerid (locker));
  1562. X    logerr (messg);
  1563. X    af_dropkey (&thiskey);
  1564. X    rcsum++;
  1565. X    continue;
  1566. X      }
  1567. X    }
  1568. X    else {
  1569. X      (void)sprintf (messg, "You must have a lock on %s to set change intention.", 
  1570. X           fname);
  1571. X      logerr (messg);
  1572. X      af_dropkey (&thiskey);
  1573. X      rcsum++;
  1574. X      continue;
  1575. X    }
  1576. X  }
  1577. X  return rcsum;
  1578. X}    
  1579. X    
  1580. END_OF_FILE
  1581. if test 12678 -ne `wc -c <'src/vc/vadm_note.c'`; then
  1582.     echo shar: \"'src/vc/vadm_note.c'\" unpacked with wrong size!
  1583. fi
  1584. # end of 'src/vc/vadm_note.c'
  1585. fi
  1586. if test -f 'src/vc/vadm_reserve.c' -a "${1}" != "-c" ; then 
  1587.   echo shar: Will not clobber existing file \"'src/vc/vadm_reserve.c'\"
  1588. else
  1589. echo shar: Extracting \"'src/vc/vadm_reserve.c'\" \(12489 characters\)
  1590. sed "s/^X//" >'src/vc/vadm_reserve.c' <<'END_OF_FILE'
  1591. X/*
  1592. X * Copyright (C) 1989, 1990 W. Koch, A. Lampen, A. Mahler, W. Obst,
  1593. X *  and U. Pralle
  1594. X * 
  1595. X * This software is published on an as-is basis. There is ABSOLUTELY NO
  1596. X * WARRANTY for any part of this software to work correctly or as described
  1597. X * in the manuals. We do not accept any liability for any kind of damage
  1598. X * caused by use of this software, such as loss of data, time, money, or 
  1599. X * effort.
  1600. X * 
  1601. X * Permission is granted to use, copy, modify, or distribute any part of
  1602. X * this software as long as this is done without asking for charge, and
  1603. X * provided that this copyright notice is retained as part of the source
  1604. X * files. You may charge a distribution fee for the physical act of
  1605. X * transferring a copy, and you may at your option offer warranty
  1606. X * protection in exchange for a fee.
  1607. X * 
  1608. X * Direct questions to: Tech. Univ. Berlin
  1609. X *              Wilfried Koch
  1610. X *              Sekr. FR 5-6 
  1611. X *              Franklinstr. 28/29
  1612. X *              D-1000 Berlin 10, West Germany
  1613. X * 
  1614. X *              Tel: +49-30-314-22972
  1615. X *              E-mail: shape@coma.uucp or shape@db0tui62.bitnet
  1616. X */
  1617. X#ifndef lint
  1618. Xstatic char *AFSid = "$Header: vadm_reserve.c[3.13] Thu Feb 23 18:14:17 1989 axel@coma published $";
  1619. X#ifdef CFFLGS
  1620. Xstatic char *ConfFlg = CFFLGS;
  1621. X    /* should be defined from within Makefile */
  1622. X#endif
  1623. X#endif
  1624. X/*
  1625. X * Log for /u/shape/dist-tape/src/vc/vadm_reserve.c[3.7]
  1626. X *     Thu Feb 23 18:14:17 1989 axel@coma published $
  1627. X *  --- empty log message ---
  1628. X *  vadm_reserve.c[3.9] Thu Feb 23 18:14:18 1989 axel@coma published $
  1629. X *  --- empty log message ---
  1630. X *  vadm_reserve.c[3.11] Thu Feb 23 18:14:18 1989 axel@coma published $
  1631. X *  --- empty log message ---
  1632. X *  vadm_reserve.c[3.12] Thu Feb 23 18:14:18 1989 axel@coma save $
  1633. X *  --- empty log message ---
  1634. X *  vadm_reserve.c[3.13] Thu Feb 23 18:14:18 1989 axel@coma published $
  1635. X *  --- empty log message ---
  1636. X */
  1637. X
  1638. X#include <sys/types.h>
  1639. X#include <sys/stat.h>
  1640. X
  1641. X#include <pwd.h>
  1642. X#include <stdio.h>
  1643. X#include <strings.h>
  1644. X
  1645. X#include "afs.h"
  1646. X#include "vadm.h"
  1647. X#include "afsapp.h"
  1648. X#include "locks.h"
  1649. X
  1650. X/* externals */
  1651. Xextern char *malloc();
  1652. Xextern int newmode;
  1653. Xextern Af_user newauthor;
  1654. Xextern int def_vnum;
  1655. Xextern struct Transaction ThisTransaction;
  1656. X
  1657. X/* forward */
  1658. Xchar *uidname ();
  1659. X
  1660. X/* locals */
  1661. Xstatic char buf[2048];
  1662. X
  1663. X/**/
  1664. XUid_t af_MY_rouid (key) Af_key *key; {
  1665. X  /*
  1666. X   *  This function returns the userid of the owner of the AFS directory
  1667. X   *  containing the AFS object identified by key.
  1668. X   */
  1669. X  char path[256];
  1670. X  struct stat statbuf;
  1671. X
  1672. X  (void)strcpy (path, af_rsyspath (key));
  1673. X  if (strcmp (path, "/") == NULL)
  1674. X    (void)strcpy (path, "");
  1675. X  (void)strcat (path, "/AFS");
  1676. X  if (stat (path, &statbuf) < 0) {
  1677. X    perror (path);
  1678. X    return -1;
  1679. X  }
  1680. X  return statbuf.st_uid;
  1681. X}
  1682. X
  1683. Xint do_reserve (set)
  1684. X     Af_set *set;
  1685. X{
  1686. X  register int i;
  1687. X  Af_user *locker;
  1688. X  int errs = 0;
  1689. X  char version[1024], *fn, *mkfn(), *p, *lockerid();
  1690. X  struct stat sbuf;
  1691. X
  1692. X  if (af_sortset (set, AF_ATTHUMAN) == -1)
  1693. X    vctl_abort ("do_reserve: af_sortset()");
  1694. X      
  1695. X  for (i = 0; i < set->af_nkeys; i++) {
  1696. X    mkvstring (version, &set->af_klist[i]);
  1697. X    if (setjmp (ThisTransaction.tr_env)) continue;
  1698. X    /* if (locking == AF_GLOBALLOCK) { /* to be implemented */
  1699. X    if (p=rindex(version, '[')) *p = '\0';
  1700. X    
  1701. X    if (!locked(locker = vc_testlock_g(&set->af_klist[i]))) {
  1702. X      logmsg ("WARNING! Administrative locking may lose attribute citations.");
  1703. X      if (vc_lock_g(&set->af_klist[i], (Uid_t)geteuid()) == (Af_user *)NULL) {
  1704. X    af_perror ("af_lock");
  1705. X    continue;
  1706. X      }
  1707. X      else {
  1708. X    if (af_rstate (&set->af_klist[i]) == AF_BUSY) {
  1709. X      char *intent, *getintent();
  1710. X      extern unsigned int options;
  1711. X      if (!IsOptionSet (Vopt_quiet)) {
  1712. X        intent = getintent ("Describe intended changes ?", (char *)NULL);
  1713. X      }
  1714. X      else intent = (char *)NULL;
  1715. X      if (intent) {
  1716. X        char *intattr;
  1717. X        intattr = malloc ((unsigned)(strlen (intent) + 
  1718. X                     strlen (INTENT) +1));
  1719. X        (void)sprintf (intattr, "%s%s", INTENT, intent);
  1720. X        if (fail(af_sudattr (&set->af_klist[i], AF_REPLACE, intattr)))
  1721. X           af_sudattr (&set->af_klist[i] , AF_ADD, intattr);
  1722. X        free (intattr);
  1723. X      }
  1724. X    }
  1725. X    (void)sprintf (buf, "%s reserved.", version);
  1726. X    fn = mkfn (&set->af_klist[i]);
  1727. X    if (stat (fn, &sbuf) == 0) {
  1728. X      (void)chmod (fn, (int)(sbuf.st_mode | 0200));
  1729. X    }
  1730. X    logmsg (buf);
  1731. X      }
  1732. X    }
  1733. X    else { /* testlock returned something */
  1734. X      if (lockeruid(locker) != (Uid_t)geteuid()) {
  1735. X    (void)sprintf (buf, "%s is already locked by %s.", version, 
  1736. X         lockerid (locker));
  1737. X    logmsg (buf);
  1738. X    errs++;
  1739. X    continue;
  1740. X      }
  1741. X      else {
  1742. X    (void)sprintf (buf, "%s reserved.", version);
  1743. X    fn = mkfn (&set->af_klist[i]);
  1744. X    if (stat (fn, &sbuf) == 0) {
  1745. X      (void)chmod (fn, (int)(sbuf.st_mode | 0200));
  1746. X    }
  1747. X    logmsg (buf);
  1748. X      }
  1749. X    }
  1750. X  }
  1751. X  if (errs)
  1752. X    return 1;
  1753. X  else
  1754. X    return 0;
  1755. X}
  1756. X
  1757. Xint do_chmod (set)
  1758. X     Af_set *set;
  1759. X{
  1760. X  int i;
  1761. X  int errs = 0;
  1762. X  char version[1024];
  1763. X  
  1764. X  if (af_sortset (set, AF_ATTHUMAN) == -1)
  1765. X    vctl_abort ("do_chmod: af_sortset()");
  1766. X      
  1767. X  for (i = 0; i < set->af_nkeys; i++) {
  1768. X    mkvstring (version, &set->af_klist[i]);
  1769. X    if (setjmp (ThisTransaction.tr_env)) continue; 
  1770. X    if (af_MY_rouid (&set->af_klist[i]) != (Uid_t)geteuid()) {
  1771. X      (void)sprintf (buf, "%s not owned by %s.", version, 
  1772. X           uidname((Uid_t)geteuid()));
  1773. X      logmsg (buf);
  1774. X      errs++;
  1775. X      continue;
  1776. X    }
  1777. X    else {
  1778. X      if (af_chmod (&set->af_klist[i], newmode) < 0) {
  1779. X    af_perror ("af_chmod");
  1780. X    errs++;
  1781. X    continue;
  1782. X      }
  1783. X      (void)sprintf (buf, "%s done.", version);
  1784. X      logmsg (buf);
  1785. X    }
  1786. X  }
  1787. X  if (errs)
  1788. X    return 1;
  1789. X  else
  1790. X    return 0;
  1791. X}
  1792. X
  1793. Xint do_chown (set)
  1794. X     Af_set *set;
  1795. X{
  1796. X  int i;
  1797. X  int errs = 0;
  1798. X  char version[1024];
  1799. X  
  1800. X  if (af_sortset (set, AF_ATTHUMAN) == -1)
  1801. X    vctl_abort ("do_chown: af_sortset()");
  1802. X      
  1803. X  for (i = 0; i < set->af_nkeys; i++) {
  1804. X    mkvstring (version, &set->af_klist[i]);
  1805. X    if (setjmp (ThisTransaction.tr_env)) continue; 
  1806. X    if (lockeruid (af_rowner (&set->af_klist[i])) != geteuid()) {
  1807. X      (void)sprintf (buf, "%s not owned by %s.", version, 
  1808. X           uidname (geteuid()));
  1809. X      logmsg (buf);
  1810. X      errs++;
  1811. X      continue;
  1812. X    }
  1813. X    else {
  1814. X      logmsg ("This function is not available under BSD.");
  1815. X      errs++;
  1816. X      continue;
  1817. X    }
  1818. X  }
  1819. X  if (errs)
  1820. X    return 1;
  1821. X  else
  1822. X    return 0;
  1823. X}
  1824. X
  1825. Xint do_chaut (set)
  1826. X     Af_set *set;
  1827. X{
  1828. X  int i;
  1829. X  int errs = 0;
  1830. X  char version[1024];
  1831. X  
  1832. X  if (af_sortset (set, AF_ATTHUMAN) == -1)
  1833. X    vctl_abort ("do_chaut: af_sortset()");
  1834. X      
  1835. X  for (i = 0; i < set->af_nkeys; i++) {
  1836. X    mkvstring (version, &set->af_klist[i]);
  1837. X    if (setjmp (ThisTransaction.tr_env)) continue; 
  1838. X    if (af_MY_rouid (&set->af_klist[i]) != (Uid_t)geteuid()) {
  1839. X      (void)sprintf (buf, "%s not owned by %s.", version, 
  1840. X           uidname ((Uid_t)geteuid()));
  1841. X      logmsg (buf);
  1842. X      errs++;
  1843. X      continue;
  1844. X    }
  1845. X    else {
  1846. X      if (af_chauthor (&set->af_klist[i], &newauthor) < 0) {
  1847. X    af_perror ("af_chaut");
  1848. X    errs++;
  1849. X    continue;
  1850. X      }
  1851. X      (void)sprintf (buf, "%s done.", version);
  1852. X      logmsg (buf);
  1853. X    }
  1854. X  }
  1855. X  if (errs)
  1856. X    return 1;
  1857. X  else
  1858. X    return 0;
  1859. X}
  1860. X
  1861. X/**/
  1862. XDoReserve (ac, av)
  1863. X     int ac;
  1864. X     char **av;
  1865. X{
  1866. X  Af_set set;
  1867. X  int errs, errput = 0;
  1868. X  char **erroneous;
  1869. X
  1870. X  errs = GetKeysByGenRev (ac,av, AF_BUSYVERS, AF_BUSYVERS, &set, 
  1871. X              &erroneous);
  1872. X
  1873. X  if (errs) {
  1874. X    print_erroneous (erroneous, errs);
  1875. X    errput++;
  1876. X  }
  1877. X
  1878. X  if (!set.af_nkeys && !errput) {
  1879. X    logmsg ("Nothing appropriate found.");
  1880. X    return 1;
  1881. X  }
  1882. X
  1883. X  if (errs && !ask_confirm ("Continue ?", "yes"))
  1884. X    return 1;
  1885. X
  1886. X  return do_reserve (&set);
  1887. X}
  1888. X
  1889. Xint do_unreserve (set)
  1890. X     Af_set *set;
  1891. X{
  1892. X  int i;
  1893. X  Af_user *locker;
  1894. X  int errs = 0;
  1895. X  char version[1024];
  1896. X  char *p;
  1897. X  FILE *pip;
  1898. X
  1899. X  if (af_sortset (set, AF_ATTHUMAN) == -1)
  1900. X    vctl_abort ("do_promote: af_sortset()");
  1901. X  for (i = 0; i < set->af_nkeys; i++) {
  1902. X    mkvstring (version, &set->af_klist[i]);
  1903. X    if (setjmp (ThisTransaction.tr_env)) continue;
  1904. X    /* if (locking == AF_GLOBALLOCK) { /* to be implemented */
  1905. X    if (p=rindex(version, '[')) *p = '\0';
  1906. X    if (!locked(locker = af_testlock (&set->af_klist[i], AF_GLOBALLOCK))) {
  1907. X      (void)sprintf (buf, "%s unlocked.", version);
  1908. X      logmsg (buf);
  1909. X      continue;
  1910. X    }
  1911. X    if (lockeruid (locker) == geteuid()) {
  1912. X      (void)vc_unlock_g(&set->af_klist[i]);
  1913. X      (void)sprintf (buf, "%s unlocked.", version);
  1914. X      logmsg (buf);
  1915. X      continue;
  1916. X    }
  1917. X    else { /* locked by somebody else */
  1918. X      /* The following is an evil hack. BSD doesn't allow chmod(2)
  1919. X       * for ordinary user processes. 
  1920. X       */
  1921. X      if (af_MY_rouid (&set->af_klist[i]) == geteuid()) { 
  1922. X    /* we've got the power ... */
  1923. X    (void)sprintf (buf, "%s currently locked by %s. Break the lock ?", version,
  1924. X         lockerid (locker));
  1925. X    if (ask_confirm (buf, "yes")) {
  1926. X      if (vc_unlock_g(&set->af_klist[i]) == NULL) {
  1927. X        af_perror ("af_unlock");
  1928. X        continue;
  1929. X      }
  1930. X      (void)sprintf (buf, MAIL, version, uidname(geteuid()));
  1931. X      (void)strcat (buf, lockerid (locker));
  1932. X      if ((pip = popen (buf, "w")) == NULL) {
  1933. X        logmsg ("WARNING: couldn't notify lockholder...");
  1934. X      }
  1935. X      else {
  1936. X        fprintf (pip, "This message was issued automatically by ");
  1937. X        fprintf (pip, "the version control system.\n");
  1938. X        fprintf (pip, "Your lock on %s was broken by %s.\n",
  1939. X             version, uidname(geteuid()));
  1940. X        (void)pclose (pip);
  1941. X      }
  1942. X      (void)sprintf (buf, "%s unlocked.", version);
  1943. X      logmsg (buf);
  1944. X      continue;
  1945. X    }
  1946. X    else { /* we don't wanna break the lock */
  1947. X      (void)sprintf (buf, "%s remains locked by %s.", version, 
  1948. X           lockerid (locker));
  1949. X      logmsg (buf);
  1950. X      continue;
  1951. X    }
  1952. X      }
  1953. X      else { /* we cannot unlock the required version */
  1954. X    (void)sprintf (buf, "%s is locked by %s.", version, lockerid (locker));
  1955. X    logmsg (buf);
  1956. X    errs++;
  1957. X    continue;
  1958. X      }
  1959. X    }
  1960. X  }
  1961. X  if (errs)
  1962. X    return 1;
  1963. X  else
  1964. X    return 0;
  1965. X}
  1966. X
  1967. X/**/
  1968. XDoUnreserve (ac, av)
  1969. X     int ac;
  1970. X     char **av;
  1971. X{
  1972. X  Af_set set;
  1973. X  int errs;
  1974. X  char **erroneous;
  1975. X
  1976. X  errs = GetKeysByGenRev (ac,av, AF_BUSYVERS, AF_BUSYVERS, &set, 
  1977. X              &(erroneous));
  1978. X
  1979. X  if (errs)
  1980. X    print_erroneous (erroneous, errs);
  1981. X
  1982. X  if (!set.af_nkeys) {
  1983. X    logmsg ("Nothing appropriate found.");
  1984. X    return 1;
  1985. X  }
  1986. X
  1987. X  if (errs && !ask_confirm ("Continue ?", "yes"))
  1988. X    return 1;
  1989. X
  1990. X  return do_unreserve (&set);
  1991. X}
  1992. X
  1993. XDoChmod (vlist, ac, av)
  1994. X     struct vc_vlist *vlist;
  1995. X     int ac;
  1996. X     char **av;
  1997. X{
  1998. X  Af_set set;
  1999. X  int errs;
  2000. X  char **erroneous;
  2001. X
  2002. X  if (IsOptionSet(Vopt_version)) {
  2003. X    errs = GetKeysByGenRev
  2004. X    (ac,av, gen(def_vnum), rev(def_vnum), &set, &erroneous);
  2005. X  }
  2006. X  else {
  2007. X    if (!(vlist->from_version_set) || !(vlist->to_version_set))
  2008. X      errs = GetKeysByGenRev 
  2009. X    (ac,av, AF_BUSYVERS, AF_BUSYVERS, &set, &erroneous);
  2010. X    else
  2011. X      errs = GetKeysByName ( ac, av, vlist, &set, &erroneous);
  2012. X  }
  2013. X  if (errs)
  2014. X    print_erroneous (erroneous, errs);
  2015. X
  2016. X  if (!set.af_nkeys) {
  2017. X    logmsg ("Nothing appropriate found.");
  2018. X    return 1;
  2019. X  }
  2020. X
  2021. X  if (errs && !ask_confirm ("Continue ?", "yes"))
  2022. X    return 1;
  2023. X
  2024. X  return do_chmod (&set);
  2025. X}
  2026. X
  2027. XDoChown (ac, av)
  2028. X     int ac;
  2029. X     char **av;
  2030. X{
  2031. X  Af_set set;
  2032. X  int errs;
  2033. X  char **erroneous;
  2034. X
  2035. X  errs = GetKeysByGenRev (ac,av, AF_BUSYVERS, AF_BUSYVERS, &set, 
  2036. X              &erroneous);
  2037. X
  2038. X  if (errs)
  2039. X    print_erroneous (erroneous, errs);
  2040. X
  2041. X  if (!set.af_nkeys) {
  2042. X    logmsg ("Nothing appropriate found.");
  2043. X    return 1;
  2044. X  }
  2045. X
  2046. X  if (errs && !ask_confirm ("Continue ?", "yes"))
  2047. X    return 1;
  2048. X
  2049. X  return do_chown (&set);
  2050. X}
  2051. X
  2052. XDoChaut (vlist, ac, av)
  2053. X     struct vc_vlist *vlist;
  2054. X     int ac;
  2055. X     char **av;
  2056. X{
  2057. X  Af_set set;
  2058. X  int errs;
  2059. X  char **erroneous;
  2060. X
  2061. X  if (IsOptionSet(Vopt_version)) {
  2062. X    errs = GetKeysByGenRev
  2063. X    (ac,av, gen(def_vnum), rev(def_vnum), &set, &erroneous);
  2064. X  }
  2065. X  else {
  2066. X    if (!(vlist->from_version_set) || !(vlist->to_version_set))
  2067. X      errs = GetKeysByGenRev 
  2068. X    (ac,av, AF_LASTVERS, AF_LASTVERS, &set, &erroneous);
  2069. X    else
  2070. X      errs = GetKeysByName ( ac, av, vlist, &set, &erroneous);
  2071. X  }
  2072. X  if (errs)
  2073. X    print_erroneous (erroneous, errs);
  2074. X
  2075. X  if (!set.af_nkeys) {
  2076. X    logmsg ("Nothing appropriate found.");
  2077. X    return 1;
  2078. X  }
  2079. X
  2080. X  if (errs && !ask_confirm ("Continue ?", "yes"))
  2081. X    return 1;
  2082. X
  2083. X  return do_chaut (&set);
  2084. X}
  2085. X
  2086. Xchar *mkfn (key) Af_key *key; {
  2087. X  /* construct a unix (busy-)filename for object pointed to by key */
  2088. X  static char name[128];
  2089. X  char *n, *t;
  2090. X
  2091. X  name[0] = '\0';
  2092. X  t = af_rtype (key); t = *t ? t : NULL;
  2093. X  (void)sprintf (name, "%s%s%s", n=af_rname (key), t ? "." : "", t ? t : "");
  2094. X  free (n); free (t);
  2095. X  return name;
  2096. X}
  2097. X
  2098. Xchar *uidname (uid) Uid_t uid; {
  2099. X  struct passwd *pwent = getpwuid ((int)uid);
  2100. X  char un[80];
  2101. X
  2102. X  if (pwent == NULL) {
  2103. X    (void)sprintf (un, "somebody (uid=%d)", uid);
  2104. X    return un;
  2105. X  }
  2106. X  else return pwent->pw_name;
  2107. X}
  2108. X
  2109. END_OF_FILE
  2110. if test 12489 -ne `wc -c <'src/vc/vadm_reserve.c'`; then
  2111.     echo shar: \"'src/vc/vadm_reserve.c'\" unpacked with wrong size!
  2112. fi
  2113. # end of 'src/vc/vadm_reserve.c'
  2114. fi
  2115. echo shar: End of archive 14 \(of 33\).
  2116. cp /dev/null ark14isdone
  2117. MISSING=""
  2118. 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
  2119.     if test ! -f ark${I}isdone ; then
  2120.     MISSING="${MISSING} ${I}"
  2121.     fi
  2122. done
  2123. if test "${MISSING}" = "" ; then
  2124.     echo You have unpacked all 33 archives.
  2125.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2126. else
  2127.     echo You still need to unpack the following archives:
  2128.     echo "        " ${MISSING}
  2129. fi
  2130. ##  End of shell archive.
  2131. exit 0
  2132.