rsalz@uunet.uu.net (Rich Salz) (06/07/89)
Submitted-by: Axel Mahler <unido!coma!axel> Posting-number: Volume 19, Issue 36 Archive-name: shape/part23 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 23 (of 33)." # Contents: src/afs/afbpool.c # Wrapped by rsalz@papaya.bbn.com on Thu Jun 1 19:27:15 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'src/afs/afbpool.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/afs/afbpool.c'\" else echo shar: Extracting \"'src/afs/afbpool.c'\" \(26801 characters\) sed "s/^X//" >'src/afs/afbpool.c' <<'END_OF_FILE' X/* X * Copyright (C) 1989, 1990 W. Koch, A. Lampen, A. Mahler, W. Obst, X * and U. Pralle X * X * This software is published on an as-is basis. There is ABSOLUTELY NO X * WARRANTY for any part of this software to work correctly or as described X * in the manuals. We do not accept any liability for any kind of damage X * caused by use of this software, such as loss of data, time, money, or X * effort. X * X * Permission is granted to use, copy, modify, or distribute any part of X * this software as long as this is done without asking for charge, and X * provided that this copyright notice is retained as part of the source X * files. You may charge a distribution fee for the physical act of X * transferring a copy, and you may at your option offer warranty X * protection in exchange for a fee. X * X * Direct questions to: Tech. Univ. Berlin X * Wilfried Koch X * Sekr. FR 5-6 X * Franklinstr. 28/29 X * D-1000 Berlin 10, West Germany X * X * Tel: +49-30-314-22972 X * E-mail: shape@coma.uucp or shape@db0tui62.bitnet X */ X/* X * Shape/AFS X * X * afbpool.c -- read/write binary-pool control files (ndbm version) X * X * Author: Andreas Lampen, TU-Berlin (andy@coma.UUCP) X * (andy@db0tui62.BITNET) X * X * $Header: afbpool.c[1.5] Wed Feb 22 16:27:14 1989 andy@coma published $ X * X * EXPORT: X * af_rbplist -- read list of files in binary pool X * af_delbpentry -- delete file entry in binary pool X * af_rplbpentry -- replace file entry in binary pool X * af_isbpfile -- see if a given file belongs to binary pool X * af_detbpool -- detach binary pool X */ X X#include <stdio.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <sys/dir.h> X#include <sys/file.h> X#include <sys/time.h> X#include <string.h> X#ifdef SUNOS_4_0 X#include <strings.h> X#endif X#ifdef OLDDBM X#undef NULL X#include <dbm.h> X#undef NULL X#else X#include <ndbm.h> X#endif X X#include "typeconv.h" X#include "afsys.h" X#include "afs.h" X#include "afarchive.h" X X#ifdef MEMDEBUG Xextern FILE *memprot; X#endif X X/*========================================================================== X * definition of binary pool revision list X * plus hashtable for faster access X * X *==========================================================================*/ X XLOCAL Af_revlist bplst; X /* base address of all binary pool list descriptors */ XLOCAL Af_revlist *bplists = (Af_revlist *)0; X /* base address of freelist for binary pool list descriptors */ XLOCAL Af_revlist *bpfreelist = &bplst; /* beginning of freelist */ X XLOCAL Af_hash bphash; X XLOCAL Af_revlist *initlist (path, mode) X char *path; X int mode; X{ X static bool hinit = FALSE; /* indicate if hashtable is yet initialized */ X int af_fhash(); X register i; X Af_revlist *list, *oldlist, **oldptr, *tail; X char *malloc(), *pathsym, *arname; X X oldptr = &oldlist; X /* init hashtable if it is not yet done */ X if (!hinit) X { X (void) af_hashinit (&bphash, AF_MAXLISTS, af_fhash); X hinit = TRUE; X } X X pathsym = af_entersym (path); X X /* if there are open archives check if desired archive is loaded yet */ X if (bplists != (Af_revlist *)0) X { X if (af_symlookup (&bphash, path, (Af_revlist *)0, oldptr)) X { X /* found something */ X /* if it is the right list */ X if (oldlist->af_cattrs.af_syspath == pathsym) X return (oldlist); X /* else continue the search as long as there are entries */ X while (af_symlookup (&bphash, path, oldlist, oldptr)) X { X if (oldlist->af_cattrs.af_syspath == pathsym) X return (oldlist); X } X } X } X X /* check if AFS subdirectory exists */ X if ((arname = af_gbpname (path)) == (char *)0) X { X if (mode == AF_READ) X SFAIL ("initlist", "", AF_ENOAFSDIR, (Af_revlist *)0) X else X FAIL ("initlist", "", AF_ENOAFSDIR, (Af_revlist *)0); X } X X /* if there are no more descriptors available - allocate new space */ X if (bpfreelist == (Af_revlist *)0) X { X if ((bpfreelist = (Af_revlist *) malloc ((unsigned) (AF_LISTSEG * sizeof (Af_revlist)))) == (Af_revlist *)0) X FAIL ("initlist", "malloc(i)", AF_ESYSERR, (Af_revlist *)0); X X /* build up new freelist */ X for (i=1; i<AF_LISTSEG; i++) X bpfreelist[i-1].af_next = &(bpfreelist[i]); X bpfreelist[AF_LISTSEG-1].af_next = (Af_revlist *)0; X } X X if (bplists != (Af_revlist *)0) X { X tail = bplists->af_next; X bplists->af_next = bpfreelist; X bpfreelist = bpfreelist->af_next; X list = bplists->af_next; X bzero ((char *)list, sizeof (*list)); X X list->af_next = tail; X } X else X { X list = bpfreelist; X bpfreelist = bpfreelist->af_next; X /* initialize whole struct (i.e. set af_next to "nil") */ X bzero ((char *)list, sizeof (*list)); X bplists = list; X } X X list->af_mem = (char *)0; X X /* initialize list structure */ X list->af_cattrs.af_host = af_gethostname (); X list->af_cattrs.af_syspath = pathsym; X list->af_arfilename = arname; X list->af_busyfilename = af_entersym (""); X X list->af_listlen = af_gmaxbpsize (list->af_arfilename); X if ((list->af_list = (Af_vattrs *)af_malloc (list, (unsigned) (list->af_listlen * sizeof(Af_vattrs)))) == (Af_vattrs *)0) X FAIL ("initlist", "malloc", AF_ESYSERR, (Af_revlist *)0); X X bzero ((char *)list->af_list, list->af_listlen * sizeof (Af_vattrs)); X X list->af_extent |= AF_BPOOL; X list->af_extent |= AF_UXWRITE; X list->af_nrevs = 0; X X /* add list to hashtable */ X (void) af_hashsym (&bphash, path, list); X#ifdef MEMDEBUG X fprintf (memprot, "InitBP (%s)\n", path); X#endif X X return (list); X} X X/*========================================================================== X * af_dbmstring -- build dbm string from attrbuf X * X *==========================================================================*/ X XLOCAL datum af_dbmstring (key, size) X Af_key *key; X int size; /* size of dbm key element */ X{ X static datum data; X static char string[MAXDBMLEN]; X char *ptrlist[AF_MAXUDAS], *udaptr; X register i; X int maxstrlen; X X data.dptr = string; X X /* enter all relevant attributes */ X#ifdef ULTRIX_2_0 X (void) sprintf (string, "%s %s %s %s %d %d %s %s \0", X CATTR(key).af_host, CATTR(key).af_syspath, VATTR(key).af_name, X NOTMT (VATTR(key).af_type), VATTR(key).af_gen, VATTR(key).af_rev, X NOTMT (VATTR(key).af_variant), VATTR(key).af_auname); X (void) sprintf (&string[strlen(string)], "%s %o %d %d %d %d \0", X VATTR(key).af_auhost, VATTR(key).af_mode, VATTR(key).af_fsize, X VATTR(key).af_mtime, VATTR(key).af_atime, VATTR(key).af_ctime); X#else X (void) sprintf (string, "%s %s %s %s %d %d %s %s %s %o %d %d %d %d \0", X CATTR(key).af_host, CATTR(key).af_syspath, VATTR(key).af_name, X NOTMT (VATTR(key).af_type), VATTR(key).af_gen, VATTR(key).af_rev, X NOTMT (VATTR(key).af_variant), VATTR(key).af_auname, X VATTR(key).af_auhost, VATTR(key).af_mode, VATTR(key).af_fsize, X VATTR(key).af_mtime, VATTR(key).af_atime, VATTR(key).af_ctime); X#endif X (void) strcat (string, AF_UDAID); X data.dsize = strlen (data.dptr) + sizeof (char); X X /* add user defined attributes */ X (void) af_lhashsyms (&(VATTR(key).af_uhtab), ptrlist); X i=0; X udaptr = string; X maxstrlen = (MAXDBMLEN - DBMLOSS) - size; X while (ptrlist[i]) X { X if ((data.dsize += ((strlen (ptrlist[i])) + sizeof (char))) >= maxstrlen) X { X data.dptr = (char *)0; X FAIL ("dbmstring", "", AF_ETOOLONG, data); X } X udaptr = &udaptr[strlen(udaptr)+1]; X (void) strcpy (udaptr, ptrlist[i]); X i++; X } X X udaptr[strlen(udaptr)+1] = '\0'; X data.dsize++; X X return (data); X} /* end af_dbmstring */ X X/*=================================================================== X * af_dbmkey -- build attrbuf from dbm entry X *===================================================================*/ X XLOCAL af_dbmkey (data, dbmkey, afkey) X datum *data, *dbmkey; X Af_key *afkey; X{ X char name[MAXNAMLEN], type[MAXTYPLEN], variant[MAXVARLEN], *udaptr; X char host[MAXHOSTNAMELEN], syspath[MAXNAMLEN*4]; X char auhost[MAXHOSTNAMELEN], auname[MAXNAMLEN]; X int af_fhash(); X X /* do initializations */ X VATTR(afkey).af_state = AF_NOSTATE; X VATTR(afkey).af_class = AF_DERIVED | AF_VALID; X VATTR(afkey).af_stime = AF_NOTIME; X VATTR(afkey).af_lckname = (char *)0; X VATTR(afkey).af_lckhost = (char *)0; X VATTR(afkey).af_ltime = AF_NOTIME; X VATTR(afkey).af_notesize = 0; X VATTR(afkey).af_note = (char *)0; X VATTR(afkey).af_repr = AF_FILE; X VATTR(afkey).af_dsize = 0; X VATTR(afkey).af_data = (char *)0; X VATTR(afkey).af_nlinks = 0; X VATTR(afkey).af_succgen = AF_NOVNUM; X VATTR(afkey).af_succrev = AF_NOVNUM; X VATTR(afkey).af_predgen = AF_NOVNUM; X VATTR(afkey).af_predrev = AF_NOVNUM; X X (void) sscanf (data->dptr, "%s%s%s%s%ld%ld%s%s%s%ho%ld%ld%ld%ld", X host, syspath, name, type, X &(VATTR(afkey).af_gen), &(VATTR(afkey).af_rev), X variant, auname, auhost, &(VATTR(afkey).af_mode), X &(VATTR(afkey).af_fsize), &(VATTR(afkey).af_mtime), X &(VATTR(afkey).af_atime),&(VATTR(afkey).af_ctime)); X X /* check plausibility of host and syspath */ X if (strcmp (host, CATTR(afkey).af_host) || X strcmp (syspath, CATTR(afkey).af_syspath)) X af_wng ("dbmkey", "location of bpool possibly not correct"); X X if (!strcmp (type, AF_NOSTRING)) X type[0] = '\0'; X if (!strcmp (variant, AF_NOSTRING)) X variant[0] = '\0'; X X VATTR(afkey).af_name = af_entersym (name); X X if (type[0]) X VATTR(afkey).af_type = af_entersym (type); X else X VATTR(afkey).af_type = (char *)0; X X if (variant[0]) X VATTR(afkey).af_variant = af_entersym (variant); X else X VATTR(afkey).af_variant = (char *)0; X X VATTR(afkey).af_auname = af_entersym (auname); X VATTR(afkey).af_auhost = af_enterhost (auhost); X VATTR(afkey).af_hashname = af_entersym (dbmkey->dptr); X X /* read user defined attributes */ X X udaptr = rindex (data->dptr, AF_UDAID[0]); X if (strcmp (udaptr, AF_UDAID)) X { X /* this should not happen very often */ X udaptr = index (data->dptr, AF_UDAID[0]); X while ((udaptr) && (!strcmp (udaptr, AF_UDAID))) X udaptr = index (udaptr, AF_UDAID[0]); X if (!udaptr) X FAIL ("dbmkey", "cannot find udas", AF_EINCONSIST, ERROR); X } X X /* build up hashlist and read user defined attributes */ X if (af_hashinit (&(VATTR(afkey).af_uhtab), AF_MAXUDAS, af_fhash) == ERROR) X return (ERROR); X X udaptr += (AF_IDSTRLEN + sizeof (char)); X while (udaptr[0]) X { X (void) af_hashsym (&(VATTR(afkey).af_uhtab), udaptr, (Af_revlist *)0); X#ifdef MEMDEBUG X fprintf (memprot, "UdaBP (%s)\n", udaptr); X#endif X VATTR(afkey).af_udanum++; X udaptr = (index (udaptr, '\0') + sizeof (char)); X } X return (AF_OK); X} /* end af_dbmkey */ X X/*=================================================================== X * gbpsize -- get binary pool size and owner X *===================================================================*/ X X#ifdef OLDDBM XLOCAL Af_user *gbpsize (size) X#else XLOCAL Af_user *gbpsize (db, size) X DBM *db; X#endif X short *size; X{ X static Af_user owner; X datum data, dbkey; X X static char *stdentryname = AF_BPSTDENTRY; X X dbkey.dptr = stdentryname; X dbkey.dsize = strlen (AF_BPSTDENTRY); X X#ifdef OLDDBM X data = fetch (dbkey); X#else X data = dbm_fetch (db, dbkey); X#endif X if (data.dptr == (char *)0) X { X *size = 0; X return (af_getuser (getuid())); X } X else X { X (void) sscanf (data.dptr, "%hd%s%s", size, owner.af_username,owner.af_userhost); X return (&owner); X } X} X X/*=================================================================== X * pbpsize -- put binary pool size and owner X *===================================================================*/ X X#ifdef OLDDBM XLOCAL pbpsize (size, owner) X#else XLOCAL pbpsize (db, size, owner) X DBM *db; X#endif X int size; X Af_user *owner; X{ X datum data, dbkey; X static char str[32], *stdentryname = AF_BPSTDENTRY; X X dbkey.dptr = stdentryname; X dbkey.dsize = strlen (AF_BPSTDENTRY); X X (void) sprintf (str, "%d %s %s\0", size, owner->af_username, owner->af_userhost); X data.dptr = str; X data.dsize = strlen (str) + sizeof (char); X X#ifdef OLDDBM X store (dbkey, data); X#else X (void) dbm_store (db, dbkey, data, DBM_REPLACE); X#endif X return (AF_OK); X} X X/*================================================================ X * af_lookupbpentry -- see if bpentry is loaded yet X * returns position in list X * X *================================================================*/ X XLOCAL af_lookupbpentry (list, hashname) X Af_revlist *list; X char *hashname; X{ X int i=0, j=0; X X for (; i < list->af_listlen; i++) X { X /* if entry is not valid */ X if (!(list->af_list[i].af_class & AF_VALID)) X continue; X if (!strcmp (list->af_list[i].af_hashname, hashname)) X return (i); X j++; X if (j >= list->af_nrevs) X return (ERROR); X } X FAIL ("lookupbpentry", "cannot find binary pool entry", AF_EINTERNAL, ERROR); X} X X#ifdef OLDDBM Xstatic char *bpool; Xstatic bool bpwrite = FALSE; X#endif X X/*========================================================================== X * af_rbplist -- read all binary pool entries X * X *==========================================================================*/ X XEXPORT Af_revlist *af_rbplist (path) X char *path; X{ X datum dbkey, data; X#ifndef OLDDBM X DBM *db; X#endif X int i=0, count=0; X Af_key entrykey; X Af_revlist *list; X Af_user *owner; X X if ((list = initlist (path, AF_READ)) == (Af_revlist *)0) X return ((Af_revlist *)0); X X if (list->af_extent & AF_COMPLETE) X return (list); X X#ifdef OLDDBM X if (list->af_arfilename != bpool) X { X char bpfilename[MAXNAMLEN+1]; X FILE *tmpfdes; X /* test existence of binary pool files */ X (void) sprintf (bpfilename, "%s.dir\0", list->af_arfilename); X if (af_sysaccess (bpfilename, 0) == -1) X { X if (bpwrite) X { X /* create bpool files */ X tmpfdes = fopen (bpfilename, "w"); X (void) fclose (tmpfdes); X (void) sprintf (bpfilename, "%s.pag\0", list->af_arfilename); X tmpfdes = fopen (bpfilename, "w"); X (void) fclose (tmpfdes); X } X else X SFAIL ("rbplist", "dbm_open", AF_ENOAFSDIR, (Af_revlist *)0); X } X if (dbminit (list->af_arfilename) != AF_OK) X { X (void) af_detbpool (list); X SFAIL ("rbplist", "dbm_open", AF_ENOAFSDIR, (Af_revlist *)0); X } X bpool = list->af_arfilename; X } X#else X if ((db = dbm_open (list->af_arfilename, O_RDONLY, 0664)) == (DBM *)0) X { X (void) af_detbpool (list); X SFAIL ("rbplist", "dbm_open", AF_ENOAFSDIR, (Af_revlist *)0); X } X#endif X X /* if list was empty up to now */ X if (list->af_nrevs == 0) X { X#ifdef OLDDBM X owner = gbpsize (&list->af_nrevs); X#else X owner = gbpsize (db, &list->af_nrevs); X#endif X list->af_cattrs.af_ownname = af_entersym (owner->af_username); X list->af_cattrs.af_ownhost = af_enterhost (owner->af_userhost); X } X else X /* if there are no references to the list, delete all entries and read */ X /* the whole binary pool. This is (hopefully) faster than updating */ X { X if (list->af_refcount == 0) X { X for (i = 0; i < list->af_listlen; i++) X { X if (list->af_list[i].af_class & AF_VALID) X { X af_hashfree (&(list->af_list[i].af_uhtab)); X list->af_list[i].af_class &= ~AF_VALID; X } X } X af_frmemlist (list); X } X } X X i=0; X#ifdef OLDDBM X for (dbkey = firstkey(); dbkey.dptr != NULL; dbkey = nextkey(dbkey)) X#else X for (dbkey = dbm_firstkey(db); dbkey.dptr != NULL; dbkey = dbm_nextkey(db)) X#endif X { X if (!strncmp (dbkey.dptr, AF_BPSTDENTRY, AF_IDSTRLEN)) X continue; X /* if there are existing references to binary pool preserve all */ X /* attribute buffers that are aleady read in and skip used places */ X if (i == list->af_listlen) /* if list is full */ X { X if (af_lookupbpentry (list, dbkey.dptr) != ERROR) X count++; X else /* delete all additional entries in bpool has shrunk */ X { X#ifdef OLDDBM X delete (dbkey); X#else X (void) dbm_delete (db, dbkey); X#endif X (void) af_unlink (af_bpfilename (path, dbkey.dptr)); X } X continue; X } X count++; X if (list->af_refcount > 0) X { X while (list->af_list[i].af_class & AF_VALID) X i++; X if (af_lookupbpentry (list, dbkey.dptr) != ERROR) X continue; X } X#ifdef OLDDBM X data = fetch (dbkey); X#else X data = dbm_fetch (db, dbkey); X#endif X /* check if file exists. If not, ignore this entry */ X /* this check may be omitted in further releases */ X if (af_sysaccess (af_bpfilename (path, dbkey.dptr), 0) == AF_OK) X { X entrykey.af_ldes = list; X entrykey.af_lpos = i; X (void) af_dbmkey (&data, &dbkey, &entrykey); X i++; X } X else X count--; X } X X list->af_nrevs = count; X X /* clear "incomplete" bit */ X list->af_extent |= AF_COMPLETE; X X#ifndef OLDDBM X dbm_close (db); X#endif X return (list); X} X X X/*========================================================================== X * af_delbpentry -- delete binary pool entry X * X *==========================================================================*/ X XEXPORT af_delbpentry (key) X Af_key *key; X{ X datum dbkey; X#ifndef OLDDBM X DBM *db; X#endif X short listsize; X Af_revlist *list; X Af_user *owner; X X if ((list = initlist (CATTR(key).af_syspath, AF_RDWR)) == (Af_revlist *)0) X return (ERROR); X X if (key->af_ldes != list) X FAIL ("delbpentry", "", AF_EINVKEY, ERROR); X X#ifdef OLDDBM X if (list->af_arfilename != bpool) X { X char bpfilename[MAXNAMLEN+1]; X FILE *tmpfdes; X /* test existence of binary pool files */ X (void) sprintf (bpfilename, "%s.dir\0", list->af_arfilename); X if (af_sysaccess (bpfilename, 0) == -1) X { X /* create bpool files */ X tmpfdes = fopen (bpfilename, "w"); X (void) fclose (tmpfdes); X (void) sprintf (bpfilename, "%s.pag\0", list->af_arfilename); X tmpfdes = fopen (bpfilename, "w"); X (void) fclose (tmpfdes); X } X if (dbminit (list->af_arfilename) != AF_OK) X { X (void) af_detbpool (list); X FAIL ("delbpentry", "dbm_open", AF_ESYSERR, ERROR); X } X bpool = list->af_arfilename; X } X#else X if ((db = dbm_open (list->af_arfilename, O_RDWR|O_CREAT, 0664)) == (DBM *)0) X { X (void) af_detbpool (list); X FAIL ("delbpentry", "dbm_open", AF_ESYSERR, ERROR); X } X#endif X X dbkey.dptr = VATTR(key).af_hashname; X dbkey.dsize = strlen (dbkey.dptr) + sizeof (char); X#ifdef OLDDBM X delete (dbkey); X#else X (void) dbm_delete (db, dbkey); X#endif X (void) af_unlink (af_bpfilename (CATTR(key).af_syspath, VATTR(key).af_hashname)); X#ifdef OLDDBM X owner = gbpsize (&listsize); X#else X owner = gbpsize (db, &listsize); X#endif X list->af_cattrs.af_ownname = af_entersym (owner->af_username); X list->af_cattrs.af_ownhost = af_enterhost (owner->af_userhost); X listsize--; X list->af_nrevs--; X#ifdef OLDDBM X (void) pbpsize (list->af_nrevs, owner); X#else X (void) pbpsize (db, list->af_nrevs, owner); X#endif X X /* clear "valid" bit in attribute buffer and free allocated memory */ X af_hashfree (&(VATTR(key).af_uhtab)); X VATTR(key).af_class &= ~AF_VALID; X X#ifndef OLDDBM X dbm_close (db); X#endif X return (AF_OK); X} X X X/*========================================================================== X * af_rplbpentry -- replace binary pool entry X * X *==========================================================================*/ X XEXPORT af_rplbpentry (oldkey, newkey, bpkey) X Af_key *oldkey, *newkey, *bpkey; X{ X datum dbkey, data; X#ifndef OLDDBM X DBM *db; X#else X datum exdata; X#endif X bool add = FALSE, found = FALSE; X short freepos, listsize, i; X Af_revlist *list; X Af_user *owner; X time_t lastacc; X struct timeval tvp[2]; X char *bpname; X int af_fhash(); X X if ((list = initlist (CATTR(newkey).af_syspath, AF_RDWR)) == (Af_revlist *)0) X return (ERROR); X X if ((oldkey != (Af_key *)0) && (oldkey->af_ldes != list)) X FAIL ("rplbpentry", "", AF_EINVKEY, ERROR); X X#ifdef OLDDBM X if (list->af_arfilename != bpool) X { X char bpfilename[MAXNAMLEN+1]; X FILE *tmpfdes; X /* test existence of binary pool files */ X (void) sprintf (bpfilename, "%s.dir\0", list->af_arfilename); X if (af_sysaccess (bpfilename, 0) == -1) X { X /* create bpool files */ X tmpfdes = fopen (bpfilename, "w"); X (void) fclose (tmpfdes); X (void) sprintf (bpfilename, "%s.pag\0", list->af_arfilename); X tmpfdes = fopen (bpfilename, "w"); X (void) fclose (tmpfdes); X } X if (dbminit (list->af_arfilename) != AF_OK) X { X (void) af_detbpool (list); X FAIL ("rplbpentry", "dbm_open", AF_ESYSERR, ERROR); X } X bpool = list->af_arfilename; X } X#else X if ((db = dbm_open (list->af_arfilename, O_RDWR|O_CREAT, 0664)) == (DBM *)0) X { X (void) af_detbpool (list); X FAIL ("rplbpentry", "dbm_open", AF_ESYSERR, ERROR); X } X#endif X X if (oldkey == (Af_key *)0) X { X /* if we actually have to "add" a file */ X#ifdef OLDDBM X owner = gbpsize (&listsize); X#else X owner = gbpsize (db, &listsize); X#endif X list->af_cattrs.af_ownname = af_entersym (owner->af_username); X list->af_cattrs.af_ownhost = af_enterhost (owner->af_userhost); X if (listsize < list->af_listlen) X { X add = TRUE; X /* look for free attribute buffer in bplist */ X freepos = list->af_listlen-1; X while ((list->af_list[freepos].af_class & AF_VALID) && (freepos >=0)) X freepos--; X if (freepos == -1) X { X#ifndef OLDDBM X dbm_close (db); X#endif X FAIL ("rplbpentry", "no free entry in binary pool", AF_EINCONSIST, ERROR); X } X } X else X { X /* remove the oldest (->af_atime) file */ X /* read in whole list of bpfiles */ X#ifdef OLDDBM X bpwrite = TRUE; X#endif X if ((list = af_rbplist (list->af_cattrs.af_syspath)) X == (Af_revlist *)0) X return (ERROR); X#ifdef OLDDBM X bpwrite = FALSE; X#endif X X lastacc = (time_t)af_acttime (); X X for (i=0; i < list->af_nrevs; i++) X { X if ((!list->af_list[i].af_nlinks) && X (list->af_list[i].af_atime < lastacc)) X { X freepos = i; X lastacc = list->af_list[freepos].af_atime; X dbkey.dptr = list->af_list[freepos].af_hashname; X found = TRUE; X } X } X X if (!found) X FAIL ("rplbpentry", "", AF_EBPFULL, ERROR); X X dbkey.dsize = strlen (dbkey.dptr) + sizeof (char); X#ifdef OLDDBM X delete (dbkey); X#else X (void) dbm_delete (db, dbkey); X#endif X if (oldkey != newkey) X (void) af_unlink (af_bpfilename (list->af_cattrs.af_syspath, dbkey.dptr)); X } X } /* if (oldkey == (Af_key *)0) then ... */ X else X { X if (oldkey != newkey) X { X dbkey.dptr = VATTR(oldkey).af_hashname; X dbkey.dsize = strlen (dbkey.dptr) + sizeof (char); X#ifdef OLDDBM X delete (dbkey); X#else X (void) dbm_delete (db, dbkey); X#endif X (void) af_unlink (af_bpfilename (CATTR(oldkey).af_syspath, dbkey.dptr)); X } X freepos = oldkey->af_lpos; X } X X /* enter new entry */ X if (oldkey != newkey) X { X i = 0; X do X { X if (++i > list->af_listlen) X FAIL ("rplbpentry", X "cannot build unique hashname", AF_EINTERNAL, ERROR); X dbkey.dptr = X af_rbphashname (VATTR(newkey).af_name,VATTR(newkey).af_type, X VATTR(newkey).af_gen, VATTR(newkey).af_rev, X VATTR(newkey).af_variant, newkey->af_ldes, i); X dbkey.dsize = strlen (dbkey.dptr) + sizeof (char); X data = af_dbmstring (newkey, dbkey.dsize); X if (data.dptr == (char *)0) X return (ERROR); X#ifdef OLDDBM X exdata = fetch (dbkey); X#endif X } X /* as long as key is not unique, try another one */ X#ifdef OLDDBM X while (exdata.dptr); X store (dbkey, data); X#else X while (dbm_store (db, dbkey, data, DBM_INSERT)); X#endif X X VATTR(newkey).af_hashname = dbkey.dptr; X X /*** copy file ***/ X bpname = af_bpfilename (CATTR(newkey).af_syspath, VATTR(newkey).af_hashname); X if (af_cpfile (newkey->af_ldes->af_busyfilename, VATTR(newkey).af_fsize, bpname) == ERROR) X FAIL ("rplbpentry", "cpfile", AF_ESYSERR, ERROR); X /*** set modification and access date (not necessary) ***/ X tvp[0].tv_sec = VATTR(newkey).af_atime; X tvp[0].tv_usec = 0; X tvp[1].tv_sec = VATTR(newkey).af_mtime; X tvp[1].tv_usec = 0; X if (utimes (bpname, tvp) == ERROR) X FAIL ("rplbpentry", "utimes", AF_ESYSERR, ERROR); X (void) af_uchmod (bpname, (int) VATTR(newkey).af_mode); X } X else X { X dbkey.dptr = VATTR(newkey).af_hashname; X dbkey.dsize = strlen (dbkey.dptr) + sizeof (char); X data = af_dbmstring (newkey, dbkey.dsize); X if (data.dptr == (char *)0) X return (ERROR); X#ifdef OLDDBM X store (dbkey, data); X#else X (void) dbm_store (db, dbkey, data, DBM_REPLACE); X#endif X } X X /* build key for new entry */ X bpkey->af_ldes = list; X bpkey->af_lpos = freepos; X X if (oldkey != newkey) X { X /* copy attribute buffers */ X VATTR(bpkey) = VATTR(newkey); X /* copy hash table */ X (void) af_hashinit (&(VATTR(newkey).af_uhtab), AF_MAXUDAS, af_fhash); X (void) af_hashcopy (&(VATTR(bpkey).af_uhtab), &(VATTR(newkey).af_uhtab)); X } X X /* if an "add" was performed -- update bplist in database */ X if (add) X { X listsize++; X list->af_nrevs++; X#ifdef OLDDBM X (void) pbpsize (list->af_nrevs, owner); X#else X (void) pbpsize (db, list->af_nrevs, owner); X#endif X } X X#ifndef OLDDBM X dbm_close (db); X#endif X return (AF_OK); X} /* af_rplbpentry */ X X X/*========================================================================== X * af_isbpfile X * X *==========================================================================*/ X XEXPORT af_isbpfile (name) X char *name; X{ X return (!strncmp (name, AF_BPFILEID, AF_IDSTRLEN)); X} X X X X/*========================================================================== X * af_detbpool X * X *==========================================================================*/ X XEXPORT af_detbpool (list) X Af_revlist *list; X{ X register int i; X Af_revlist *tmplist; X X /* if first list descriptor should be deleted - the base (af_lists) */ X /* has to be preserved */ X if (list == bplists) X bplists = bplists->af_next; X else X { X /* if archive list has more than one entry -- close gap in list */ X if ((tmplist = bplists) != (Af_revlist *)0) X { X while (tmplist->af_next != list) X if ((tmplist = tmplist->af_next) == (Af_revlist *)0) X FAIL ("detbpool", "binary pool lost", AF_EINTERNAL, ERROR); X tmplist->af_next = list->af_next; X } X } X X /* remove list from hash table */ X (void) af_delsym (&bphash, list->af_cattrs.af_syspath, list); X X /* hang free entry at the beginning of freelist */ X list->af_next = bpfreelist; X bpfreelist = list; X X /* free all allocated memory */ X for (i = 0; i < list->af_listlen; i++) X { X if (list->af_list[i].af_class & AF_VALID) X af_hashfree (&(list->af_list[i].af_uhtab)); X } X af_frmemlist (list); X X return (AF_OK); X} X END_OF_FILE if test 26801 -ne `wc -c <'src/afs/afbpool.c'`; then echo shar: \"'src/afs/afbpool.c'\" unpacked with wrong size! fi # end of 'src/afs/afbpool.c' fi echo shar: End of archive 23 \(of 33\). cp /dev/null ark23isdone MISSING="" 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 if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 33 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.