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

  1. Subject:  v19i036:  A software configuration management system, Part23/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 36
  8. Archive-name: shape/part23
  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 23 (of 33)."
  19. # Contents:  src/afs/afbpool.c
  20. # Wrapped by rsalz@papaya.bbn.com on Thu Jun  1 19:27:15 1989
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'src/afs/afbpool.c' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'src/afs/afbpool.c'\"
  24. else
  25. echo shar: Extracting \"'src/afs/afbpool.c'\" \(26801 characters\)
  26. sed "s/^X//" >'src/afs/afbpool.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 *    Shape/AFS
  55. X *
  56. X *    afbpool.c -- read/write binary-pool control files (ndbm version)
  57. X *
  58. X *    Author: Andreas Lampen, TU-Berlin (andy@coma.UUCP)
  59. X *                      (andy@db0tui62.BITNET)
  60. X *
  61. X *    $Header: afbpool.c[1.5] Wed Feb 22 16:27:14 1989 andy@coma published $
  62. X *
  63. X *    EXPORT:
  64. X *      af_rbplist -- read list of files in binary pool
  65. X *      af_delbpentry -- delete file entry in binary pool
  66. X *      af_rplbpentry -- replace file entry in binary pool
  67. X *      af_isbpfile -- see if a given file belongs to binary pool
  68. X *      af_detbpool -- detach binary pool
  69. X */
  70. X
  71. X#include <stdio.h>
  72. X#include <sys/types.h>
  73. X#include <sys/stat.h>
  74. X#include <sys/dir.h>
  75. X#include <sys/file.h>
  76. X#include <sys/time.h>
  77. X#include <string.h>
  78. X#ifdef SUNOS_4_0
  79. X#include <strings.h>
  80. X#endif
  81. X#ifdef OLDDBM
  82. X#undef NULL
  83. X#include <dbm.h>
  84. X#undef NULL
  85. X#else
  86. X#include <ndbm.h>
  87. X#endif
  88. X
  89. X#include "typeconv.h"
  90. X#include "afsys.h"
  91. X#include "afs.h"
  92. X#include "afarchive.h"
  93. X
  94. X#ifdef MEMDEBUG
  95. Xextern FILE *memprot;
  96. X#endif
  97. X
  98. X/*==========================================================================
  99. X *    definition of binary pool revision list
  100. X *      plus hashtable for faster access
  101. X *
  102. X *==========================================================================*/
  103. X
  104. XLOCAL Af_revlist bplst;
  105. X     /* base address of all binary pool list descriptors */
  106. XLOCAL Af_revlist *bplists = (Af_revlist *)0;  
  107. X     /* base address of freelist for binary pool list descriptors */
  108. XLOCAL Af_revlist *bpfreelist = &bplst;  /* beginning of freelist */
  109. X
  110. XLOCAL Af_hash bphash;
  111. X
  112. XLOCAL Af_revlist *initlist (path, mode)
  113. X     char *path;
  114. X     int  mode;
  115. X{
  116. X  static bool hinit = FALSE; /* indicate if hashtable is yet initialized */
  117. X  int         af_fhash();
  118. X  register    i;
  119. X  Af_revlist  *list, *oldlist, **oldptr, *tail;
  120. X  char        *malloc(), *pathsym, *arname;
  121. X
  122. X  oldptr = &oldlist;
  123. X  /* init hashtable if it is not yet done */
  124. X  if (!hinit)
  125. X    {
  126. X      (void) af_hashinit (&bphash, AF_MAXLISTS, af_fhash);
  127. X      hinit = TRUE;
  128. X    }
  129. X
  130. X  pathsym = af_entersym (path);
  131. X
  132. X  /* if there are open archives check if desired archive is loaded yet */
  133. X  if (bplists != (Af_revlist *)0)
  134. X    {
  135. X      if (af_symlookup (&bphash, path, (Af_revlist *)0, oldptr))
  136. X    {
  137. X      /* found something */
  138. X      /* if it is the right list */
  139. X      if (oldlist->af_cattrs.af_syspath == pathsym)
  140. X        return (oldlist);
  141. X      /* else continue the search as long as there are entries */
  142. X      while (af_symlookup (&bphash, path, oldlist, oldptr))
  143. X        {
  144. X          if (oldlist->af_cattrs.af_syspath == pathsym)
  145. X        return (oldlist);
  146. X        }
  147. X    }
  148. X    }
  149. X
  150. X  /* check if AFS subdirectory exists */
  151. X  if ((arname = af_gbpname (path)) == (char *)0)
  152. X    {
  153. X      if (mode == AF_READ)
  154. X    SFAIL ("initlist", "", AF_ENOAFSDIR, (Af_revlist *)0)
  155. X      else
  156. X    FAIL ("initlist", "", AF_ENOAFSDIR, (Af_revlist *)0);
  157. X    }
  158. X  
  159. X  /* if there are no more descriptors available - allocate new space */
  160. X  if (bpfreelist == (Af_revlist *)0)
  161. X    {
  162. X      if ((bpfreelist = (Af_revlist *) malloc ((unsigned) (AF_LISTSEG * sizeof (Af_revlist)))) == (Af_revlist *)0)
  163. X    FAIL ("initlist", "malloc(i)", AF_ESYSERR, (Af_revlist *)0);
  164. X
  165. X      /* build up new freelist */
  166. X      for (i=1; i<AF_LISTSEG; i++)
  167. X    bpfreelist[i-1].af_next = &(bpfreelist[i]);
  168. X      bpfreelist[AF_LISTSEG-1].af_next = (Af_revlist *)0;
  169. X    }
  170. X
  171. X  if (bplists != (Af_revlist *)0)
  172. X    {
  173. X      tail = bplists->af_next;
  174. X      bplists->af_next = bpfreelist;
  175. X      bpfreelist = bpfreelist->af_next;
  176. X      list = bplists->af_next;
  177. X      bzero ((char *)list, sizeof (*list));
  178. X
  179. X      list->af_next = tail;
  180. X    }
  181. X  else
  182. X    {
  183. X      list = bpfreelist;
  184. X      bpfreelist = bpfreelist->af_next;
  185. X      /* initialize whole struct (i.e. set af_next to "nil") */
  186. X      bzero ((char *)list, sizeof (*list));
  187. X      bplists = list;
  188. X    }
  189. X
  190. X  list->af_mem = (char *)0;
  191. X
  192. X  /* initialize list structure */
  193. X  list->af_cattrs.af_host = af_gethostname ();
  194. X  list->af_cattrs.af_syspath = pathsym;
  195. X  list->af_arfilename = arname;
  196. X  list->af_busyfilename = af_entersym ("");
  197. X
  198. X  list->af_listlen = af_gmaxbpsize (list->af_arfilename);
  199. X  if ((list->af_list = (Af_vattrs *)af_malloc (list, (unsigned) (list->af_listlen * sizeof(Af_vattrs)))) == (Af_vattrs *)0)
  200. X    FAIL ("initlist", "malloc", AF_ESYSERR, (Af_revlist *)0);
  201. X
  202. X  bzero ((char *)list->af_list, list->af_listlen * sizeof (Af_vattrs));
  203. X
  204. X  list->af_extent |= AF_BPOOL;
  205. X  list->af_extent |= AF_UXWRITE;
  206. X  list->af_nrevs = 0;
  207. X
  208. X  /* add list to hashtable */
  209. X  (void) af_hashsym (&bphash, path, list);
  210. X#ifdef MEMDEBUG
  211. X  fprintf (memprot, "InitBP (%s)\n", path);
  212. X#endif
  213. X
  214. X  return (list);
  215. X}
  216. X
  217. X/*==========================================================================
  218. X * af_dbmstring -- build dbm string from attrbuf
  219. X *
  220. X *==========================================================================*/
  221. X
  222. XLOCAL datum af_dbmstring (key, size)
  223. X     Af_key *key;
  224. X     int    size; /* size of dbm key element */
  225. X{
  226. X  static datum data;
  227. X  static char  string[MAXDBMLEN];
  228. X  char *ptrlist[AF_MAXUDAS], *udaptr;
  229. X  register i;
  230. X  int  maxstrlen;
  231. X
  232. X  data.dptr = string;
  233. X
  234. X  /* enter all relevant attributes */
  235. X#ifdef ULTRIX_2_0
  236. X  (void) sprintf (string, "%s %s %s %s %d %d %s %s \0",
  237. X       CATTR(key).af_host, CATTR(key).af_syspath, VATTR(key).af_name, 
  238. X       NOTMT (VATTR(key).af_type), VATTR(key).af_gen, VATTR(key).af_rev, 
  239. X       NOTMT (VATTR(key).af_variant), VATTR(key).af_auname);
  240. X  (void) sprintf (&string[strlen(string)], "%s %o %d %d %d %d \0",
  241. X       VATTR(key).af_auhost, VATTR(key).af_mode, VATTR(key).af_fsize,
  242. X       VATTR(key).af_mtime, VATTR(key).af_atime, VATTR(key).af_ctime);
  243. X#else
  244. X  (void) sprintf (string, "%s %s %s %s %d %d %s %s %s %o %d %d %d %d \0",
  245. X       CATTR(key).af_host, CATTR(key).af_syspath, VATTR(key).af_name, 
  246. X       NOTMT (VATTR(key).af_type), VATTR(key).af_gen, VATTR(key).af_rev, 
  247. X       NOTMT (VATTR(key).af_variant), VATTR(key).af_auname, 
  248. X       VATTR(key).af_auhost, VATTR(key).af_mode, VATTR(key).af_fsize,
  249. X       VATTR(key).af_mtime, VATTR(key).af_atime, VATTR(key).af_ctime);
  250. X#endif
  251. X  (void) strcat (string, AF_UDAID);
  252. X  data.dsize = strlen (data.dptr) + sizeof (char);
  253. X
  254. X  /* add user defined attributes */ 
  255. X  (void) af_lhashsyms (&(VATTR(key).af_uhtab), ptrlist);
  256. X  i=0;
  257. X  udaptr = string;
  258. X  maxstrlen = (MAXDBMLEN - DBMLOSS) - size;
  259. X  while (ptrlist[i])
  260. X    {
  261. X      if ((data.dsize += ((strlen (ptrlist[i])) + sizeof (char))) >= maxstrlen)
  262. X    {
  263. X      data.dptr = (char *)0;
  264. X      FAIL ("dbmstring", "", AF_ETOOLONG, data);
  265. X    }
  266. X      udaptr = &udaptr[strlen(udaptr)+1];
  267. X      (void) strcpy (udaptr, ptrlist[i]);
  268. X      i++;
  269. X    }
  270. X
  271. X  udaptr[strlen(udaptr)+1] = '\0';
  272. X  data.dsize++;
  273. X
  274. X  return (data);
  275. X} /* end af_dbmstring */
  276. X
  277. X/*===================================================================
  278. X * af_dbmkey -- build attrbuf from dbm entry
  279. X *===================================================================*/
  280. X
  281. XLOCAL af_dbmkey (data, dbmkey, afkey)
  282. X     datum *data, *dbmkey;
  283. X     Af_key *afkey;
  284. X{
  285. X  char name[MAXNAMLEN], type[MAXTYPLEN], variant[MAXVARLEN], *udaptr;
  286. X  char host[MAXHOSTNAMELEN], syspath[MAXNAMLEN*4];
  287. X  char auhost[MAXHOSTNAMELEN], auname[MAXNAMLEN];
  288. X  int  af_fhash();
  289. X
  290. X  /* do initializations */
  291. X  VATTR(afkey).af_state = AF_NOSTATE;
  292. X  VATTR(afkey).af_class = AF_DERIVED | AF_VALID;
  293. X  VATTR(afkey).af_stime = AF_NOTIME;
  294. X  VATTR(afkey).af_lckname = (char *)0;
  295. X  VATTR(afkey).af_lckhost = (char *)0;
  296. X  VATTR(afkey).af_ltime = AF_NOTIME;
  297. X  VATTR(afkey).af_notesize = 0;
  298. X  VATTR(afkey).af_note = (char *)0;
  299. X  VATTR(afkey).af_repr = AF_FILE;
  300. X  VATTR(afkey).af_dsize = 0;
  301. X  VATTR(afkey).af_data = (char *)0;
  302. X  VATTR(afkey).af_nlinks = 0;
  303. X  VATTR(afkey).af_succgen = AF_NOVNUM;
  304. X  VATTR(afkey).af_succrev = AF_NOVNUM;
  305. X  VATTR(afkey).af_predgen = AF_NOVNUM;
  306. X  VATTR(afkey).af_predrev = AF_NOVNUM;
  307. X
  308. X  (void) sscanf (data->dptr, "%s%s%s%s%ld%ld%s%s%s%ho%ld%ld%ld%ld",
  309. X      host, syspath, name, type,
  310. X      &(VATTR(afkey).af_gen), &(VATTR(afkey).af_rev), 
  311. X      variant, auname, auhost, &(VATTR(afkey).af_mode), 
  312. X      &(VATTR(afkey).af_fsize), &(VATTR(afkey).af_mtime), 
  313. X      &(VATTR(afkey).af_atime),&(VATTR(afkey).af_ctime));
  314. X
  315. X  /* check plausibility of host and syspath */
  316. X  if (strcmp (host, CATTR(afkey).af_host) || 
  317. X      strcmp (syspath, CATTR(afkey).af_syspath))
  318. X    af_wng ("dbmkey", "location of bpool possibly not correct");
  319. X
  320. X  if (!strcmp (type, AF_NOSTRING))
  321. X    type[0] = '\0';
  322. X  if (!strcmp (variant, AF_NOSTRING))
  323. X    variant[0] = '\0';
  324. X
  325. X  VATTR(afkey).af_name = af_entersym (name);
  326. X
  327. X  if (type[0])
  328. X    VATTR(afkey).af_type = af_entersym (type);
  329. X  else
  330. X    VATTR(afkey).af_type = (char *)0;
  331. X
  332. X  if (variant[0])
  333. X    VATTR(afkey).af_variant = af_entersym (variant);
  334. X  else
  335. X    VATTR(afkey).af_variant = (char *)0;
  336. X  
  337. X  VATTR(afkey).af_auname = af_entersym (auname);
  338. X  VATTR(afkey).af_auhost = af_enterhost (auhost);
  339. X  VATTR(afkey).af_hashname = af_entersym (dbmkey->dptr);
  340. X
  341. X  /* read user defined attributes */
  342. X
  343. X  udaptr = rindex (data->dptr, AF_UDAID[0]);
  344. X  if (strcmp (udaptr, AF_UDAID))
  345. X    {
  346. X      /* this should not happen very often */
  347. X      udaptr = index (data->dptr, AF_UDAID[0]);
  348. X      while ((udaptr) && (!strcmp (udaptr, AF_UDAID)))
  349. X    udaptr = index (udaptr, AF_UDAID[0]);
  350. X      if (!udaptr)
  351. X    FAIL ("dbmkey", "cannot find udas", AF_EINCONSIST, ERROR);
  352. X    }
  353. X
  354. X  /* build up hashlist and read user defined attributes */
  355. X  if (af_hashinit (&(VATTR(afkey).af_uhtab), AF_MAXUDAS, af_fhash) == ERROR)
  356. X    return (ERROR);
  357. X
  358. X  udaptr += (AF_IDSTRLEN + sizeof (char));
  359. X  while (udaptr[0])
  360. X    {
  361. X      (void) af_hashsym (&(VATTR(afkey).af_uhtab), udaptr, (Af_revlist *)0);
  362. X#ifdef MEMDEBUG
  363. X      fprintf (memprot, "UdaBP (%s)\n", udaptr);
  364. X#endif
  365. X      VATTR(afkey).af_udanum++;
  366. X      udaptr = (index (udaptr, '\0') + sizeof (char));
  367. X    }
  368. X  return (AF_OK);
  369. X} /* end af_dbmkey */
  370. X
  371. X/*===================================================================
  372. X * gbpsize -- get binary pool size and owner
  373. X *===================================================================*/
  374. X
  375. X#ifdef OLDDBM
  376. XLOCAL Af_user *gbpsize (size)
  377. X#else
  378. XLOCAL Af_user *gbpsize (db, size)
  379. X     DBM *db;
  380. X#endif
  381. X     short *size;
  382. X{
  383. X  static Af_user owner;
  384. X  datum data, dbkey;
  385. X  
  386. X  static char *stdentryname = AF_BPSTDENTRY;
  387. X
  388. X  dbkey.dptr = stdentryname;
  389. X  dbkey.dsize = strlen (AF_BPSTDENTRY);
  390. X
  391. X#ifdef OLDDBM
  392. X  data = fetch (dbkey);
  393. X#else
  394. X  data = dbm_fetch (db, dbkey);
  395. X#endif
  396. X  if (data.dptr == (char *)0)
  397. X    {
  398. X      *size = 0;
  399. X      return (af_getuser (getuid()));
  400. X    }
  401. X  else
  402. X    {
  403. X      (void) sscanf (data.dptr, "%hd%s%s", size, owner.af_username,owner.af_userhost);
  404. X      return (&owner);
  405. X    }
  406. X}
  407. X
  408. X/*===================================================================
  409. X * pbpsize -- put binary pool size and owner
  410. X *===================================================================*/
  411. X
  412. X#ifdef OLDDBM
  413. XLOCAL pbpsize (size, owner)
  414. X#else
  415. XLOCAL pbpsize (db, size, owner)
  416. X     DBM     *db;
  417. X#endif
  418. X     int     size;
  419. X     Af_user *owner;
  420. X{
  421. X  datum data, dbkey;
  422. X  static char str[32], *stdentryname = AF_BPSTDENTRY;
  423. X
  424. X  dbkey.dptr = stdentryname;
  425. X  dbkey.dsize = strlen (AF_BPSTDENTRY);
  426. X
  427. X  (void) sprintf (str, "%d %s %s\0", size, owner->af_username, owner->af_userhost);
  428. X  data.dptr = str;
  429. X  data.dsize = strlen (str) + sizeof (char);
  430. X
  431. X#ifdef OLDDBM
  432. X  store (dbkey, data);
  433. X#else
  434. X  (void) dbm_store (db, dbkey, data, DBM_REPLACE);
  435. X#endif
  436. X  return (AF_OK);
  437. X}
  438. X
  439. X/*================================================================
  440. X * af_lookupbpentry -- see if bpentry is loaded yet
  441. X *                     returns position in list
  442. X *
  443. X *================================================================*/
  444. X
  445. XLOCAL af_lookupbpentry (list, hashname)
  446. X     Af_revlist *list;
  447. X     char *hashname;
  448. X{
  449. X  int i=0, j=0;
  450. X
  451. X  for (; i < list->af_listlen; i++)
  452. X    {
  453. X      /* if entry is not valid */
  454. X      if (!(list->af_list[i].af_class & AF_VALID))
  455. X    continue;
  456. X      if (!strcmp (list->af_list[i].af_hashname, hashname))
  457. X    return (i);
  458. X      j++;
  459. X      if (j >= list->af_nrevs)
  460. X    return (ERROR);
  461. X    }
  462. X  FAIL ("lookupbpentry", "cannot find binary pool entry", AF_EINTERNAL, ERROR);
  463. X}
  464. X
  465. X#ifdef OLDDBM
  466. Xstatic char *bpool;
  467. Xstatic bool bpwrite = FALSE;
  468. X#endif
  469. X
  470. X/*==========================================================================
  471. X *    af_rbplist -- read all binary pool entries
  472. X *
  473. X *==========================================================================*/
  474. X
  475. XEXPORT Af_revlist *af_rbplist (path)
  476. X     char *path;
  477. X{
  478. X  datum  dbkey, data;
  479. X#ifndef OLDDBM
  480. X  DBM    *db;
  481. X#endif
  482. X  int    i=0, count=0;
  483. X  Af_key     entrykey;
  484. X  Af_revlist *list;
  485. X  Af_user    *owner;
  486. X
  487. X  if ((list = initlist (path, AF_READ)) == (Af_revlist *)0)
  488. X    return ((Af_revlist *)0);
  489. X  if (list->af_extent & AF_COMPLETE)
  490. X    return (list);
  491. X
  492. X#ifdef OLDDBM
  493. X  if (list->af_arfilename != bpool)
  494. X    {
  495. X      char bpfilename[MAXNAMLEN+1];
  496. X      FILE *tmpfdes;
  497. X      /* test existence of binary pool files */
  498. X      (void) sprintf (bpfilename, "%s.dir\0", list->af_arfilename);
  499. X      if (af_sysaccess (bpfilename, 0) == -1)
  500. X    {
  501. X      if (bpwrite)
  502. X        {
  503. X          /* create bpool files */
  504. X          tmpfdes = fopen (bpfilename, "w");
  505. X          (void) fclose (tmpfdes);
  506. X          (void) sprintf (bpfilename, "%s.pag\0", list->af_arfilename);
  507. X          tmpfdes = fopen (bpfilename, "w");
  508. X          (void) fclose (tmpfdes);
  509. X        }
  510. X      else
  511. X        SFAIL ("rbplist", "dbm_open", AF_ENOAFSDIR, (Af_revlist *)0);
  512. X    }
  513. X      if (dbminit (list->af_arfilename) != AF_OK)
  514. X    {
  515. X      (void) af_detbpool (list);
  516. X      SFAIL ("rbplist", "dbm_open", AF_ENOAFSDIR, (Af_revlist *)0);
  517. X    }
  518. X      bpool = list->af_arfilename;
  519. X    }
  520. X#else
  521. X  if ((db = dbm_open (list->af_arfilename, O_RDONLY, 0664)) == (DBM *)0)
  522. X    {
  523. X      (void) af_detbpool (list);
  524. X      SFAIL ("rbplist", "dbm_open", AF_ENOAFSDIR, (Af_revlist *)0);
  525. X    }
  526. X#endif
  527. X
  528. X  /* if list was empty up to now */
  529. X  if (list->af_nrevs == 0)
  530. X    {
  531. X#ifdef OLDDBM
  532. X      owner = gbpsize (&list->af_nrevs);
  533. X#else
  534. X      owner = gbpsize (db, &list->af_nrevs);
  535. X#endif
  536. X      list->af_cattrs.af_ownname = af_entersym (owner->af_username);
  537. X      list->af_cattrs.af_ownhost = af_enterhost (owner->af_userhost);
  538. X    }
  539. X  else
  540. X    /* if there are no references to the list, delete all entries and read */
  541. X    /* the whole binary pool. This is (hopefully) faster than updating */
  542. X    {
  543. X      if (list->af_refcount == 0)
  544. X    {
  545. X      for (i = 0; i < list->af_listlen; i++)
  546. X        {
  547. X          if (list->af_list[i].af_class & AF_VALID)
  548. X        {
  549. X          af_hashfree (&(list->af_list[i].af_uhtab));
  550. X          list->af_list[i].af_class &= ~AF_VALID;
  551. X        }
  552. X        }
  553. X      af_frmemlist (list);
  554. X    }
  555. X    }
  556. X
  557. X  i=0;
  558. X#ifdef OLDDBM
  559. X  for (dbkey = firstkey(); dbkey.dptr != NULL; dbkey = nextkey(dbkey))
  560. X#else
  561. X  for (dbkey = dbm_firstkey(db); dbkey.dptr != NULL; dbkey = dbm_nextkey(db))
  562. X#endif
  563. X    {
  564. X      if (!strncmp (dbkey.dptr, AF_BPSTDENTRY, AF_IDSTRLEN))
  565. X    continue;
  566. X      /* if there are existing references to binary pool preserve all */
  567. X      /* attribute buffers that are aleady read in and skip used places */
  568. X      if (i == list->af_listlen) /* if list is full */
  569. X    {
  570. X      if (af_lookupbpentry (list, dbkey.dptr) != ERROR)
  571. X        count++;
  572. X      else /* delete all additional entries in bpool has shrunk */
  573. X        {
  574. X#ifdef OLDDBM
  575. X          delete (dbkey);
  576. X#else
  577. X          (void) dbm_delete (db, dbkey);
  578. X#endif
  579. X          (void) af_unlink (af_bpfilename (path, dbkey.dptr));
  580. X        }
  581. X      continue;
  582. X    }
  583. X      count++;
  584. X      if (list->af_refcount > 0)
  585. X     {
  586. X      while (list->af_list[i].af_class & AF_VALID)
  587. X        i++;
  588. X      if (af_lookupbpentry (list, dbkey.dptr) != ERROR)
  589. X          continue;
  590. X    }
  591. X#ifdef OLDDBM
  592. X      data = fetch (dbkey);
  593. X#else
  594. X      data = dbm_fetch (db, dbkey);
  595. X#endif
  596. X      /* check if file exists. If not, ignore this entry */
  597. X      /* this check may be omitted in further releases */
  598. X      if (af_sysaccess (af_bpfilename (path, dbkey.dptr), 0) == AF_OK)
  599. X    {
  600. X      entrykey.af_ldes = list;
  601. X      entrykey.af_lpos = i;
  602. X      (void) af_dbmkey (&data, &dbkey, &entrykey);
  603. X      i++;
  604. X    }
  605. X      else
  606. X    count--;
  607. X    }
  608. X
  609. X  list->af_nrevs = count;
  610. X
  611. X  /* clear "incomplete" bit */
  612. X  list->af_extent |= AF_COMPLETE;
  613. X
  614. X#ifndef OLDDBM
  615. X  dbm_close (db);
  616. X#endif
  617. X  return (list);
  618. X}
  619. X
  620. X
  621. X/*==========================================================================
  622. X *    af_delbpentry -- delete binary pool entry
  623. X *
  624. X *==========================================================================*/
  625. X
  626. XEXPORT af_delbpentry (key)
  627. X     Af_key *key;
  628. X{
  629. X  datum  dbkey;
  630. X#ifndef OLDDBM
  631. X  DBM    *db;
  632. X#endif
  633. X  short  listsize;
  634. X  Af_revlist *list;
  635. X  Af_user    *owner;
  636. X
  637. X  if ((list = initlist (CATTR(key).af_syspath, AF_RDWR)) == (Af_revlist *)0)
  638. X    return (ERROR);
  639. X
  640. X  if (key->af_ldes != list)
  641. X    FAIL ("delbpentry", "", AF_EINVKEY, ERROR);
  642. X
  643. X#ifdef OLDDBM
  644. X  if (list->af_arfilename != bpool)
  645. X    {
  646. X      char bpfilename[MAXNAMLEN+1];
  647. X      FILE *tmpfdes;
  648. X      /* test existence of binary pool files */
  649. X      (void) sprintf (bpfilename, "%s.dir\0", list->af_arfilename);
  650. X      if (af_sysaccess (bpfilename, 0) == -1)
  651. X    {
  652. X      /* create bpool files */
  653. X      tmpfdes = fopen (bpfilename, "w");
  654. X      (void) fclose (tmpfdes);
  655. X      (void) sprintf (bpfilename, "%s.pag\0", list->af_arfilename);
  656. X      tmpfdes = fopen (bpfilename, "w");
  657. X      (void) fclose (tmpfdes);
  658. X    }
  659. X      if (dbminit (list->af_arfilename) != AF_OK)
  660. X    {
  661. X      (void) af_detbpool (list);
  662. X      FAIL ("delbpentry", "dbm_open", AF_ESYSERR, ERROR);
  663. X    }
  664. X      bpool = list->af_arfilename;
  665. X    }
  666. X#else
  667. X  if ((db = dbm_open (list->af_arfilename, O_RDWR|O_CREAT, 0664)) == (DBM *)0)
  668. X    {
  669. X      (void) af_detbpool (list);
  670. X      FAIL ("delbpentry", "dbm_open", AF_ESYSERR, ERROR);
  671. X    }
  672. X#endif
  673. X
  674. X  dbkey.dptr = VATTR(key).af_hashname;
  675. X  dbkey.dsize = strlen (dbkey.dptr) + sizeof (char);
  676. X#ifdef OLDDBM
  677. X  delete (dbkey);
  678. X#else
  679. X  (void) dbm_delete (db, dbkey);
  680. X#endif
  681. X  (void) af_unlink (af_bpfilename (CATTR(key).af_syspath, VATTR(key).af_hashname));
  682. X#ifdef OLDDBM
  683. X  owner = gbpsize (&listsize);
  684. X#else
  685. X  owner = gbpsize (db, &listsize);
  686. X#endif
  687. X  list->af_cattrs.af_ownname = af_entersym (owner->af_username);
  688. X  list->af_cattrs.af_ownhost = af_enterhost (owner->af_userhost);
  689. X  listsize--;
  690. X  list->af_nrevs--;
  691. X#ifdef OLDDBM
  692. X  (void) pbpsize (list->af_nrevs, owner);
  693. X#else
  694. X  (void) pbpsize (db, list->af_nrevs, owner);
  695. X#endif
  696. X
  697. X  /* clear "valid" bit in attribute buffer and free allocated memory */
  698. X  af_hashfree (&(VATTR(key).af_uhtab));
  699. X  VATTR(key).af_class &= ~AF_VALID;
  700. X
  701. X#ifndef OLDDBM
  702. X  dbm_close (db);
  703. X#endif
  704. X  return (AF_OK);
  705. X}
  706. X
  707. X
  708. X/*==========================================================================
  709. X *    af_rplbpentry -- replace binary pool entry
  710. X *
  711. X *==========================================================================*/
  712. X
  713. XEXPORT af_rplbpentry (oldkey, newkey, bpkey)
  714. X     Af_key *oldkey, *newkey, *bpkey;
  715. X{
  716. X  datum  dbkey, data;
  717. X#ifndef OLDDBM
  718. X  DBM    *db;
  719. X#else
  720. X  datum  exdata;
  721. X#endif
  722. X  bool   add = FALSE, found = FALSE;
  723. X  short  freepos, listsize, i;
  724. X  Af_revlist *list;
  725. X  Af_user    *owner;
  726. X  time_t lastacc;
  727. X  struct timeval tvp[2];
  728. X  char   *bpname;
  729. X  int    af_fhash();
  730. X
  731. X  if ((list = initlist (CATTR(newkey).af_syspath, AF_RDWR)) == (Af_revlist *)0)
  732. X    return (ERROR);
  733. X
  734. X  if ((oldkey != (Af_key *)0) && (oldkey->af_ldes != list))
  735. X    FAIL ("rplbpentry", "", AF_EINVKEY, ERROR);
  736. X
  737. X#ifdef OLDDBM
  738. X  if (list->af_arfilename != bpool)
  739. X    {
  740. X      char bpfilename[MAXNAMLEN+1];
  741. X      FILE *tmpfdes;
  742. X      /* test existence of binary pool files */
  743. X      (void) sprintf (bpfilename, "%s.dir\0", list->af_arfilename);
  744. X      if (af_sysaccess (bpfilename, 0) == -1)
  745. X    {
  746. X      /* create bpool files */
  747. X      tmpfdes = fopen (bpfilename, "w");
  748. X      (void) fclose (tmpfdes);
  749. X      (void) sprintf (bpfilename, "%s.pag\0", list->af_arfilename);
  750. X      tmpfdes = fopen (bpfilename, "w");
  751. X      (void) fclose (tmpfdes);
  752. X    }
  753. X      if (dbminit (list->af_arfilename) != AF_OK)
  754. X    {
  755. X      (void) af_detbpool (list);
  756. X      FAIL ("rplbpentry", "dbm_open", AF_ESYSERR, ERROR);
  757. X    }
  758. X      bpool = list->af_arfilename;
  759. X    }
  760. X#else
  761. X  if ((db = dbm_open (list->af_arfilename, O_RDWR|O_CREAT, 0664)) == (DBM *)0)
  762. X    {
  763. X      (void) af_detbpool (list);
  764. X      FAIL ("rplbpentry", "dbm_open", AF_ESYSERR, ERROR);
  765. X    }
  766. X#endif
  767. X
  768. X  if (oldkey == (Af_key *)0)
  769. X    {
  770. X      /* if we actually have to "add" a file */
  771. X#ifdef OLDDBM
  772. X      owner = gbpsize (&listsize);
  773. X#else
  774. X      owner = gbpsize (db, &listsize);
  775. X#endif
  776. X      list->af_cattrs.af_ownname = af_entersym (owner->af_username);
  777. X      list->af_cattrs.af_ownhost = af_enterhost (owner->af_userhost);
  778. X      if (listsize < list->af_listlen)
  779. X    {
  780. X      add = TRUE;
  781. X      /* look for free attribute buffer in bplist */
  782. X      freepos = list->af_listlen-1;
  783. X      while ((list->af_list[freepos].af_class & AF_VALID) && (freepos >=0))
  784. X        freepos--;
  785. X      if (freepos == -1)
  786. X        {
  787. X#ifndef OLDDBM         
  788. X          dbm_close (db);
  789. X#endif
  790. X          FAIL ("rplbpentry", "no free entry in binary pool", AF_EINCONSIST, ERROR);
  791. X        }
  792. X    }
  793. X      else
  794. X    {
  795. X      /* remove the oldest (->af_atime) file */
  796. X      /* read in whole list of bpfiles */
  797. X#ifdef OLDDBM
  798. X      bpwrite = TRUE;
  799. X#endif
  800. X      if ((list = af_rbplist (list->af_cattrs.af_syspath))
  801. X          == (Af_revlist *)0)
  802. X        return (ERROR);
  803. X#ifdef OLDDBM
  804. X      bpwrite = FALSE;
  805. X#endif
  806. X          
  807. X      lastacc = (time_t)af_acttime ();
  808. X      
  809. X      for (i=0; i < list->af_nrevs; i++)
  810. X        {
  811. X          if ((!list->af_list[i].af_nlinks) && 
  812. X          (list->af_list[i].af_atime < lastacc))
  813. X        {
  814. X          freepos = i;
  815. X          lastacc = list->af_list[freepos].af_atime;
  816. X          dbkey.dptr = list->af_list[freepos].af_hashname;
  817. X          found = TRUE;
  818. X        }
  819. X        }
  820. X
  821. X      if (!found)
  822. X        FAIL ("rplbpentry", "", AF_EBPFULL, ERROR);
  823. X
  824. X      dbkey.dsize = strlen (dbkey.dptr) + sizeof (char);
  825. X#ifdef OLDDBM
  826. X      delete (dbkey);
  827. X#else
  828. X      (void) dbm_delete (db, dbkey);
  829. X#endif
  830. X      if (oldkey != newkey)
  831. X        (void) af_unlink (af_bpfilename (list->af_cattrs.af_syspath, dbkey.dptr));
  832. X    }
  833. X    } /* if (oldkey == (Af_key *)0) then ... */
  834. X  else
  835. X    {
  836. X      if (oldkey != newkey)
  837. X    {
  838. X      dbkey.dptr = VATTR(oldkey).af_hashname;
  839. X      dbkey.dsize = strlen (dbkey.dptr) + sizeof (char);
  840. X#ifdef OLDDBM
  841. X      delete (dbkey);
  842. X#else
  843. X      (void) dbm_delete (db, dbkey);
  844. X#endif
  845. X      (void) af_unlink (af_bpfilename (CATTR(oldkey).af_syspath, dbkey.dptr));
  846. X    }
  847. X      freepos = oldkey->af_lpos;
  848. X    }
  849. X
  850. X  /* enter new entry */
  851. X  if (oldkey != newkey)
  852. X    {
  853. X      i = 0;
  854. X      do
  855. X    {
  856. X      if (++i > list->af_listlen)
  857. X        FAIL ("rplbpentry",
  858. X          "cannot build unique hashname", AF_EINTERNAL, ERROR);
  859. X      dbkey.dptr =
  860. X        af_rbphashname (VATTR(newkey).af_name,VATTR(newkey).af_type,
  861. X                VATTR(newkey).af_gen, VATTR(newkey).af_rev,
  862. X                VATTR(newkey).af_variant, newkey->af_ldes, i);
  863. X      dbkey.dsize = strlen (dbkey.dptr) + sizeof (char);
  864. X      data = af_dbmstring (newkey, dbkey.dsize);
  865. X      if (data.dptr == (char *)0)
  866. X        return (ERROR);
  867. X#ifdef OLDDBM
  868. X      exdata = fetch (dbkey);
  869. X#endif
  870. X    }
  871. X      /* as long as key is not unique, try another one */
  872. X#ifdef OLDDBM
  873. X      while (exdata.dptr);
  874. X      store (dbkey, data);
  875. X#else
  876. X      while (dbm_store (db, dbkey, data, DBM_INSERT));
  877. X#endif
  878. X      
  879. X      VATTR(newkey).af_hashname = dbkey.dptr;
  880. X
  881. X      /*** copy file ***/
  882. X      bpname = af_bpfilename (CATTR(newkey).af_syspath, VATTR(newkey).af_hashname);
  883. X      if (af_cpfile (newkey->af_ldes->af_busyfilename, VATTR(newkey).af_fsize, bpname) == ERROR)
  884. X    FAIL ("rplbpentry", "cpfile", AF_ESYSERR, ERROR);
  885. X      /*** set modification and access date (not necessary) ***/
  886. X      tvp[0].tv_sec = VATTR(newkey).af_atime;
  887. X      tvp[0].tv_usec = 0; 
  888. X      tvp[1].tv_sec = VATTR(newkey).af_mtime;
  889. X      tvp[1].tv_usec = 0;
  890. X      if (utimes (bpname, tvp) == ERROR)
  891. X    FAIL ("rplbpentry", "utimes", AF_ESYSERR, ERROR);
  892. X      (void) af_uchmod (bpname, (int) VATTR(newkey).af_mode);
  893. X    }
  894. X  else
  895. X    {
  896. X      dbkey.dptr = VATTR(newkey).af_hashname;
  897. X      dbkey.dsize = strlen (dbkey.dptr) + sizeof (char);
  898. X      data = af_dbmstring (newkey, dbkey.dsize);
  899. X      if (data.dptr == (char *)0)
  900. X    return (ERROR);
  901. X#ifdef OLDDBM
  902. X      store (dbkey, data);
  903. X#else
  904. X      (void) dbm_store (db, dbkey, data, DBM_REPLACE);
  905. X#endif
  906. X    }
  907. X
  908. X  /* build key for new entry */
  909. X  bpkey->af_ldes = list;
  910. X  bpkey->af_lpos = freepos;
  911. X
  912. X  if (oldkey != newkey)
  913. X    {
  914. X      /* copy attribute buffers */
  915. X      VATTR(bpkey) = VATTR(newkey);
  916. X      /* copy hash table */
  917. X      (void) af_hashinit (&(VATTR(newkey).af_uhtab), AF_MAXUDAS, af_fhash);
  918. X      (void) af_hashcopy (&(VATTR(bpkey).af_uhtab), &(VATTR(newkey).af_uhtab));
  919. X    }
  920. X
  921. X  /* if an "add" was performed -- update bplist in database */
  922. X  if (add)
  923. X    {
  924. X      listsize++;
  925. X      list->af_nrevs++;
  926. X#ifdef OLDDBM
  927. X      (void) pbpsize (list->af_nrevs, owner);
  928. X#else
  929. X      (void) pbpsize (db, list->af_nrevs, owner);
  930. X#endif
  931. X    }
  932. X  
  933. X#ifndef OLDDBM
  934. X  dbm_close (db);
  935. X#endif
  936. X  return (AF_OK);
  937. X} /* af_rplbpentry */
  938. X
  939. X
  940. X/*==========================================================================
  941. X *    af_isbpfile
  942. X *
  943. X *==========================================================================*/
  944. X
  945. XEXPORT af_isbpfile (name)
  946. X     char *name;
  947. X{
  948. X  return (!strncmp (name, AF_BPFILEID, AF_IDSTRLEN));
  949. X}
  950. X
  951. X
  952. X
  953. X/*==========================================================================
  954. X *    af_detbpool
  955. X *
  956. X *==========================================================================*/
  957. X
  958. XEXPORT af_detbpool (list)
  959. X     Af_revlist *list;
  960. X{
  961. X  register int i;
  962. X  Af_revlist *tmplist;
  963. X
  964. X  /* if first list descriptor should be deleted - the base (af_lists) */
  965. X  /* has to be preserved */
  966. X  if (list == bplists)
  967. X    bplists = bplists->af_next;
  968. X  else
  969. X    {
  970. X      /* if archive list has more than one entry -- close gap in list */
  971. X      if ((tmplist = bplists) != (Af_revlist *)0)
  972. X    {
  973. X      while (tmplist->af_next != list)
  974. X        if ((tmplist = tmplist->af_next) == (Af_revlist *)0)
  975. X          FAIL ("detbpool", "binary pool lost", AF_EINTERNAL, ERROR);
  976. X      tmplist->af_next = list->af_next;
  977. X    }
  978. X    }
  979. X
  980. X  /* remove list from hash table */
  981. X  (void) af_delsym (&bphash, list->af_cattrs.af_syspath, list);
  982. X
  983. X  /* hang free entry at the beginning of freelist */
  984. X  list->af_next = bpfreelist;
  985. X  bpfreelist = list;
  986. X
  987. X  /* free all allocated memory */
  988. X  for (i = 0; i < list->af_listlen; i++)
  989. X    {
  990. X      if (list->af_list[i].af_class & AF_VALID)
  991. X    af_hashfree (&(list->af_list[i].af_uhtab));
  992. X    }
  993. X  af_frmemlist (list);
  994. X
  995. X  return (AF_OK);
  996. X}
  997. X
  998. END_OF_FILE
  999. if test 26801 -ne `wc -c <'src/afs/afbpool.c'`; then
  1000.     echo shar: \"'src/afs/afbpool.c'\" unpacked with wrong size!
  1001. fi
  1002. # end of 'src/afs/afbpool.c'
  1003. fi
  1004. echo shar: End of archive 23 \(of 33\).
  1005. cp /dev/null ark23isdone
  1006. MISSING=""
  1007. 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
  1008.     if test ! -f ark${I}isdone ; then
  1009.     MISSING="${MISSING} ${I}"
  1010.     fi
  1011. done
  1012. if test "${MISSING}" = "" ; then
  1013.     echo You have unpacked all 33 archives.
  1014.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1015. else
  1016.     echo You still need to unpack the following archives:
  1017.     echo "        " ${MISSING}
  1018. fi
  1019. ##  End of shell archive.
  1020. exit 0
  1021.