home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume19
/
shape
/
part16
< prev
next >
Wrap
Text File
|
1989-05-31
|
48KB
|
1,825 lines
Subject: v19i029: A software configuration management system, Part16/33
Newsgroups: comp.sources.unix
Sender: sources
Approved: rsalz@uunet.UU.NET
Submitted-by: Axel Mahler <unido!coma!axel>
Posting-number: Volume 19, Issue 29
Archive-name: shape/part16
#! /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 16 (of 33)."
# Contents: src/afs/afenviron.c src/misc/citeattr.c src/vc/vlmisc.c
# Wrapped by rsalz@papaya.bbn.com on Thu Jun 1 19:27:08 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/afs/afenviron.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/afs/afenviron.c'\"
else
echo shar: Extracting \"'src/afs/afenviron.c'\" \(15493 characters\)
sed "s/^X//" >'src/afs/afenviron.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/*LINTLIBRARY*/
X/*
X * Shape/AFS
X *
X * afenviron.c -- communication with the UNIX-Filesystem
X *
X * Author: Andreas Lampen, TU-Berlin (andy@coma.UUCP)
X * (andy@db0tui62.BITNET)
X *
X * $Header: afenviron.c[1.6] Wed Feb 22 16:27:29 1989 andy@coma published $
X *
X * EXPORT:
X * af_uniqpath -- build unified pathname
X * af_setarchpath -- name directory where archives shall be stored
X * af_isarchive -- test if a given file is an archive
X * af_garname -- build name for archive file
X * af_garown -- get owner of archive file
X * af_gbpname -- build name for binary pool db-file
X * af_gtmpname -- build name for tmp file
X * af_gbusname -- build name of busy version
X * af_afpath -- build af-syspath from UNIX-filename
X * af_afname -- build af-filename from UNIX-filename
X * af_aftype -- build af-filetype from UNIX-filename
X * af_unixname -- build UNIX-filename from af-filename/type
X * af_gmaxbpsize -- get max. number of files in binary pool
X * af_bpfilename -- return filename for binary pool file
X * af_rbphashname -- get unique filename for file in binary pool
X * af_getuid -- returns uid of user if from local host
X * af_getgid -- returns gid of user if from local host
X * af_getuser -- returns name and host of caller
X */
X
X#include <stdio.h>
X#include <pwd.h>
X#include <string.h>
X#ifdef SUNOS_4_0
X#include <strings.h>
X#endif
X#include <sys/file.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#include "typeconv.h"
X#include "afsys.h"
X#include "afs.h"
X#include "afarchive.h"
X
Xchar *malloc();
X
X/*================================================================
X * af_uniqpath -- build unified pathname
X *
X *================================================================*/
X
XEXPORT char *af_uniqpath (path)
X char *path;
X{
X static char uniqpath[4*MAXNAMLEN], tmppath[4*MAXNAMLEN];
X char *p, *u, *getwd();
X
X if ((path == (char *)0) || (path[0] == '\0') || ((path[0] == '.' && path[1] == '\0')))
X return (getwd (uniqpath));
X
X /* build absolute pathname if only a relative one is given */
X if (path[0] != '/')
X {
X if (!strcmp (path, ".."))
X {
X (void) getwd (uniqpath);
X if ((p = rindex (uniqpath, '/')) == uniqpath)
X uniqpath[1] = '\0';
X else
X *p = '\0';
X return (uniqpath);
X }
X (void) getwd (tmppath);
X (void) strcat (tmppath, "/");
X (void) strcat (tmppath, path);
X p = tmppath;
X }
X else
X p = path;
X
X /* eliminate things like "/usr/./bin" and "/usr/../usr/bin" */
X u = uniqpath;
X *u = '/';
X while (*p)
X {
X if ((p[0] == '/') && (p[1] == '.'))
X {
X if ((p[2] == '/') || (p[2] == '\0'))
X {
X p = &p[2];
X continue;
X }
X else
X if ((p[2] == '.') && ((p[3] == '/') || (p[3] == '\0')))
X {
X if (u != uniqpath)
X do { *u = '\0'; u--; } while (*u != '/');
X p = &p[3];
X continue;
X }
X }
X u++;
X *u = p[1];
X p++;
X }
X
X /* cut slash if present at the end */
X u--;
X if ((u != uniqpath) && (*u == '/'))
X *u = '\0';
X else
X u[1] = '\0';
X
X return (uniqpath);
X}
X
Xstatic char archpath[4*MAXNAMLEN] = "\0";
X
X/*================================================================
X * af_setarchpath
X *
X *================================================================*/
X
XEXPORT af_setarchpath (pathname)
X char *pathname;
X{
X if (pathname == (char *)0)
X archpath[0] = '\0';
X else
X (void) strcpy (archpath, af_uniqpath (pathname));
X}
X
X
X/*====================================================================
X * af_isarchive -- test if a given file is an archive
X *
X *====================================================================*/
X
XEXPORT af_isarchive (name)
X char *name;
X{
X char ext;
X
X if (!name || strncmp (name, AF_AFSFILEID, AF_IDSTRLEN))
X return (FALSE);
X
X ext = name[strlen (name) - sizeof (char)];
X if ((ext != AF_ARCHEXT) && (ext != AF_DATAEXT))
X return (FALSE);
X
X return (TRUE);
X}
X
X
X/*================================================================
X * af_garname
X *
X *================================================================*/
X
XEXPORT char *af_garname (pathname, name, type)
X char *pathname;
X char *name, *type;
X{
X char arname[MAXNAMLEN*4];
X
X /* see if there is an explicit pathname where archives shall be stored */
X if (archpath[0])
X (void) strcpy (arname, archpath);
X else
X (void) sprintf (arname, "%s/%s\0", NOTNIL(pathname), AF_SUBDIR);
X
X if ((type != (char *)0) && (type[0] != '\0'))
X (void) sprintf (&arname[strlen (arname)], "/%s%s.%s%c\0",
X AF_AFSFILEID, NOTNIL(name), NOTNIL(type), AF_ARCHEXT);
X else
X (void) sprintf (&arname[strlen (arname)], "/%s%s%c\0",
X AF_AFSFILEID, NOTNIL(name), AF_ARCHEXT);
X
X return (af_entersym (arname));
X} /* af_garname */
X
X
X/*================================================================
X * af_garown
X *
X *================================================================*/
X
XEXPORT Af_user *af_garown (archname, writeok)
X char *archname;
X bool *writeok; /* out */
X{
X char ardirname[MAXNAMLEN*4], *namptr;
X struct stat ibuf;
X
X /* build name of directory, where the archive is located */
X (void) strcpy (ardirname, archname);
X
X /* cut name */
X namptr = rindex (ardirname, '/');
X *namptr = '\0';
X
X *writeok = FALSE;
X if (stat (ardirname, &ibuf) == ERROR)
X return ((Af_user *)0);
X else
X if (!af_sysaccess (ardirname, W_OK))
X *writeok = TRUE;
X
X return (af_getuser (ibuf.st_uid));
X} /* af_garown */
X
X
X/*================================================================
X * af_gbpname
X *
X *================================================================*/
X
XEXPORT char *af_gbpname (pathname)
X char *pathname;
X{
X char bpname[MAXNAMLEN*4];
X
X /* see if there is an explicit pathname where archives shall be stored */
X if (archpath[0])
X (void) strcpy (bpname, archpath);
X else
X (void) sprintf (bpname, "%s/%s/\0", pathname, AF_SUBDIR);
X
X if (af_sysaccess (bpname, R_OK))
X return ((char *)0);
X
X (void) strcat (bpname, AF_BPOOLNAME);
X
X return (af_entersym (bpname));
X} /* af_garname */
X
X
X/*================================================================
X * af_gtmpname
X *
X *================================================================*/
X
Xstatic int count=0;
X
XEXPORT char *af_gtmpname (pathname, filename)
X /*ARGSUSED*/
X char *pathname; /* unused up to now */
X char *filename;
X{
X char tmpname[MAXNAMLEN*4];
X
X (void) sprintf (tmpname, "%s/%s%d%d\0", AF_TMPDIR, filename, getpid(), count++);
X return (af_entersym (tmpname));
X} /* af_gtmpname */
X
X
X/*================================================================
X * af_gbusname
X *
X *================================================================*/
X
XEXPORT char *af_gbusname (pathname, name, type)
X char *pathname;
X char *name, *type;
X{
X char busyname[MAXNAMLEN*4];
X
X (void) sprintf (busyname, "%s/%s", pathname, name);
X if ((type != (char *)0) && (type[0] != '\0'))
X {
X (void) strcat (busyname, ".");
X (void) strcat (busyname, type);
X }
X return (af_entersym (busyname));
X} /* af_gbusname */
X
X
X
X/*================================================================
X * af_afpath
X *
X *================================================================*/
X
XEXPORT char *af_afpath (unixname)
X char *unixname;
X{
X char *nameptr;
X static char afpath[MAXNAMLEN];
X
X if (unixname)
X (void) strcpy (afpath, unixname);
X else
X afpath[0] = '\0';
X
X /* cut name */
X if ((nameptr = rindex (afpath, '/')) != (char *)0)
X nameptr[0] = '\0';
X else
X {
X afpath[0] = '\0';
X return (afpath);
X }
X
X /* cut AFS subdirectory name if present */
X if (((nameptr = rindex (afpath, '/')) != (char *)0) &&
X !strcmp (AF_SUBDIR, nameptr+1))
X nameptr[0] = '\0';
X else
X if (!strcmp (AF_SUBDIR, afpath))
X afpath[0] = '\0';
X
X return (afpath);
X}
X
X/*================================================================
X * af_afname
X *
X *================================================================*/
X
XEXPORT char *af_afname (unixname)
X char *unixname;
X{
X char *typeptr, *nameptr;
X static char afname[MAXNAMLEN];
X
X if (!unixname)
X {
X afname[0] = '\0';
X return (afname);
X }
X
X /* set nameptr to beginning of name */
X if ((nameptr = rindex (unixname, '/')) == (char *)0)
X nameptr = unixname;
X else
X nameptr++;
X
X if (af_isarchive (nameptr))
X {
X (void) strcpy (afname, nameptr + strlen (AF_AFSFILEID));
X afname[strlen (afname) - sizeof (char)] = '\0';
X }
X else
X (void) strcpy (afname, nameptr);
X
X /* special handling for "." and ".." */
X if (!strcmp (afname, ".") || !strcmp (afname, ".."))
X return (afname);
X
X /* if a UNIX type-extension is given -- cut it, except the dot is */
X /* at position 0 (e.g. .cshrc) */
X if ((typeptr = rindex (afname, '.')) != (char *)0)
X if (typeptr != afname)
X typeptr[0] = '\0';
X
X return (afname);
X}
X
X/*================================================================
X * af_aftype
X *
X *================================================================*/
X
XEXPORT char *af_aftype (unixname)
X char *unixname;
X{
X char *typeptr, *nameptr;
X static char aftype[MAXTYPLEN];
X bool isarch = FALSE;
X
X if (!unixname)
X {
X aftype[0] = '\0';
X return (aftype);
X }
X
X /* set nameptr to beginning of name */
X if ((nameptr = rindex (unixname, '/')) == (char *)0)
X nameptr = unixname;
X else
X nameptr++;
X
X if (af_isarchive (nameptr))
X {
X nameptr += strlen (AF_AFSFILEID);
X isarch = TRUE;
X }
X
X /* if there is no UNIX type-extension */
X if ((typeptr = rindex (nameptr, '.')) == (char *)0)
X aftype[0] = '\0';
X else
X {
X /* if the found dot indicates a "hidden file" (eg. .cshrc) */
X if (typeptr == nameptr)
X aftype[0] = '\0';
X else
X {
X (void) strcpy (aftype, typeptr + sizeof(char));
X /* if the named file is an archive, cut the name-extension */
X if (isarch)
X aftype [strlen (aftype) - sizeof (char)] = '\0';
X }
X }
X return (aftype);
X}
X
X
X/*================================================================
X * af_unixname
X *
X *================================================================*/
X
XEXPORT char *af_unixname (path, name, type)
X char *path, *name, *type;
X{
X static char unixname[4*MAXNAMLEN];
X
X if ((path == (char *)0) || (path[0] == '\0'))
X (void) strcpy (unixname, NOTNIL(name));
X else
X (void) sprintf (unixname, "%s/%s\0", path, name);
X
X if ((type != (char *)0) && (type[0] != '\0'))
X {
X (void) strcat (unixname, ".");
X (void) strcat (unixname, type);
X }
X return (unixname);
X}
X
X
X/*================================================================
X * af_gmaxbpsize -- get max. number of files in binary pool
X *
X *================================================================*/
X
XEXPORT int af_gmaxbpsize (name)
X /*ARGSUSED*/
X char *name; /* unused up to now */
X{
X char *envval, *getenv();
X
X if (envval = getenv (AF_ENVBPSIZE))
X return (atoi (envval));
X else
X return AF_MAXBPSIZE;
X}
X
X
X/*================================================================
X * af_bpfilename
X *
X *================================================================*/
X
XEXPORT char *af_bpfilename (pathname, name)
X char *pathname, *name;
X{
X static char bpname[MAXNAMLEN];
X
X (void) sprintf (bpname, "%s/%s/%s\0", pathname, AF_SUBDIR, name);
X return (bpname);
X}
X
X/*================================================================
X * af_rbphashname -- get unique filename for file in binary pool
X *
X *================================================================*/
X
XEXPORT char *af_rbphashname (name, type, gen, rev, variant, list, count)
X char *name, *type, *variant;
X int gen, rev;
X /*ARGSUSED*/
X Af_revlist *list; /* unused up to now */
X int count;
X{
X char hashname[MAXNAMLEN];
X
X (void) sprintf (hashname, "%s%s.%s[%d.%d]%s%d\0", AF_BPFILEID,
X name, type, gen, rev, variant, count);
X
X return (af_entersym (hashname));
X}
X
X
X/*========================================================================
X * af_getuid - returns uid of user if from local host
X * AF_ERROR if user is unknown
X * AF_REMOTE if user is not local
X *
X *========================================================================*/
X
XEXPORT Uid_t af_getuid (name, host)
X char *name, *host;
X{
X struct passwd *pwent;
X
X if (name == (char *)0) /* in this case, name and host are null pointers */
X return ((Uid_t) ERROR);
X
X if (strcmp (af_gethostname(), host))
X return ((Uid_t) AF_REMOTE);
X
X if ((pwent = getpwnam (name)) == (struct passwd *)0)
X FAIL ("getuid", "cannot get user ID", AF_EINTERNAL, (Uid_t) ERROR);
X
X return (pwent->pw_uid);
X}
X
X
X/*========================================================================
X * af_getgid - returns gid of user if from local host
X * AF_ERROR if user is unknown
X * AF_REMOTE if user is not local
X *
X *========================================================================*/
X
XEXPORT Gid_t af_getgid (name, host)
X char *name, *host;
X{
X struct passwd *pwent;
X
X if (name == (char *)0) /* in this case, name and host are null pointers */
X return ((Gid_t) ERROR);
X
X if (strcmp (af_gethostname(), host))
X return ((Gid_t) AF_REMOTE);
X
X if ((pwent = getpwnam (name)) == (struct passwd *)0)
X FAIL ("getgid", "cannot get group ID", AF_EINTERNAL, (Gid_t) ERROR);
X
X return (pwent->pw_gid);
X}
X
X
X/*========================================================================
X * af_getuser - returns name and host of caller
X *
X *========================================================================*/
X
Xstatic Uid_t calleruid;
Xstatic Af_user caller;
Xstatic bool initcaller = FALSE;
X
XEXPORT Af_user *af_getuser (uid)
X Uid_t uid;
X{
X static Af_user result;
X struct passwd *pwent;
X
X if (!initcaller) /* if caller struct is not yet initialized */
X {
X calleruid = getuid();
X (void) strcpy (caller.af_userhost, af_gethostname ());
X if ((pwent = getpwuid ((int) calleruid)) == (struct passwd *)0)
X SFAIL ("getuser", "", AF_EINVUSER, (Af_user *)0);
X (void) strcpy (caller.af_username, pwent->pw_name);
X initcaller = TRUE;
X }
X if (uid == calleruid)
X return (&caller);
X
X (void) strcpy (result.af_userhost, af_gethostname ());
X if ((pwent = getpwuid ((int) uid)) == (struct passwd *)0)
X SFAIL ("getuser", "", AF_EINVUSER, (Af_user *)0);
X (void) strcpy (result.af_username, pwent->pw_name);
X
X return (&result);
X}
END_OF_FILE
if test 15493 -ne `wc -c <'src/afs/afenviron.c'`; then
echo shar: \"'src/afs/afenviron.c'\" unpacked with wrong size!
fi
# end of 'src/afs/afenviron.c'
fi
if test -f 'src/misc/citeattr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/misc/citeattr.c'\"
else
echo shar: Extracting \"'src/misc/citeattr.c'\" \(14280 characters\)
sed "s/^X//" >'src/misc/citeattr.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 */
Xstatic char *AFSid = "$Header: citeattr.c[1.6] Thu Feb 23 21:24:18 1989 axel@coma published $";
X
X/*
X * Log for /u/shape/dist-tape/src/misc/citeattr.c[1.1]
X * Thu Feb 23 21:24:18 1989 axel@coma save $
X * --- empty log message ---
X * citeattr.c[1.2] Thu Feb 23 21:24:18 1989 axel@coma save $
X * --- empty log message ---
X * citeattr.c[1.3] Thu Feb 23 21:24:18 1989 axel@coma save $
X * --- empty log message ---
X * citeattr.c[1.4] Thu Feb 23 21:24:18 1989 axel@coma published $
X * Threw out silly #ifdef BSD43 s.
X * I think there are also other changes concerning attribute citations.
X *
X * citeattr.c[1.5] Thu Feb 23 21:24:18 1989 axel@coma published $
X * --- empty log message ---
X * citeattr.c[1.6] Thu Feb 23 21:24:18 1989 axel@coma published $
X * --- empty log message ---
X */
X
X#include <pwd.h>
X#include <grp.h>
X#include <stdio.h>
X#include <strings.h>
X#include "afs.h"
X#include "afsapp.h"
X#include "anames.h"
X
Xchar *st_table[] = {
X "busy", "save", "proposed",
X "published", "accessed", "frozen",
X (char *)0
X };
X
XWriteXPand (buf, bufcnt, dest, curkey)
X char *buf; int bufcnt; FILE *dest; Af_key *curkey; {
X/*
X * WriteXPand scans the char buffer 'buf' to the extent of bufcnt
X * for strings of the form '$__attribute_name'. If such a string
X * is found, the buffer contents up to the character preceding the
X * first '$' will be sent to the destination output 'dest'.
X * If an attribute with name 'atttribute_name' is set for the current
X * attribute file, the citation-string will be substituted by the value
X * of that attribute. Output of 'buf' contents resumes with the first
X * character after the blank delimiting the 'attribute_name'.
X * There are two built-in pseudo-attributes, 'Header' and 'Log' which
X * are substituted by a version header in RCS style or a log-history
X * respectively. Lines of the log-history are preceded by a 'comment
X * leader' symbol, defined as user-defined attribute CLEAD.
X * Header and Log are ended by newline characters.
X */
X short stat=0, incite=0, gotattrs=0;
X char attrcitebuf[128];
X Af_attrs allattrs;
X register int i, j, k;
X char *bufp = buf, *attrname = attrcitebuf+3,
X *spt, *ept;
X
X i = 0;
X
X spt = ept = buf;
X
X while (i < bufcnt) {
X
X switch (buf[i]) {
X /* scan attribute citation marker */
X case '$':
X if (stat) ept = &(buf[i]);
X stat = 1;
X attrcitebuf[0] = '$';
X break;
X case '_':
X switch (stat) {
X case 0:
X ept++;
X break;
X case 1:
X case 2:
X attrcitebuf[stat++] = '_';
X break;
X }
X break;
X default:
X if (stat)
X ept = &(buf[i+1]);
X else
X ept++;
X stat = 0;
X break;
X }
X
X if (stat == 3) { /* lets see if there's an attribute citation */
X /* assertion: i is index of 2nd '_' */
X if ((i < bufcnt-1) && (buf[i+1] != ' ')) {
X stat = 0;
X /* ... yes, there seems to be one */
X i++; incite = 0;
X if (af_gattrs (curkey, &allattrs) < 0) {
X af_perror ("af_gattrs");
X return;
X }
X gotattrs = 1;
X while ((!index (" \n\t$", buf[i])) && (i < bufcnt))
X attrname[incite++] = buf[i++];
X if (i < bufcnt) {
X /* i points to first char after attribute name */
X if (buf[i] == '$') { /* consider '$' part of attr-name */
X attrname[incite++] = '$'; i++;
X }
X attrname[incite] = '\0';
X /* write out everything up to beginning of cite_mark */
X fwrite (spt, sizeof (*buf), ept - spt, dest);
X spt = ept = &(buf[i]);
X if (!substitute (attrname, curkey, &allattrs, dest))
X fputs (attrcitebuf, dest);
X incite = 0;
X }
X else {
X attrname[incite] = '\0';
X fwrite (spt, sizeof (*buf), ept - spt, dest);
X spt = ept = &(buf[i]);
X if (!substitute (attrname, curkey, &allattrs, dest))
X fputs (attrcitebuf, dest);
X }
X }
X else { /* blank after citemark or buffer exceeded */
X fputs ("$__", dest);
X }
X i--;
X }
X i++;
X }
X /* Ok, we've had it -- send remaining chars to dest */
X fwrite (spt, sizeof (*buf), ept - spt, dest);
X if (gotattrs) {
X i = 0;
X while (allattrs.af_udattrs[i]) free (allattrs.af_udattrs[i++]);
X }
X }
X
X
Xstatic substitute (attrname, afkey, afattrs, dest)
X char *attrname; Af_key *afkey; Af_attrs *afattrs; FILE *dest; {
X /*
X * This procedure tries to substitute the occurrence of the
X * given attribute name by the corresponding value stored with the
X * attribute file version denoted by afkey. The substituted
X * value is printed on dest. If 'attrname' actually is the name
X * of an attribute and the last character in the name is '$'
X * it will be deleted. In case that attrname is not a known
X * attributename, nothing happens and a value of 0, indicating
X * that no substitution took place, will be returned. Nonzero
X * return means successful substitution.
X */
X char *ap, *p, clead[32], *note, *IsAStdAttr();
X register char *lp, *ep, *l;
X Af_attrs retbuf;
X Af_set kset;
X Af_key thiskey;
X int cgen, crev, tgen, setsz, title_printed = FALSE;
X register int k;
X
X if (l = index (attrname, '$')) *l = '\0';
X if (ap = IsAStdAttr (attrname, afattrs)) {
X fputs (ap, dest);
X return TRUE;
X }
X if (strcmp (attrname, HEADER)) {
X if (strcmp (attrname, LOG)) {
X ap = af_rudattr (afkey, attrname);
X if (ap > 0) {
X fputs (ap, dest);
X free (ap);
X return TRUE;
X }
X if (l) *l = '$'; /* restore '$' if 'attrname' unknown */
X return FALSE;
X }
X else { /* fill in the logs */
X /* we've got to find all preceding versions */
X
X af_initattrs (&retbuf);
X strcpy (retbuf.af_syspath, p=af_rsyspath (afkey));
X free (p);
X strcpy (retbuf.af_name, p=af_rname (afkey));
X free (p);
X strcpy (retbuf.af_type, p=af_rtype (afkey));
X free (p);
X af_find (&retbuf, &kset);
X af_sortset (&kset, AF_ATTVERSION);
X cgen = af_rgen (afkey);
X crev = af_rrev (afkey);
X setsz = af_nrofkeys (&kset);
X
X /* determine comment leader sym to prepend it to loglines */
X p = af_rudattr (afkey, CLEAD);
X if (p) {
X strcpy (clead, p);
X }
X else clead[0] = '\0';
X free (p);
X
X /* write log for each version up to current on dest file */
X for (k = 0 ; k < setsz; k++) {
X af_setgkey (&kset, k, &thiskey);
X if (af_rstate (&thiskey) == AF_BUSY)
X continue; /* don't consider busy version */
X if ((tgen = af_rgen (&thiskey)) > cgen)
X break;
X if ((tgen == cgen) && (af_rrev(&thiskey) > crev))
X break;
X if (!title_printed) {
X fprintf (dest, "Log for ");
X putlongheader (&thiskey, dest, clead);
X title_printed = TRUE;
X }
X else { /* each log preceded by version header */
X fprintf (dest, "%s%s", (clead && clead[0]) ? clead : "",
X (clead && clead[0]) ? " " : "");
X putshortheader (&thiskey, dest, TRUE);
X
X }
X note = af_rnote (&thiskey);
X lp = note;
X /* break log text into separate strings */
X /* assertion: lp == 0 if no log or log is printed */
X while (lp) {
X ep = lp;
X while ((*ep != '\n') && (*ep != '\0'))
X ep++;
X if (*ep == '\n') {
X *ep++ = '\0'; /* make it end of an ordinary string */
X fprintf (dest, "%s %s\n", clead, lp);
X /* ...and let it point to next string segment */
X }
X else {
X ep = NULL; /* we're ready */
X if (k < setsz-1) /* handle 'last-newline' problem */
X fprintf (dest, "%s %s\n", clead, lp);
X else
X fprintf (dest, "%s %s", clead, lp);
X }
X lp = ep;
X }
X free (note);
X /* aw rite --- lets go for the next log entry */
X }
X af_dropset (&kset);
X }
X }
X else { /* print standard version header -- do it RCS-style */
X fprintf (dest, "%cHeader: ", '$');
X putshortheader (afkey, dest, FALSE);
X }
X return TRUE;
X }
X
Xstatic char *vnum (key) Af_key *key; {
X int _gen, _rev;
X static char vstr[20];
X
X _gen = af_rgen (key);
X _rev = af_rrev (key);
X
X if (af_rstate (key) == AF_BUSY)
X strcpy (vstr, "busy");
X else
X sprintf (vstr, "%d.%d", _gen, _rev);
X return vstr;
X}
X
X
Xstatic putlongheader (afkey, dest, clead)
X Af_key *afkey; FILE *dest; char *clead; {
X char *spath, *name, *type, *systime(), *UidString(), *csym;
X extern char *st_table[];
X register int i;
X Af_attrs allattrs;
X
X spath = af_rsyspath (afkey);
X name = af_rname (afkey);
X type = af_rtype (afkey);
X af_gattrs (afkey, &allattrs);
X csym = (clead && clead[0]) ? clead : "";
X for (i = 0; allattrs.af_udattrs[i]; i++) free (allattrs.af_udattrs[i]);
X
X fprintf (dest, "%s/%s%s%s[%s]\n%s\t%s %s %s $\n", spath, name,
X type[0] ? "." : "", type, vnum(afkey), csym,
X systime(), UidString (&(allattrs.af_author)),
X st_table[af_rstate(afkey)]);
X free (spath); free (name); free (type);
X}
X
Xstatic putshortheader (afkey, dest, nl)
X Af_key *afkey; FILE *dest; int nl; {
X char *spath, *name, *type, *systime(), *UidString();
X extern char *st_table[];
X register int i;
X Af_attrs allattrs;
X
X spath = af_rsyspath (afkey);
X name = af_rname (afkey);
X type = af_rtype (afkey);
X af_gattrs (afkey, &allattrs);
X for (i = 0; allattrs.af_udattrs[i]; i++) free (allattrs.af_udattrs[i]);
X
X fprintf (dest, "%s%s%s[%s] %s %s %s $%s", name,
X type[0] ? "." : "",type, vnum(afkey),
X systime(), UidString (&(allattrs.af_author)),
X st_table[af_rstate(afkey)], nl ? "\n" : "");
X free (spath); free (name); free (type);
X}
X
Xstatic struct {
X char *name;
X short code;
X} an_tab[] = {
X { "atime", ATIME }, /* 0 */
X { "auuid", AUUID },
X { "ctime", CTIME },
X { "generation", GEN },
X { "host", HOST },
X { "lock", LOCK },
X { "ltime", LTIME },
X { "mode", MODE },
X { "mtime", MTIME },
X { "name", NAME },
X { "ownuid", OWNUID },
X { "revision", REV },
X { "size", SIZE },
X { "stime", STIME },
X { "syspath", SYSPATH },
X { "type", TYPE },
X { "variant", VAR },
X { "version", VERSION },
X { "state", STATE } /* 18 */
X};
X
Xstatic char *IsAStdAttr (attrname, afattrs)
X char *attrname; Af_attrs *afattrs; {
X extern char *st_table[];
X char messg[80], *UidString();
X static char rets[32];
X register int i;
X int anc = 0;
X
X for (i = 0; i < AN_TABSIZ; i++) {
X if (!(strcmp (attrname, an_tab[i].name))) {
X anc = an_tab[i].code;
X break;
X }
X }
X if (anc) {
X switch (anc) {
X case HOST:
X return afattrs->af_host;
X break;
X case SYSPATH:
X return afattrs->af_syspath;
X break;
X case NAME:
X return afattrs->af_name;
X break;
X case TYPE:
X return afattrs->af_type;
X break;
X case GEN:
X if (afattrs->af_state == AF_BUSY) return "nogen";
X else {
X sprintf (rets, "%d", afattrs->af_gen);
X return rets;
X }
X break;
X case REV:
X if (afattrs->af_state == AF_BUSY) return "nogen";
X else {
X sprintf (rets, "%d", afattrs->af_rev);
X return rets;
X }
X break;
X case VERSION:
X if (afattrs->af_state == AF_BUSY) return "busy";
X else {
X sprintf (rets, "%d.%d", afattrs->af_gen, afattrs->af_rev);
X return rets;
X }
X break;
X case VAR:
X return (afattrs->af_variant);
X break;
X case STATE:
X return st_table[afattrs->af_state];
X break;
X case OWNUID:
X return UidString (&(afattrs->af_owner));
X break;
X case AUUID:
X return UidString (&(afattrs->af_author));
X break;
X case SIZE:
X sprintf (rets, "%d", afattrs->af_size);
X return rets;
X break;
X case MODE:
X sprintf (rets, "%o", afattrs->af_mode);
X return rets;
X break;
X case LOCK:
X if (strcmp (afattrs->af_locker.af_username, "")) {
X sprintf (rets, "%s@%s", afattrs->af_locker.af_username,
X afattrs->af_locker.af_userhost);
X return rets;
X }
X return "nobody";
X break;
X case MTIME:
X strcpy (rets, asctime(localtime(&afattrs->af_mtime)));
X rets[strlen(rets) - 1] = '\0';
X return rets;
X break;
X case ATIME:
X strcpy (rets, asctime(localtime(&afattrs->af_atime)));
X rets[strlen(rets) - 1] = '\0';
X return rets;
X break;
X case CTIME:
X strcpy (rets, asctime(localtime(&afattrs->af_ctime)));
X rets[strlen(rets) - 1] = '\0';
X return rets;
X break;
X case STIME:
X if (afattrs->af_state == AF_BUSY) return "no_date";
X else {
X strcpy (rets, asctime(localtime(&afattrs->af_stime)));
X rets[strlen(rets) - 1] = '\0';
X return rets;
X }
X break;
X case LTIME:
X strcpy (rets, asctime(localtime(&afattrs->af_ltime)));
X rets[strlen(rets) - 1] = '\0';
X return rets;
X break;
X default: /* shouldn't happen ! */
X sprintf (messg, "illegal standard attribute code %d.", anc);
X logerr (anc);
X }
X }
X else return NULL; /* no standard attribute */
X}
X
Xchar *UidString (user) Af_user *user; {
X static char rst[256];
X
X rst[0] = '\0';
X if (user) {
X sprintf (rst, "%s@%s", user->af_username, user->af_userhost);
X }
X return rst;
X}
X
Xstatic char *systime () {
X char *asctime();
X register char *ts;
X struct timeval tm;
X struct timezone tz;
X
X gettimeofday (&tm, &tz);
X ts = asctime (localtime (&tm));
X ts[strlen(ts)-1] = '\0';
X return ts;
X}
END_OF_FILE
if test 14280 -ne `wc -c <'src/misc/citeattr.c'`; then
echo shar: \"'src/misc/citeattr.c'\" unpacked with wrong size!
fi
# end of 'src/misc/citeattr.c'
fi
if test -f 'src/vc/vlmisc.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/vc/vlmisc.c'\"
else
echo shar: Extracting \"'src/vc/vlmisc.c'\" \(14112 characters\)
sed "s/^X//" >'src/vc/vlmisc.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#ifndef lint
Xstatic char *AFSid = "$Header: vlmisc.c[3.11] Thu Feb 23 18:14:52 1989 axel@coma published $";
X#ifdef CFFLGS
Xstatic char *ConfFlg = CFFLGS;
X /* should be defined from within Makefile */
X#endif
X#endif
X/*
X * Log for /u/shape/dist-tape/src/vc/vlmisc.c[3.5]
X * Thu Feb 23 18:14:52 1989 axel@coma published $
X * --- empty log message ---
X * vlmisc.c[3.7] Thu Feb 23 18:14:52 1989 uli@coma published $
X * --- empty log message ---
X * vlmisc.c[3.9] Thu Feb 23 18:14:52 1989 axel@coma published $
X * --- empty log message ---
X * vlmisc.c[3.10] Thu Feb 23 18:14:52 1989 axel@coma save $
X * --- empty log message ---
X * vlmisc.c[3.11] Thu Feb 23 18:14:52 1989 axel@coma published $
X * --- empty log message ---
X */
X
X#include <stdio.h>
X#include <pwd.h>
X#include <grp.h>
X#include <strings.h>
X#include <sys/param.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#include <afs.h>
X#include <afsys.h>
X
X#include "vl.h"
X
X/*
X * Global, but not exported variables
X */
X#define VL_MAX_OWNERNAME 7 /* in real life 8 chars */
X#define VL_MAX_GROUPNAME 7 /* dito. */
X
Xstatic char *Progname; /* name of the called process*/
Xstatic char filemode[10]; /* visible file mode (ls(1)) */
Xstatic Af_user author, owner;
Xstatic char version_string[80]; /* e.g. -V1.0 */
Xstatic char error_string[80]; /* for {af_}perror */
X
Xchar **udattrs; /* Uda sorted */
Xint version_number; /* Version identification
X * via option -V */
Xchar *version_states; /* Version states via
X * option -s */
X
Xchar *GetVersionState (state)
X int state;
X{
X switch (state) {
X case AF_BUSY:
X return (IsOptionSet(VL_O_VERSIONSTATE) ? "[busy]" : "b");
X case AF_SAVED:
X return (IsOptionSet(VL_O_VERSIONSTATE) ? "[save]" : "s");
X case AF_PROPOSED:
X return (IsOptionSet(VL_O_VERSIONSTATE) ? "[prop]" : "p");
X case AF_PUBLISHED:
X return (IsOptionSet(VL_O_VERSIONSTATE) ? "[publ]" : "P");
X case AF_ACCESSED:
X return (IsOptionSet(VL_O_VERSIONSTATE) ? "[acce]" : "a");
X case AF_FROZEN:
X return (IsOptionSet(VL_O_VERSIONSTATE) ? "[froz]" : "f");
X default:
X return (IsOptionSet(VL_O_VERSIONSTATE) ? "[????]" : "?");
X }
X}
X
Xchar *GetVersionId (generation, revision)
X int generation, revision;
X{
X if ( (generation != AF_BUSYVERS) || ( revision != AF_BUSYVERS)) {
X (void)sprintf (version_string, "[%d.%d]", generation, revision);
X return version_string;
X }
X else
X return "";
X}
X
XVinfoCleanup ()
X{
X
X}
X
Xchar *GetMode (mode)
X u_short mode;
X{
X/* This function should return a capital 'L' in the file-class field */
X/* to indicate a *locked* version. Maybe optional. Instead of Ownername */
X/* the name of the locker is to be printed. */
X (void)sprintf (filemode, "%c%c%c%c%c%c%c%c%c%c",
X (mode & S_IFDIR) ? 'd' : '-',
X (mode & S_IREAD) ? 'r' : '-',
X (mode & S_IWRITE) ? 'w' : '-',
X (mode & S_IEXEC) ? 'x' : '-',
X (mode & (S_IREAD >> 3)) ? 'r' : '-',
X (mode & (S_IWRITE >> 3)) ? 'w' : '-',
X (mode & (S_IEXEC >> 3)) ? 'x' : '-',
X (mode & (S_IREAD >> 6)) ? 'r' : '-',
X (mode & (S_IWRITE >> 6)) ? 'w' : '-',
X (mode & (S_IEXEC >> 6)) ? 'x' : '-'
X );
X
X if (mode & S_ISUID)
X filemode[1] = 's';
X if (mode & S_ISGID)
X filemode[6] = 's';
X if (mode & S_ISVTX)
X filemode[9] = 't';
X
X return filemode;
X}
X
Xextern char *GetUserInfo (userdesc)
X Af_user *userdesc;
X{
X char *uinfo, *tmp;
X
X if ((tmp = malloc(MAXNAMLEN + MAXHOSTNAMELEN + 2)) == NULL) {
X fprintf (stderr, "in GetUserInfo: not enough memory\n");
X exit (1);
X }
X
X if ((uinfo = malloc(20)) == NULL) {
X fprintf (stderr, "in GetUserInfo: not enough memory\n");
X exit (1);
X }
X
X (void)sprintf
X (tmp, "%s%s%s", userdesc->af_username, userdesc->af_userhost[0] ?
X "@" : "", userdesc->af_userhost);
X (void)sprintf (uinfo, "%-16s", tmp);
X free (tmp);
X return uinfo;
X}
X
Xchar *GetDate (date)
X time_t date;
X{
X char *tmp_time;
X extern char *ctime();
X
X tmp_time = ctime(&date);
X
X /* Format is "Sun Sep 16 01:03:52 1973\n\0" */
X tmp_time = tmp_time + 4;
X tmp_time[20] = '\0';
X return tmp_time;
X}
X
X
XIsDirectory (name)
X char *name;
X{
X struct stat stbuf;
X
X if (stat(name, &stbuf)) {
X return 0;
X }
X
X return (stbuf.st_mode & S_IFDIR);
X}
X
Xint FileExists (name)
X char *name;
X{
X struct stat buf;
X
X return ((stat (name, &buf) == 0) ? 1 : 0);
X}
X
X
Xint PutProgramName (name)
X char *name;
X{
X Progname = ((Progname = rindex (name, '/')) ? ++Progname : name);
X}
X
Xchar *GetProgramName ()
X{
X return Progname;
X}
X
Xvoid PutVersionStates (states)
X char *states;
X{
X version_states = states;
X}
X
X#define nxt(s) (s = (*(s+strlen(s)+1) != '\0') ? s+strlen(s)+1 : NULL)
X
XCopyUdattrs (udaval, udattrs)
X char *udaval;
X char **udattrs;
X{
X /* returns # of udattrs */
X register int i;
X
X register char *cp;
X char *temp;
X
X if ( (temp = malloc ((unsigned)(strlen (udaval) +2))) == NULL) {
X perror ("malloc");
X exit (1);
X }
X (void)strcpy (temp, udaval);
X temp[strlen(udaval)+1] = '\0';
X
X cp = temp; /* */
X while (temp && *temp) {
X if (*temp == ',') {
X *temp = '\0';
X }
X ++temp;
X }
X
X i = 0;
X while (cp && *cp) {
X udattrs[i] = cp;
X i++; nxt(cp); /* nxt() is a macro !*/
X }
X udattrs[i] = NULL;
X
X /*
X * Now scan for "foo=bar<blank>bar1" and substitute <blank> by <Ctrl-A>.
X * Don't ask why.
X */
X
X for (i=0; udattrs[i]; i++) {
X cp = udattrs[i];
X for (cp = udattrs[i]; cp && *cp; cp++)
X if (*cp == ' ')
X *cp = AF_UDAVALDEL; /* This is a Ctrl-A */
X }
X return i; /* return # of udattrs */
X}
X
Xint AddUdattrs (udas)
X char *udas;
X{
X int i, length, na;
X char **cpp;
X
X if ( udas && (*udas == ':')) udas++;
X length = 0;
X /* determine length of current udattrs */
X if (udattrs && *udattrs) {
X for (i = 0 ; udattrs[i]; i++)
X length++;
X }
X
X length += strlen (udas) + 1; /* plus the new udas */
X length++;
X if ((cpp = (char **) malloc ((unsigned)(sizeof (char **) * length)))
X == (char **) NULL) {
X (void)sprintf (error_string, "%s: in AddUdattra(): malloc", Progname);
X perror (error_string);
X exit (1);
X }
X
X na = CopyUdattrs (udas, cpp);
X
X if (udattrs && *udattrs) {
X for (i = 0 ; udattrs[i]; i++) /* copy old into new array */
X cpp[na++] = udattrs[i];
X }
X
X cpp[na] = (char *) NULL;
X free ((char *)udattrs);
X
X udattrs = cpp;
X}
X
XAddHiddenUda (name, val)
X char *name, *val;
X{
X int length;
X char *huda;
X
X length = strlen (name);
X length += strlen (val);
X
X if ((huda = malloc ((unsigned)(length+2*sizeof(char)))) == (char *) NULL) {
X (void)sprintf (error_string, "in AddHiddenUda(): malloc");
X perror (error_string);
X exit (1);
X }
X (void)sprintf (huda, "%s=%s", name, val);
X AddUdattrs (huda);
X}
X
Xchar **GetUdattrs ()
X{
X return udattrs;
X}
X
Xu_long vstates = 0;
X#define VL_CHCK_BUSY 01
X#define VL_CHCK_SAVE 02
X#define VL_CHCK_PROPOSED 04
X#define VL_CHCK_PUBLISHED 010
X#define VL_CHCK_ACCESSED 020
X#define VL_CHCK_FROZEN 040
X#define VL_CHCK_ALL 077
X#define VL_MAX_STATES 6
X
Xvoid ScanVersionStates ()
X
X /*
X * Scans strings of the form:
X * bspPaf
X * c+ (c is a char)
X * c-
X * ~c (not)
X * !c (not)
X * c-,c+
X * c+c-
X */
X{
X register last_state;
X
X if (! (*version_states)) {
X vstates = VL_CHCK_ALL;
X return;
X }
X
X while (*version_states) {
X switch (*version_states) {
X case 'b':
X vstates |= VL_CHCK_BUSY;
X last_state = AF_BUSY;
X break;
X case 's':
X vstates |= VL_CHCK_SAVE;
X last_state = AF_SAVED;
X break;
X case 'p':
X vstates |= VL_CHCK_PROPOSED;
X last_state = AF_PROPOSED;
X break;
X case 'P':
X vstates |= VL_CHCK_PUBLISHED;
X last_state = AF_PUBLISHED;
X break;
X case 'a':
X vstates |= VL_CHCK_ACCESSED;
X last_state = AF_ACCESSED;
X break;
X case 'f':
X vstates |= VL_CHCK_FROZEN;
X last_state = AF_FROZEN;
X break;
X case '+': /* -sb+ */
X switch (last_state) {
X case AF_BUSY:
X vstates |= VL_CHCK_BUSY;
X case AF_SAVED:
X vstates |= VL_CHCK_SAVE;
X case AF_PROPOSED:
X vstates |= VL_CHCK_PROPOSED;
X case AF_PUBLISHED:
X vstates |= VL_CHCK_PUBLISHED;
X case AF_ACCESSED:
X vstates |= VL_CHCK_ACCESSED;
X case AF_FROZEN:
X vstates |= VL_CHCK_FROZEN;
X break;
X default:
X fprintf (stderr, "%s: fatal error in ScanVersionStates\n", Progname);
X exit (1);
X }
X break;
X case '-': /* -sb- */
X if ( !((*(version_states+1) == ',') ||
X (!*(version_states+1)))) { /* -sb-f */
X fprintf (stderr, "%s: subrange of states is not allowed\n",
X Progname);
X exit (1);
X }
X else {
X switch (last_state) {
X case AF_FROZEN:
X vstates |= VL_CHCK_FROZEN;
X case AF_ACCESSED:
X vstates |= VL_CHCK_ACCESSED;
X case AF_PUBLISHED:
X vstates |= VL_CHCK_PUBLISHED;
X case AF_PROPOSED:
X vstates |= VL_CHCK_PROPOSED;
X case AF_SAVED:
X vstates |= VL_CHCK_SAVE;
X case AF_BUSY:
X vstates |= VL_CHCK_BUSY;
X break;
X default:
X fprintf (stderr, "%s: fatal error in ScanVersionStates\n", Progname);
X exit (1);
X }
X }
X break;
X case ',': /* skip this char */
X break;
X case '~':
X case '!':
X if (!*(version_states + 1)) {
X fprintf (stderr, "%s: missing version state after '%c'\n",
X Progname, *version_states);
X exit (1);
X }
X vstates = VL_CHCK_ALL;
X switch (*(++version_states)) {
X case 'b':
X vstates &= ~VL_CHCK_BUSY;
X last_state = AF_BUSY;
X break;
X case 's':
X vstates &= ~VL_CHCK_SAVE;
X last_state = AF_SAVED;
X break;
X case 'p':
X vstates &= ~VL_CHCK_PROPOSED;
X last_state = AF_PROPOSED;
X break;
X case 'P':
X vstates &= ~VL_CHCK_PUBLISHED;
X last_state = AF_PUBLISHED;
X break;
X case 'a':
X vstates &= ~VL_CHCK_ACCESSED;
X last_state = AF_ACCESSED;
X break;
X case 'f':
X vstates &= ~VL_CHCK_FROZEN;
X last_state = AF_FROZEN;
X break;
X default:
X fprintf (stderr, "%s: unknown state '%c'. Ignored.\n",
X Progname, *version_states);
X break;
X }
X break;
X default:
X fprintf (stderr, "%s: unknown state '%c'. Asume 'b+'\n",
X Progname, *version_states);
X vstates = VL_CHCK_ALL;
X return;
X }
X version_states++;
X }
X}
X
Xint MatchesVersionStates (attrbuf)
X Af_attrs *attrbuf;
X{
X register int attrstate;
X register int state;
X
X state = vstates;
X attrstate = attrbuf->af_state;
X
X if (state == VL_CHCK_ALL) return 1;
X
X switch (attrstate) {
X case AF_BUSY:
X return (state & VL_CHCK_BUSY);
X case AF_SAVED:
X return (state & VL_CHCK_SAVE);
X case AF_PROPOSED:
X return (state & VL_CHCK_PROPOSED);
X case AF_PUBLISHED:
X return (state & VL_CHCK_PUBLISHED);
X case AF_ACCESSED:
X return (state & VL_CHCK_ACCESSED);
X case AF_FROZEN:
X return (state & VL_CHCK_FROZEN);
X default:
X return 0;
X }
X}
X
Xvoid PutAuthorIdentifications (author_id)
X char *author_id;
X{
X char *cp;
X
X if (cp=index (author_id, '@')) {
X *cp++ = '\0';
X (void)strcpy (author.af_userhost, cp);
X }
X (void)strcpy (author.af_username, author_id);
X}
X
Xchar *GetAuthoridFromAuthor ()
X{
X return author.af_username;
X}
X
Xchar *GetAuthorhostFromAuthor ()
X{
X return author.af_userhost;
X}
X
X
Xvoid PutOwnerIdentifications (owner_id)
X char *owner_id;
X{
X char *cp;
X
X if (cp=index (owner_id, '@')) {
X *cp++ = '\0';
X (void)strcpy (owner.af_userhost, cp);
X }
X (void)strcpy (owner.af_username, owner_id);
X}
X
Xchar *GetOwneridFromOwner ()
X{
X return owner.af_username;
X}
X
Xchar *GetOwnerhostFromOwner ()
X{
X return owner.af_userhost;
X}
X
X/*ARGSUSED*/
Xint
Xa_dir_and_a_file (ac, av)
X int ac;
X char **av;
X{
X /*
X * Return 1 iff av contains any directory name.
X */
X while (av && *av) {
X if (IsDirectory (*av))
X return 1;
X av++;
X }
X return 0;
X}
X
Xchar **
Xrearrange_args (ac, av)
X int ac;
X char **av;
X{
X /*
X * Sorts av in the following order: first pure files, then directories.
X * Returns sorted av.
X */
X char **dirs;
X char **tdirs;
X char **files;
X char **tfiles;
X char **tav;
X
X tav = av;
X
X if ((dirs = (char **)
X malloc ((unsigned)((ac + 1) * sizeof(char *)))) == (char **)NULL) {
X perror ("malloc");
X exit (1);
X }
X tdirs = dirs;
X
X if ((files = (char **)
X malloc ((unsigned)((ac + 1) * sizeof(char *)))) == (char **)NULL) {
X perror ("malloc");
X exit (1);
X }
X tfiles = files;
X
X while (av && *av) {
X if (IsDirectory (*av)) {
X *dirs = *av;
X dirs++;
X }
X else {
X *files = *av;
X files++;
X }
X
X av++;
X }
X
X files = (char **) NULL;
X dirs = (char **) NULL;
X
X av = tav;
X while (tfiles && *tfiles) {
X *av = *tfiles;
X av++; tfiles++;
X }
X
X while (tdirs && *tdirs) {
X *av = *tdirs;
X av++; tdirs++;
X }
X
X return tav;
X}
X
Xint IsHiddenUda (uda)
X char *uda;
X{
X /*
X * A hidden Uda begins and ends with 2 '_'.
X */
X
X return (!strncmp (uda, "__", 2));
X}
X
Xint IsHiddenFile(attrbuf)
X Af_attrs *attrbuf;
X{
X /* Is file a hidden file ? */
X if ( (attrbuf->af_name[0] == '\0') || (attrbuf->af_name[0] == '.') )
X return 1;
X else
X return 0;
X}
X
Xlogerr (msg) char *msg; {
X fprintf (stderr, "%s: %s.\n", Progname, msg);
X}
END_OF_FILE
if test 14112 -ne `wc -c <'src/vc/vlmisc.c'`; then
echo shar: \"'src/vc/vlmisc.c'\" unpacked with wrong size!
fi
# end of 'src/vc/vlmisc.c'
fi
echo shar: End of archive 16 \(of 33\).
cp /dev/null ark16isdone
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