home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume19 / shape / part26 < prev    next >
Encoding:
Internet Message Format  |  1989-05-31  |  32.3 KB

  1. Subject:  v19i039:  A software configuration management system, Part26/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 39
  8. Archive-name: shape/part26
  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 26 (of 33)."
  19. # Contents:  src/afs/afsrepair.c
  20. # Wrapped by rsalz@papaya.bbn.com on Thu Jun  1 19:27:17 1989
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'src/afs/afsrepair.c' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'src/afs/afsrepair.c'\"
  24. else
  25. echo shar: Extracting \"'src/afs/afsrepair.c'\" \(30386 characters\)
  26. sed "s/^X//" >'src/afs/afsrepair.c' <<'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 *
  55. X * AFS-test -- try to repair corrupted archive
  56. X *
  57. X * $Header: afsrepair.c[1.4] Wed Feb 22 16:28:01 1989 andy@coma published $
  58. X */
  59. X
  60. X#include <stdio.h>
  61. X#include <string.h>
  62. X#ifdef SUNOS_4_0
  63. X#include <strings.h>
  64. X#endif
  65. X#include <setjmp.h>
  66. X#include <signal.h>
  67. X#include <sys/types.h>
  68. X#include <sys/stat.h>
  69. X
  70. X#include "typeconv.h"
  71. X#include "afs.h"
  72. X#include "afarchive.h"
  73. X#include "afsrepair.h"
  74. X
  75. Xint        givenVLevel = NORMAL;
  76. XInput      attrIn, dataIn;
  77. XConstAttrs cAttrs;
  78. XRevision   revList[MAXREVS];
  79. XUdas       udaList[MAXREVS];
  80. XNote       noteList[MAXREVS];
  81. XData       dataList[MAXREVS];
  82. Xint        curRev, curUda, curNote, curData;
  83. X
  84. Xchar *malloc(), *verifyString(), *complainString();
  85. Xextern char *optarg;
  86. Xextern int optind;
  87. X
  88. Xjmp_buf env;
  89. X
  90. Xmain (argc, argv)
  91. X     int  argc;
  92. X     char **argv;
  93. X{
  94. X  int   cleanup(), getopt();
  95. X  short c, i, nfiles;
  96. X  
  97. X  if (argc < 2)
  98. X    { usage (); exit (-1); }
  99. X  
  100. X  while ((c = getopt (argc, argv, "l:v")) != EOF)
  101. X    {
  102. X      switch (c)
  103. X    {
  104. X    case 'l': /* level */
  105. X      givenVLevel = atoi (optarg);
  106. X      if ((givenVLevel < 0) || (givenVLevel > 3))
  107. X        {
  108. X          fprintf (stderr, "illegal level of verbosity (%s)\n",
  109. X               "must be 0, 1, 2 or 3");
  110. X          exit (-1);
  111. X        }
  112. X      break;
  113. X    case 'v': /* print current version of this program */
  114. X      printf ("This is %s version %s.\n", argv[0], af_version());
  115. X      exit (0);
  116. X    default:
  117. X      usage ();
  118. X      exit (-1);
  119. X    }
  120. X    }  /* end of command line parsing */
  121. X  
  122. X  (void) signal (SIGINT, cleanup);
  123. X  
  124. X  nfiles = argc - optind;
  125. X  for (i = 0; i < nfiles; i++)
  126. X    {
  127. X      if (setjmp (env) == 0)
  128. X    (void) repair (argv[i+optind]);
  129. X    }
  130. X} /* end of main */
  131. X
  132. Xusage ()
  133. X{
  134. X  fprintf (stderr, "Usage: afsrepair [-l level] [-v] files\n");
  135. X}
  136. X
  137. Xchar lckFilename[4*MAXNAMLEN];
  138. X
  139. Xcleanup ()
  140. X{
  141. X  fprintf (stderr, "abort processing of this file\n");
  142. X  (void) af_unlink (lckFilename);
  143. X  longjmp (env, 1);
  144. X}
  145. X
  146. Xrepair (filename)
  147. X     char *filename;
  148. X{
  149. X  char *fullname = af_uniqpath (filename), *sPtr, commandLine[1024];
  150. X  char *arFilename, datFilename[4*MAXNAMLEN];
  151. X  char arTmpFilename[4*MAXNAMLEN], datTmpFilename[4*MAXNAMLEN];
  152. X  int  size, i, j;
  153. X  Af_user *owner, *af_garown();
  154. X  bool error, writeOk, confirm, busyEx = FALSE;
  155. X  FILE *inFile, *tmpFile, *lckFile;
  156. X  struct stat ibuf;
  157. X
  158. X  if (!strcmp (filename, "binary_pool"))
  159. X    {
  160. X      fprintf (stdout, "cannot repair binary pools yet -- \nthe only way ");
  161. X      fprintf (stdout, "to fix a binary pool is to clear it ! (y/n) ? ");
  162. X      if (askConfirm ("y"))
  163. X    {
  164. X      fprintf (stdout, "clearing binary pool...\n", filename);
  165. X      (void) sprintf (commandLine, "rm -f AFS/%s*\0", AF_BPFILEID);
  166. X      (void) system (commandLine);
  167. X    }
  168. X      exit (0);
  169. X    }
  170. X
  171. X  cAttrs.host = af_gethostname ();
  172. X  cAttrs.syspath = af_afpath (fullname);
  173. X  cAttrs.name = af_afname (fullname);
  174. X  cAttrs.type = af_aftype (fullname);
  175. X  
  176. X  fprintf (stdout, "%s:\n", af_unixname ((char *)0, cAttrs.name, cAttrs.type));
  177. X       
  178. X  arFilename = af_garname (cAttrs.syspath, cAttrs.name, cAttrs.type);
  179. X       
  180. X  if ((owner = af_garown (arFilename, &writeOk)) == (Af_user *)0)
  181. X    {
  182. X      fprintf (stdout, "cannot determine owner of AFS subdirectory !!\n");
  183. X      owner = af_getuser (getuid());
  184. X    }
  185. X  cAttrs.ownerName = af_entersym (owner->af_username);
  186. X  cAttrs.ownerHost = af_enterhost (owner->af_userhost);
  187. X
  188. X  /* look for Lockfile */
  189. X  (void) strcpy (lckFilename, arFilename);
  190. X  lckFilename [strlen (lckFilename) - sizeof (char)] = AF_LCKEXT;
  191. X  if (stat (lckFilename, &ibuf) != ERROR) /* lock file present */
  192. X    {
  193. X      fprintf (stdout, "Archive file is locked!\n");
  194. X      fprintf (stdout, "   There might be a spurious lockfile,\n");
  195. X      fprintf (stdout, "   or another application is currently modifying the archive file.\n");
  196. X      fprintf (stdout, "   Ignore the lock (y/n) ? ");
  197. X      if (!askConfirm ("y"))
  198. X    exit (0);
  199. X      else /* create lockfile */
  200. X    {
  201. X      lckFile = fopen (lckFilename, "w");
  202. X      (void) fclose (lckFile);
  203. X    }
  204. X    }
  205. X
  206. X  /* read the two archive files (if present) */
  207. X  if (inFile = fopen (arFilename, "r"))
  208. X    {
  209. X      attrIn.length = af_retfsize (arFilename);
  210. X      if ((attrIn.string = malloc ((unsigned) attrIn.length)) == (char *)0)
  211. X    {
  212. X      fprintf (stdout, "repair (malloc): not enough memory\n");
  213. X      cleanup ();
  214. X    }
  215. X      (void) fread (attrIn.string, sizeof (char), (Size_t) attrIn.length, inFile);
  216. X      (void) fclose (inFile);
  217. X      attrIn.curPos = 0;
  218. X    }
  219. X       
  220. X  (void) strcpy (datFilename, arFilename);
  221. X  datFilename[strlen(datFilename)-sizeof(char)] = AF_DATAEXT;
  222. X  if (inFile = fopen (datFilename, "r"))
  223. X    {
  224. X      dataIn.length = af_retfsize (datFilename);
  225. X      if ((dataIn.string = malloc ((unsigned) dataIn.length)) == (char *)0)
  226. X    {
  227. X      fprintf (stdout, "repair (malloc): not enough memory\n");
  228. X      cleanup ();
  229. X    }
  230. X      (void) fread (dataIn.string, sizeof (char), (Size_t) dataIn.length, inFile);
  231. X      (void) fclose (inFile);
  232. X    }
  233. X  else
  234. X    {
  235. X      if (attrIn.string == (char *)0)
  236. X    {
  237. X      fprintf (stdout, "repair: no archive files for %s\n",
  238. X           af_unixname ((char *)0, cAttrs.name, cAttrs.type));
  239. X      cleanup ();
  240. X    }
  241. X    }
  242. X
  243. X  /* test existence of busy file */
  244. X  if (access (fullname, 0) == 0)
  245. X    busyEx = TRUE;
  246. X
  247. X  /*=========
  248. X   * Phase 1
  249. X   *=========*/
  250. X  fprintf (stdout, "*** Phase 1 (check version independent attributes) ***\n");
  251. X
  252. X  (void) lookup (&attrIn, AF_NAMEID, 0);
  253. X
  254. X  (void) nextItem (&attrIn); /* host */
  255. X  sPtr = verifyString ("hostname", attrIn, VERBOSE);
  256. X  if (strcmp (sPtr, cAttrs.host))
  257. X    sPtr = complainString ("hostname", sPtr, cAttrs.host, NORMAL);
  258. X  cAttrs.host = af_entersym (sPtr);
  259. X    
  260. X  (void) nextItem (&attrIn); /* syspath */
  261. X  sPtr = verifyString ("syspath", attrIn, VERBOSE);
  262. X  if (strcmp (sPtr, cAttrs.syspath))
  263. X    sPtr = complainString ("syspath", sPtr, cAttrs.syspath, NORMAL);
  264. X  cAttrs.syspath = af_entersym (sPtr);
  265. X    
  266. X  (void) nextItem (&attrIn); /* name */
  267. X  sPtr = verifyString ("name", attrIn, VERBOSE);
  268. X  if (strcmp (sPtr, cAttrs.name))
  269. X    sPtr = complainString ("name", sPtr, cAttrs.name, NORMAL);
  270. X  cAttrs.name = af_entersym (sPtr);
  271. X    
  272. X  (void) nextItem (&attrIn); /* type */
  273. X  sPtr = verifyString ("type", attrIn, VERBOSE);
  274. X  if (strcmp (sPtr, cAttrs.type))
  275. X    sPtr = complainString ("type", sPtr, cAttrs.type, NORMAL);
  276. X  cAttrs.type = af_entersym (sPtr);
  277. X
  278. X  (void) lookup (&attrIn, AF_OWNID, 0);
  279. X
  280. X  (void) nextItem (&attrIn); /* owner's name */
  281. X  sPtr = verifyString ("owner's name", attrIn, VERBOSE);
  282. X  if (strcmp (sPtr, cAttrs.ownerName))
  283. X    sPtr = complainString ("owner's name", sPtr, cAttrs.ownerName, NORMAL);
  284. X  cAttrs.ownerName = af_entersym (sPtr);
  285. X
  286. X  (void) nextItem (&attrIn); /* owner's host */
  287. X  sPtr = verifyString ("owner's host", attrIn, VERBOSE);
  288. X  if (strcmp (sPtr, cAttrs.ownerHost))
  289. X    sPtr = complainString ("owner's host", sPtr, cAttrs.ownerHost, NORMAL);
  290. X  cAttrs.ownerHost = af_entersym (sPtr);
  291. X
  292. X  /*=========
  293. X   * Phase 2
  294. X   *=========*/
  295. X  fprintf (stdout, "*** Phase 2 (check version attributes) ***\n");
  296. X
  297. X  /* initialize busy version --- not *all* attributes get initialized !!! */
  298. X  revList[0].generation = AF_BUSYVERS;
  299. X  revList[0].revision = AF_BUSYVERS;
  300. X  (void) lookup (&attrIn, AF_NAMEID, 0);
  301. X  (void) nextItem (&attrIn); (void) nextItem (&attrIn);
  302. X  (void) nextItem (&attrIn); (void) nextItem (&attrIn);
  303. X  (void) nextItem (&attrIn);
  304. X  sPtr = verifyString ("variant", attrIn, VERBOSE);
  305. X  revList[0].variant = af_entersym (sPtr);
  306. X
  307. X  (void) lookup (&attrIn, AF_LOCKID, 0);
  308. X  (void) nextItem (&attrIn);
  309. X  sPtr = verifyString ("locker's name", attrIn, VERBOSE);
  310. X  revList[0].lockerName = af_entersym (sPtr);
  311. X  (void) nextItem (&attrIn);
  312. X  sPtr = verifyString ("locker's host", attrIn, VERBOSE);
  313. X  revList[0].lockerHost = af_entersym (sPtr);
  314. X
  315. X  if ((revList[0].lockerName == (char *)0) && revList[0].lockerHost)
  316. X    {
  317. X      fprintf (stdout, "Warning: lockerID inconsistent -- lock cancelled\n");
  318. X      revList[0].lockerName = (char *)0;
  319. X      revList[0].lockerHost = (char *)0;
  320. X    }
  321. X  if (revList[0].lockerName && (revList[0].lockerHost == (char *)0))
  322. X    {
  323. X      fprintf (stdout,"locker's host missing - inserting author's host\n");
  324. X      revList[0].lockerHost = revList[0].authorHost;
  325. X    }
  326. X
  327. X  (void) nextItem (&attrIn);
  328. X  revList[0].lockTime = verifyDate ("locking date", attrIn, EVERYTHING);
  329. X  if (revList[0].lockerName && (revList[0].lockTime == AF_NOTIME))
  330. X    {
  331. X      fprintf (stdout, "Warning: locking date inconsistent -- %s\n",
  332. X           "setting actual date");
  333. X      revList[0].lockTime = (time_t) af_acttime();
  334. X    }
  335. X
  336. X  (void) lookup (&attrIn, AF_PRDID, 0);
  337. X  (void) nextItem (&attrIn);
  338. X  revList[0].predGen =
  339. X    verifyInt ("pred(gen) of busy version", attrIn, EVERYTHING);
  340. X  (void) nextItem (&attrIn);
  341. X  revList[0].predRev =
  342. X    verifyInt ("pred(rev) of busy version", attrIn, EVERYTHING);
  343. X
  344. X  attrIn.curPos = 0;
  345. X  curRev = 0;
  346. X  while (lookup (&attrIn, AF_REVID, 1) != -1)
  347. X    {
  348. X      curRev++;
  349. X      (void) nextItem (&attrIn);
  350. X      revList[curRev].generation = verifyInt ("gen", attrIn, EVERYTHING);
  351. X      (void) nextItem (&attrIn);
  352. X      revList[curRev].revision = verifyInt ("rev", attrIn, EVERYTHING);
  353. X      (void) nextItem (&attrIn);
  354. X      revList[curRev].state = verifyInt ("state", attrIn, EVERYTHING);
  355. X      (void) nextItem (&attrIn);
  356. X      revList[curRev].mode = (u_short) verifyOct ("mode", attrIn, EVERYTHING);
  357. X      (void) nextItem (&attrIn);
  358. X      sPtr = verifyString ("variant", attrIn, VERBOSE);
  359. X      revList[curRev].variant = af_entersym (sPtr);
  360. X      
  361. X      (void) lookup (&attrIn, AF_AUTHORID, 1);
  362. X      (void) nextItem (&attrIn); /* author's name */
  363. X      sPtr = verifyString ("author's name", attrIn, VERBOSE);
  364. X      if (sPtr == (char *)0)
  365. X    {
  366. X      fprintf (stdout,"author's name missing -- inserting owner's name\n");
  367. X      revList[curRev].authorName = cAttrs.ownerName;
  368. X    }
  369. X      else
  370. X    revList[curRev].authorName = af_entersym (sPtr);
  371. X      
  372. X      (void) nextItem (&attrIn); /* authort's host */
  373. X      sPtr = verifyString ("author's host", attrIn, VERBOSE);
  374. X      if (sPtr == (char *)0)
  375. X    {
  376. X      fprintf (stdout,"author's host missing -- inserting owner's host\n");
  377. X      revList[curRev].authorHost = cAttrs.ownerHost;
  378. X    }
  379. X      else
  380. X    revList[curRev].authorHost = af_entersym (sPtr);
  381. X
  382. X      (void) nextItem (&attrIn); /* locker's name */
  383. X      sPtr = verifyString ("locker's name", attrIn, VERBOSE);
  384. X      revList[curRev].lockerName = af_entersym (sPtr);
  385. X
  386. X      (void) nextItem (&attrIn); /* locker's host */
  387. X      sPtr = verifyString ("locker's host", attrIn, VERBOSE);
  388. X      if ((sPtr == (char *)0) && (revList[curRev].lockerName != (char *)0))
  389. X    {
  390. X      fprintf (stdout,"locker's host missing - inserting author's host\n");
  391. X      revList[curRev].lockerHost = revList[curRev].authorHost;
  392. X    }
  393. X      else
  394. X    revList[curRev].lockerHost = af_entersym (sPtr);
  395. X
  396. X      (void) lookup (&attrIn, AF_DATEID, 1);
  397. X      (void) nextItem (&attrIn);
  398. X      revList[curRev].modTime = verifyDate ("mod. date", attrIn, EVERYTHING);
  399. X      if (revList[curRev].modTime == AF_NOTIME)
  400. X    {
  401. X      fprintf (stdout, "Warning: modification date missing -- %s\n",
  402. X           "inserting actual date");
  403. X      revList[curRev].modTime = (time_t) af_acttime();
  404. X    }
  405. X      (void) nextItem (&attrIn);
  406. X      revList[curRev].accessTime = verifyDate ("acc. date", attrIn,EVERYTHING);
  407. X      if (revList[curRev].accessTime == AF_NOTIME)
  408. X    {
  409. X      fprintf (stdout, "Warning: access date missing -- %s\n",
  410. X           "inserting actual date");
  411. X      revList[curRev].accessTime = (time_t) af_acttime();
  412. X    }
  413. X      (void) nextItem (&attrIn);
  414. X      revList[curRev].statChangeTime =
  415. X    verifyDate ("status change date", attrIn, EVERYTHING);
  416. X      if (revList[curRev].statChangeTime == AF_NOTIME)
  417. X    {
  418. X      fprintf (stdout, "Warning: status change date missing -- %s\n",
  419. X           "inserting actual date");
  420. X      revList[curRev].statChangeTime = (time_t) af_acttime();
  421. X    }
  422. X      (void) nextItem (&attrIn);
  423. X      revList[curRev].saveTime = verifyDate ("save date", attrIn, EVERYTHING);
  424. X      if (revList[curRev].saveTime == AF_NOTIME)
  425. X    {
  426. X      fprintf (stdout, "Warning: save date missing -- %s\n",
  427. X           "inserting actual date");
  428. X      revList[curRev].saveTime = (time_t) af_acttime();
  429. X    }
  430. X      (void) nextItem (&attrIn);
  431. X      revList[curRev].lockTime = verifyDate ("lock date", attrIn, EVERYTHING);
  432. X      if ((revList[curRev].lockTime == AF_NOTIME) &&
  433. X      (revList[curRev].lockerName != (char *)0))
  434. X    {
  435. X      fprintf (stdout, "Warning: locking date missing -- %s\n",
  436. X           "inserting actual date");
  437. X      revList[curRev].lockTime = (time_t) af_acttime();
  438. X    }
  439. X
  440. X      (void) lookup (&attrIn, AF_REPRID, 1);
  441. X      (void) nextItem (&attrIn);
  442. X      revList[curRev].representation = verifyInt ("repr", attrIn, EVERYTHING);
  443. X      (void) nextItem (&attrIn);
  444. X      revList[curRev].fileSize = verifyInt ("filesize", attrIn, EVERYTHING);
  445. X      (void) nextItem (&attrIn);
  446. X      revList[curRev].deltaSize = verifyInt ("deltasize", attrIn, EVERYTHING);
  447. X      (void) nextItem (&attrIn);
  448. X      revList[curRev].succGen = verifyInt ("succ. gen", attrIn, EVERYTHING);
  449. X      (void) nextItem (&attrIn);
  450. X      revList[curRev].succRev = verifyInt ("succ. rev", attrIn, EVERYTHING);
  451. X      (void) nextItem (&attrIn);
  452. X      revList[curRev].predGen = verifyInt ("pred. gen", attrIn, EVERYTHING);
  453. X      (void) nextItem (&attrIn);
  454. X      revList[curRev].predRev = verifyInt ("pred. rev", attrIn, EVERYTHING);
  455. X    } /* revision loop */
  456. X
  457. X  /*=========
  458. X   * Phase 3
  459. X   *=========*/
  460. X  fprintf (stdout, "*** Phase 3 (check user defined attributes) ***\n");
  461. X
  462. X  attrIn.curPos = 0;
  463. X  curUda = 0;
  464. X  while (lookup (&attrIn, AF_UDAID, 1) != -1)
  465. X    {
  466. X      (void) nextItem (&attrIn);
  467. X      udaList[curUda].generation = verifyInt ("gen", attrIn, EVERYTHING);
  468. X      (void) nextItem (&attrIn);
  469. X      udaList[curUda].revision = verifyInt ("rev", attrIn, EVERYTHING);
  470. X      (void) nextItem (&attrIn);
  471. X      i = 0;
  472. X      size = 0;
  473. X      while (i < MAXUDAS)
  474. X    {
  475. X      udaList[curUda].uda[i] = &attrIn.string[attrIn.curPos];
  476. X      udaList[curUda].size = udaList[curUda].size + 
  477. X        (strlen (udaList[curUda].uda[i]) + sizeof (char));
  478. X      while (attrIn.string[attrIn.curPos] != '\0')
  479. X        attrIn.curPos++;
  480. X      attrIn.curPos++;
  481. X      i++;
  482. X      if (!strcmp (&attrIn.string[attrIn.curPos], AF_UDAID))
  483. X        break;
  484. X      if (attrIn.string[attrIn.curPos] == '\0')
  485. X        {
  486. X          udaList[curUda].size++;
  487. X          break;
  488. X        }
  489. X    } /* uda loop */
  490. X      udaList[curUda].uda[i] = (char *)0;
  491. X      curUda++;
  492. X    } /* revision loop */
  493. X
  494. X  /*=========
  495. X   * Phase 4
  496. X   *=========*/
  497. X  fprintf (stdout, "*** Phase 4 (check notes) ***\n");
  498. X
  499. X  dataIn.curPos = 0;
  500. X  curNote = 0;
  501. X  while (lookup (&dataIn, AF_NOTEID, 1) != -1)
  502. X    {
  503. X      (void) nextItem (&dataIn);
  504. X      noteList[curNote].generation = verifyInt ("gen", dataIn, EVERYTHING);
  505. X      (void) nextItem (&dataIn);
  506. X      noteList[curNote].revision = verifyInt ("rev", dataIn, EVERYTHING);
  507. X      (void) nextItem (&dataIn);
  508. X      (void) nextLine (&dataIn); /* skip size */
  509. X      size = 0;
  510. X      noteList[curNote].contents = &dataIn.string[dataIn.curPos];
  511. X      while (((noteList[curNote].contents)[size] != AF_DATAID[0]) &&
  512. X         ((noteList[curNote].contents)[size] != '\0'))
  513. X    size++;
  514. X      if (size == 0)
  515. X    {
  516. X      noteList[curNote].contents = (char *)0;
  517. X      size = 1;
  518. X    }
  519. X      else
  520. X    (noteList[curNote].contents)[size-1] = '\0';
  521. X      noteList[curNote].size = size;
  522. X      curNote++;
  523. X    } /* revision loop */
  524. X
  525. X  /*=========
  526. X   * Phase 5
  527. X   *=========*/
  528. X  fprintf (stdout, "*** Phase 5 (check data) ***\n");
  529. X
  530. X  dataIn.curPos = 0;
  531. X  curData = 0;
  532. X  while (lookup (&dataIn, AF_DATAID, 1) != -1)
  533. X    {
  534. X      (void) nextItem (&dataIn);
  535. X      dataList[curData].generation = verifyInt ("gen", dataIn, EVERYTHING);
  536. X      (void) nextItem (&dataIn);
  537. X      dataList[curData].revision = verifyInt ("rev", dataIn, EVERYTHING);
  538. X      (void) nextItem (&dataIn);
  539. X      dataList[curData].representation = verifyInt ("repr",dataIn, EVERYTHING);
  540. X      (void) nextItem (&dataIn);
  541. X      (void) nextLine (&dataIn); /* skip size */
  542. X      size = 0;
  543. X      dataList[curData].contents = &dataIn.string[dataIn.curPos];
  544. X      while (itemCmp (&(dataList[curData].contents)[size],
  545. X              AF_NOTEID, AF_IDSTRLEN) &&
  546. X         itemCmp (&(dataList[curData].contents)[size],
  547. X              AF_DATAID, AF_IDSTRLEN))
  548. X    {
  549. X      size++;
  550. X      while ((dataList[curData].contents)[size] != AF_NOTEID[0])
  551. X        {
  552. X          size++;
  553. X          if ((dataIn.curPos + size) == dataIn.length)
  554. X        goto loopexit;
  555. X        }
  556. X    }
  557. X    loopexit:
  558. X      if (size == 0)
  559. X    dataList[curData].contents = (char *)0;
  560. X      dataList[curData].size = size;
  561. X      curData++;
  562. X    } /* revision loop */
  563. X
  564. X  /*=========
  565. X   * Phase 6
  566. X   *=========*/
  567. X  fprintf (stdout, "*** Phase 6 (check connectivity) ***\n");
  568. X
  569. X  /* test order of revisions -- not yet implemented */
  570. X  /* test existence on successors and predecessors -- not yet implemented */
  571. X
  572. X  /* calculate number of revisions and size of data */
  573. X  cAttrs.noOfRevisions = curRev;
  574. X
  575. X  cAttrs.datasize = 0;
  576. X  for (i=0; i<curRev; i++)
  577. X    cAttrs.datasize = cAttrs.datasize + noteList[i].size;
  578. X  for (i=0; i<curRev; i++)
  579. X    cAttrs.datasize = cAttrs.datasize + dataList[i].size;
  580. X
  581. X  /* test integrity of attr and data file */
  582. X  error = FALSE;
  583. X  for (i=0; i<=cAttrs.noOfRevisions; i++)
  584. X    {
  585. X      if ((udaList[i].generation != revList[i].generation) ||
  586. X      (udaList[i].revision != revList[i].revision))
  587. X    {
  588. X      error = TRUE;
  589. X      udaList[i].generation = revList[i].generation;
  590. X      udaList[i].revision = revList[i].revision;
  591. X    }
  592. X    }
  593. X    
  594. X  for (i=0; i<cAttrs.noOfRevisions; i++)
  595. X    {
  596. X      if ((noteList[i].generation != revList[i+1].generation) ||
  597. X      (noteList[i].revision != revList[i+1].revision))
  598. X    {
  599. X      error = TRUE;
  600. X      noteList[i].generation = revList[i+1].generation;
  601. X      noteList[i].revision = revList[i+1].revision;
  602. X    }
  603. X      if ((dataList[i].generation != revList[i+1].generation) ||
  604. X      (dataList[i].revision != revList[i+1].revision))
  605. X    {
  606. X      error = TRUE;
  607. X      dataList[i].generation = revList[i+1].generation;
  608. X      dataList[i].revision = revList[i+1].revision;
  609. X    }
  610. X    }
  611. X  if (error)
  612. X    fprintf (stderr, "version numbering inconsistent -- fixed !\n");
  613. X
  614. X
  615. X
  616. X  /*==============================
  617. X   * Write temporary archive files
  618. X   *==============================*/
  619. X
  620. X  /* if all revisions have been removed */
  621. X  if (!busyEx && (cAttrs.noOfRevisions == 0))
  622. X    {
  623. X      fprintf (stdout, "no revisions found\n");
  624. X      cleanup ();
  625. X    }
  626. X
  627. X  /* open tmpfile */
  628. X  (void) strcpy (arTmpFilename, arFilename);
  629. X  arTmpFilename[strlen(arTmpFilename)-sizeof(char)] = AF_ARCHTMP;
  630. X  if ((tmpFile = fopen (arTmpFilename, "w")) == (FILE *)0)
  631. X    {
  632. X      fprintf (stderr, "cannot open tmp file\n");
  633. X      cleanup ();
  634. X    }
  635. X
  636. X  /* write header */
  637. X  fprintf (tmpFile, "%s %d %d %ld\n", AF_ARHEADER, AF_ARCURVERS,
  638. X       cAttrs.noOfRevisions + 1, cAttrs.datasize);
  639. X
  640. X  /* write constant attributes */
  641. X  if (busyEx)
  642. X    {
  643. X      fprintf (tmpFile, "%s %s %s %s %s %s\n", AF_NAMEID, 
  644. X           cAttrs.host, cAttrs.syspath, cAttrs.name, NOTMT (cAttrs.type),
  645. X           NOTMT (revList[0].variant));
  646. X    }
  647. X  else
  648. X    {
  649. X      fprintf (tmpFile, "%s %s %s %s %s %s\n", AF_NAMEID, cAttrs.host,
  650. X           cAttrs.syspath, cAttrs.name, NOTMT (cAttrs.type), AF_NOSTRING);
  651. X    }
  652. X
  653. X  /* write owner */
  654. X  fprintf (tmpFile,
  655. X       "%s %s %s\n", AF_OWNID, cAttrs.ownerName, cAttrs.ownerHost);
  656. X
  657. X  /* write predecessor of busy version */
  658. X  if (busyEx)
  659. X    {
  660. X      fprintf (tmpFile, "%s %d %d\n", AF_PRDID,
  661. X           revList[0].predGen, revList[0].predRev);
  662. X    }
  663. X  else
  664. X    fprintf (tmpFile, "%s %d %d\n", AF_PRDID, AF_NOVNUM, AF_NOVNUM);
  665. X
  666. X  /* write locker of busy version */
  667. X  fprintf (tmpFile, "%s %s %s %d\n", AF_LOCKID,
  668. X       NOTMT (revList[0].lockerName), NOTMT (revList[0].lockerHost),
  669. X       revList[0].lockTime);
  670. X  
  671. X
  672. X  /* write list of version attributes */
  673. X  for (i=1; i <= cAttrs.noOfRevisions; i++)
  674. X    {
  675. X      /* write revision ID */
  676. X      fprintf (tmpFile, "%s %d %d %d %o %s\n", AF_REVID, 
  677. X           revList[i].generation, revList[i].revision, revList[i].state,
  678. X           revList[i].mode, NOTMT (revList[i].variant));
  679. X
  680. X      /* write author */
  681. X      fprintf (tmpFile, "\t%s %s %s %s %s\n", AF_AUTHORID,
  682. X           revList[i].authorName, revList[i].authorHost,
  683. X           NOTMT (revList[i].lockerName), NOTMT (revList[i].lockerHost));
  684. X
  685. X      /* write dates */
  686. X      fprintf (tmpFile, "\t%s %ld %ld %ld %ld %ld\n", AF_DATEID, 
  687. X           revList[i].modTime, revList[i].accessTime, 
  688. X           revList[i].statChangeTime, revList[i].saveTime,
  689. X           revList[i].lockTime);
  690. X
  691. X      /* write kind of representation and tree connects */
  692. X      fprintf (tmpFile, "\t%s %d %ld %ld %d %d %d %d\n", AF_REPRID,
  693. X           revList[i].representation, revList[i].fileSize,
  694. X           revList[i].deltaSize, revList[i].succGen, revList[i].succRev,
  695. X           revList[i].predGen, revList[i].predRev);
  696. X    }
  697. X
  698. X  /* write user defined attributes */
  699. X  fprintf (tmpFile, "%s\n", AF_UDASEG);
  700. X
  701. X  for (i=0; i <= cAttrs.noOfRevisions; i++)
  702. X    {
  703. X      fprintf (tmpFile, "%s %d %d\n", AF_UDAID, 
  704. X           udaList[i].generation, udaList[i].revision);
  705. X      j=0;
  706. X      while (udaList[i].uda[j])
  707. X    fprintf (tmpFile, "%s%c", udaList[i].uda[j++], '\0');
  708. X      if (j==0) /* if no user defined attribute has been written */
  709. X    (void) putc ('\0', tmpFile);
  710. X      (void) putc ('\0', tmpFile);
  711. X      (void) putc ('\n', tmpFile);
  712. X    }
  713. X  (void) fclose (tmpFile);
  714. X  /* release attrIn */
  715. X  (void) free (attrIn.string);
  716. X  attrIn.string = (char *)0;
  717. X  attrIn.length = 0;
  718. X  attrIn.curPos = 0;
  719. X      
  720. X
  721. X  /* open datatmpfile */
  722. X  (void) strcpy (datTmpFilename, arFilename);
  723. X  datTmpFilename[strlen(datTmpFilename)-sizeof(char)] = AF_DATATMP;
  724. X  if ((tmpFile = fopen (datTmpFilename, "w")) == (FILE *)0)
  725. X    {
  726. X      fprintf (stderr, "cannot open tmp file\n");
  727. X      cleanup ();
  728. X    }
  729. X
  730. X  fprintf (tmpFile, "%s %d\n", AF_DATAHEADER, AF_ARCURVERS);
  731. X      
  732. X  for (i=0; i < cAttrs.noOfRevisions; i++)
  733. X    {
  734. X      fprintf (tmpFile, "%s %d %d %ld\n", AF_NOTEID,
  735. X           noteList[i].generation, noteList[i].revision, noteList[i].size);
  736. X      (void) fwrite (noteList[i].contents, sizeof(char), (Size_t)(noteList[i].size - sizeof(char)), tmpFile);
  737. X      (void) putc ('\n', tmpFile);
  738. X
  739. X      fprintf (tmpFile, "%s %d %d %d %ld\n", AF_DATAID,
  740. X           dataList[i].generation, dataList[i].revision,
  741. X           dataList[i].representation, dataList[i].size);
  742. X
  743. X      (void) fwrite (dataList[i].contents, sizeof(char), (Size_t)dataList[i].size, tmpFile);
  744. X    }
  745. X  (void) fclose (tmpFile);
  746. X  /* release dataIn */
  747. X  (void) free (dataIn.string);
  748. X  dataIn.string = (char *)0;
  749. X  dataIn.length = 0;
  750. X  dataIn.curPos = 0;
  751. X      
  752. X
  753. X  /* test, if archive files are changed -- if not, exit */
  754. X  (void) sprintf (commandLine, "cmp -s %s %s\0", arFilename, arTmpFilename);
  755. X  if (system (commandLine) == 0) /* if files are identical */
  756. X    {
  757. X      (void) sprintf (commandLine, "cmp -s %s %s\0", datFilename, datTmpFilename);
  758. X      if (system (commandLine) == 0)
  759. X    {
  760. X      (void) af_unlink (arTmpFilename);
  761. X      (void) af_unlink (datTmpFilename);
  762. X      (void) af_unlink (lckFilename);
  763. X      fprintf (stdout, "*** archive files ok ! -- unchanged ***\n");
  764. X          return (AF_OK);
  765. X        }
  766. X    }
  767. X  if (NORMAL <= givenVLevel)
  768. X    {
  769. X      fprintf (stdout, "archive files for %s inconsistent - fix ? (y/n) ",
  770. X           af_unixname ((char *)0, cAttrs.name, cAttrs.type));
  771. X      confirm = askConfirm ("y");
  772. X    }
  773. X  else
  774. X    confirm = TRUE;
  775. X
  776. X  if (!confirm) 
  777. X    {
  778. X      (void) af_unlink (arTmpFilename);
  779. X      (void) af_unlink (datTmpFilename);
  780. X      (void) af_unlink (lckFilename);
  781. X      fprintf (stdout, "*** No archive files written ***\n");
  782. X      return (AF_OK);
  783. X    }
  784. X
  785. X  fprintf (stdout, "*** Write new archive files ***\n");
  786. X
  787. X  (void) af_unlink (arFilename);
  788. X  if (af_syslink (arTmpFilename, arFilename) == ERROR)
  789. X    fprintf (stderr,"cannot create new archive file -- preserving tmp file\n");
  790. X
  791. X  (void) af_uchmod (arFilename, AF_ARCHMODE);
  792. X  (void) af_unlink (arTmpFilename);
  793. X
  794. X  (void) af_unlink (datFilename);
  795. X  if (af_syslink (datTmpFilename, datFilename) == ERROR)
  796. X    fprintf (stderr,"cannot create new archive file -- preserving tmp file\n");
  797. X  (void) af_uchmod (datFilename, AF_ARCHMODE);
  798. X  (void) af_unlink (datTmpFilename);
  799. X  (void) af_unlink (lckFilename);
  800. X
  801. X  return (AF_OK);
  802. X}
  803. X
  804. X/*===========================================================================
  805. X * askConfirm -- ask for confirmation
  806. X *
  807. X *==========================================================================*/
  808. X
  809. XLOCAL askConfirm (expAnswer)
  810. X     char *expAnswer;
  811. X{
  812. X  char strBuf[256], answer[10], *cp;
  813. X
  814. X  (void) fflush (stdin);
  815. X  printf ("[%s] ", expAnswer);
  816. X  strBuf[0] = '\0';
  817. X  answer[0] = '\0';
  818. X  (void) gets (strBuf);
  819. X  (void) sscanf (strBuf, "%s", answer);
  820. X  if (answer[0] == '\0') return TRUE; /* assumption acknowledged */
  821. X  cp = answer;
  822. X  while (*cp ? (*cp++ |= ' ') : 0); /* make sure answer is lowercase */
  823. X  return !strncmp (expAnswer, answer, strlen (expAnswer));
  824. X}
  825. X
  826. X/*===========================================================================
  827. X * lookup, netItem, itemCmp
  828. X * Functions for random positioning in input stream
  829. X *
  830. X *==========================================================================*/
  831. X
  832. Xlookup (input, searchStr, pos)
  833. X     Input *input;
  834. X     char  *searchStr;
  835. X     int   pos;
  836. X{
  837. X  if (pos == 0)
  838. X    input->curPos = 0;
  839. X  if (input->curPos == input->length)
  840. X    return (-1);
  841. X
  842. X  while (itemCmp (&(input->string[input->curPos]),
  843. X           searchStr, strlen (searchStr)))
  844. X    {
  845. X      input->curPos++;
  846. X      while (input->string[input->curPos] != searchStr[0])
  847. X    {
  848. X      input->curPos++;
  849. X      if (input->curPos == input->length)
  850. X        return (-1);
  851. X    }
  852. X    }
  853. X  return (input->curPos);
  854. X}
  855. X
  856. XnextItem (input)
  857. X     Input *input;
  858. X{
  859. X  if (input->curPos == input->length)
  860. X    return (-1);
  861. X  /* search next white space */
  862. X  while ((input->string[input->curPos] != ' ') && 
  863. X     (input->string[input->curPos] != '\t') && 
  864. X     (input->string[input->curPos] != '\n'))
  865. X    if (++input->curPos == input->length)
  866. X      return (-1);
  867. X
  868. X  /* skip white spaces */
  869. X  while ((input->string[input->curPos] == ' ') || 
  870. X     (input->string[input->curPos] == '\t') || 
  871. X     (input->string[input->curPos] == '\n'))
  872. X    if (++input->curPos == input->length)
  873. X      return (-1);
  874. X
  875. X  return (input->curPos);
  876. X}
  877. X
  878. XnextLine(input)
  879. X     Input *input;
  880. X{
  881. X  if (input->curPos == input->length)
  882. X    return (-1);
  883. X  /* search beginning of next line */
  884. X  while (input->string[input->curPos] != '\n')
  885. X    if (++input->curPos == input->length)
  886. X      return (-1);
  887. X
  888. X  /* skip newline */
  889. X  if (++input->curPos == input->length)
  890. X    return (-1);
  891. X
  892. X  return (input->curPos);
  893. X}
  894. X
  895. Xchar *itemCopy (str1, str2)
  896. X     char *str1, *str2;
  897. X{
  898. X  if (!strncmp (str2, AF_NOSTRING, 2))
  899. X    {
  900. X      str1[0] = '\0';
  901. X      return (str1);
  902. X    }
  903. X
  904. X  while (*str1 = *str2)
  905. X    {
  906. X      if ((*str2 ==' ') || (*str2 =='\t') || (*str2 =='\n'))
  907. X    { *str1 = '\0'; return (str1); }
  908. X      str1++;
  909. X      str2++;
  910. X    }
  911. X  return (str1);
  912. X}
  913. X
  914. XitemCmp (baseStr, searchStr, len)
  915. X     char *baseStr, *searchStr;
  916. X     int  len;
  917. X{
  918. X  int i=0;
  919. X  while (baseStr[i] == searchStr[i])
  920. X    {
  921. X      i++;
  922. X      if (i == len)
  923. X    {
  924. X      if ((baseStr[i] == ' ') || (baseStr[i] == '\t') ||
  925. X          (baseStr[i] == '\0') || (baseStr[i] == '\n'))
  926. X        return (0);
  927. X      else
  928. X        return (1);
  929. X    }
  930. X    }
  931. X  return (1);
  932. X}
  933. X
  934. X/*=========================================================================
  935. X * verifyString, verifyInt, verifyDate
  936. X * complainString
  937. X * 
  938. X *=========================================================================*/
  939. X
  940. Xchar *verifyString (name, input, level)
  941. X     char  *name;
  942. X     Input input;
  943. X     int   level;
  944. X{
  945. X  static char value[256];
  946. X
  947. X  (void) itemCopy (value, &input.string[input.curPos]);
  948. X
  949. X  if (level <= givenVLevel)
  950. X    {
  951. X      fprintf (stdout, "assume %s to be: ->%s<-, ok ? (y/n) ", name, value);
  952. X      if (askConfirm ("y"))
  953. X    goto exit;
  954. X      fprintf (stdout, "enter new %s (*0* for empty string): ", name);
  955. X      (void) fscanf (stdin, "%s", value);
  956. X      if (!strncmp (value, "*0*", 3))
  957. X    return ((char *)0);
  958. X    }
  959. X exit:
  960. X  if (value[0])
  961. X    return (value);
  962. X  else
  963. X    return ((char *)0);
  964. X}
  965. X  
  966. Xchar *complainString (name, string1, string2, level)
  967. X     char  *name, *string1, *string2;
  968. X     int   level;
  969. X{
  970. X  if (level <= givenVLevel)
  971. X    {
  972. X      fprintf (stdout,
  973. X           "Inconsistency: value for %s is ->%s<- (should be ->%s<-), %s",
  974. X           name, string1, string2, "fix ? (y/n) ");
  975. X      if (askConfirm ("y"))
  976. X    return (string1);
  977. X    }
  978. X  return (string2);
  979. X}
  980. X  
  981. XverifyInt (name, input, level)
  982. X     char  *name;
  983. X     Input input;
  984. X     int   level;
  985. X{
  986. X  int  value;
  987. X
  988. X  value = atoi (&input.string[input.curPos]);
  989. X
  990. X  if (level <= givenVLevel)
  991. X    {
  992. X      fprintf (stdout, "assume %s to be: ->%d<-, ok ? (y/n) ", name, value);
  993. X      if (askConfirm ("y"))
  994. X    return (value);
  995. X      fprintf (stdout, "enter new %s: ", name);
  996. X      (void) fscanf (stdin, "%d", value);
  997. X    }
  998. X  return (value);
  999. X}
  1000. X  
  1001. XverifyOct (name, input, level)
  1002. X     char  *name;
  1003. X     Input input;
  1004. X     int   level;
  1005. X{
  1006. X  int  value;
  1007. X
  1008. X  (void) sscanf (&input.string[input.curPos], "%o", &value);
  1009. X
  1010. X  if (level <= givenVLevel)
  1011. X    {
  1012. X      fprintf (stdout, "assume %s to be: ->%o<-, ok ? (y/n) ", name, value);
  1013. X      if (askConfirm ("y"))
  1014. X    return (value);
  1015. X      fprintf (stdout, "enter new %s: ", name);
  1016. X      (void) fscanf (stdin, "%o", value);
  1017. X    }
  1018. X  return (value);
  1019. X}
  1020. X  
  1021. XverifyDate (name, input, level)
  1022. X     char  *name;
  1023. X     Input input;
  1024. X     int   level;
  1025. X{
  1026. X  int  value;
  1027. X
  1028. X  value = atoi (&input.string[input.curPos]);
  1029. X
  1030. X  if (level <= givenVLevel)
  1031. X    {
  1032. X      fprintf (stdout, "assume %s to be: ->%d<-, ok ? (y/n) ", name, value);
  1033. X      if (askConfirm ("y"))
  1034. X    return (value);
  1035. X      fprintf (stdout, "enter new date: ");
  1036. X      (void) fscanf (stdin, "%d", value);
  1037. X    }
  1038. X  return (value);
  1039. X}
  1040. X  
  1041. END_OF_FILE
  1042. if test 30386 -ne `wc -c <'src/afs/afsrepair.c'`; then
  1043.     echo shar: \"'src/afs/afsrepair.c'\" unpacked with wrong size!
  1044. fi
  1045. # end of 'src/afs/afsrepair.c'
  1046. fi
  1047. echo shar: End of archive 26 \(of 33\).
  1048. cp /dev/null ark26isdone
  1049. MISSING=""
  1050. 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
  1051.     if test ! -f ark${I}isdone ; then
  1052.     MISSING="${MISSING} ${I}"
  1053.     fi
  1054. done
  1055. if test "${MISSING}" = "" ; then
  1056.     echo You have unpacked all 33 archives.
  1057.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1058. else
  1059.     echo You still need to unpack the following archives:
  1060.     echo "        " ${MISSING}
  1061. fi
  1062. ##  End of shell archive.
  1063. exit 0
  1064.