home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume19
/
shape
/
part18
< prev
next >
Wrap
Text File
|
1989-05-31
|
55KB
|
2,003 lines
Subject: v19i031: A software configuration management system, Part18/33
Newsgroups: comp.sources.unix
Sender: sources
Approved: rsalz@uunet.UU.NET
Submitted-by: Axel Mahler <unido!coma!axel>
Posting-number: Volume 19, Issue 31
Archive-name: shape/part18
#! /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 18 (of 33)."
# Contents: src/afs/aflib.c src/afs/afretr.c src/afsit/rcsit.c
# Wrapped by rsalz@papaya.bbn.com on Thu Jun 1 19:27:10 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/afs/aflib.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/afs/aflib.c'\"
else
echo shar: Extracting \"'src/afs/aflib.c'\" \(16973 characters\)
sed "s/^X//" >'src/afs/aflib.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 * aflib.c -- Miscellaneous functions
X *
X * Author: Andreas Lampen, TU-Berlin (andy@coma.UUCP)
X * (andy@db0tui62.BITNET)
X *
X * $Header: aflib.c[1.6] Wed Feb 22 16:27:41 1989 andy@coma published $
X *
X * EXPORT:
X *
X * af_errno -- global variable holding the actual error code
X * af_serr -- report error without writing error protocol
X * af_err -- write error protocol
X * af_wng -- print out warning message
X * af_perror -- print AFS-error
X * af_regtmpfile -- register tmp file
X * af_unregtmpfile -- unregister tmp file
X * af_reglckfile -- register lock file
X * af_cpfile -- copy files
X * af_cleanup -- do cleanup (e.g. upon signal)
X * af_malloc -- allocate memory
X * af_realloc -- reallocate memoty
X * af_free -- free allocated memory segment
X * af_frmemlist -- free list of allocated memory segments
X * af_bsearch -- binary search on ordered list of strings
X * af_checkread -- check read permissions of AF-file
X * af_checkperm -- check access permissions for AF-file
X */
X
X#include <stdio.h>
X#include <string.h>
X#ifdef SUNOS_4_0
X#include <strings.h>
X#endif
X#ifdef SYSLOG
X#include <syslog.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#ifdef TMPDEBUG
Xextern FILE *tmpprot;
X#endif
X
Xchar *getlogin();
X
X/*=========================================================================
X * af_serr -- report error without writing error protocol
X *
X *=========================================================================*/
X
Xextern int errno;
X
XEXPORT int af_errno, af_nodiag = FALSE;
X
XEXPORT void af_serr (routine, called, errcd)
X char *routine;
X char *called;
X int errcd;
X{
X af_nodiag = TRUE;
X af_err (routine, called, errcd);
X af_nodiag = FALSE;
X}
X
X/*=========================================================================
X * af_err -- write error protocol
X *
X *=========================================================================*/
X
Xstatic char diagstr[265]; /* for diagnistics of AF_EMISC */
X
Xstatic char *errors[] =
X {
X "", "", "",
X "permission denied", /* 3 */
X "archive file has changed since last read", /* 4 */
X "archive file is locked for writing", /* 5 */
X "no additional space in binary pool", /* 6 */
X "specified revision must not be a busy version", /* 7 */
X "specified revision is a derived object", /* 8 */
X "illegal format of var or uda string", /* 9 */
X "invalid key", /* 10 */
X "invalid set", /* 11 */
X "invalid user", /* 12 */
X "bad version number", /* 13 */
X "invalid location of archive", /* 14 */
X "miscellaneous errors", /* 15 */
X "invalid mode", /* 16 */
X "AFS subdirectory missing or not writable", /* 17 */
X "key does not exist in set", /* 18 */
X "invalid position in set", /* 19 */
X "specified revision does not exist", /* 20 */
X "specified object is no busy version", /* 21 */
X "specified object is no derived object", /* 22 */
X "version is not locked or locked by someone else", /* 23 */
X "specified object is no regular file", /* 24 */
X "specified object has no versions", /* 25 */
X "user defined attribute does not exist", /* 26 */
X "saved versions cannot be modified", /* 27 */
X "invalid state transition", /* 28 */
X "string too long", /* 29 */
X "too many user defined attributes", /* 30 */
X "wrong state", /* 31 */
X "error during delta operation", /* 32 */
X "Archive file inconsistent", /* 33 */
X "internal error", /* 34 */
X "no AFS file", /* 35 */
X };
X
X
XEXPORT void af_err (routine, called, errcd)
X char *routine;
X char *called;
X int errcd;
X{
X#ifndef SYSLOG
X FILE *errfile;
X char *af_asctime();
X#endif
X
X if (af_nodiag)
X {
X af_errno = errcd;
X if (af_errno == AF_EMISC)
X (void) strcpy (diagstr, called);
X return; /* do nothing */
X }
X
X#ifdef SYSLOG
X if (!openlog ("AFS", LOG_PID, LOG_LOCAL1))
X#else
X if ((errfile = fopen (AF_ERRLOG, "a")) == (FILE *)0)
X#endif
X {
X fprintf (stderr, "AFS: cannot open Error-logfile\n");
X return;
X }
X (void) chmod (AF_ERRLOG, 0666);
X
X#ifdef SYSLOG
X switch (errcd)
X {
X case AF_ESYSERR: syslog (LOG_ERR, "%s called af_%s: %s error in %s (%m)",
X getlogin(), routine, errors [abs(errcd)], called);
X break;
X case AF_EINCONSIST:
X case AF_ENOAFSFILE:
X case AF_EINTERNAL: syslog (LOG_ERR, "%s called af_%s: %s (%s)", getlogin(),
X routine, errors [abs(errcd)], called);
X break;
X case AF_EMISC: syslog (LOG_ERR, "%s called af_%s: %s ", getlogin(),
X routine, called);
X (void) strcpy (diagstr, called);
X break;
X default: syslog (LOG_ERR, "%s called af_%s: %s", getlogin(),
X routine, errors [abs(errcd)]);
X }
X#else
X fprintf (errfile, "%s pid[%d] %s",af_gethostname(),getpid (), af_asctime ());
X switch (errcd)
X {
X case AF_ESYSERR: fprintf (errfile, "\t%s called af_%s: %s error in %s\n",
X (char *) getlogin(), routine, errors [abs(errcd)], called);
X break;
X case AF_EINCONSIST:
X case AF_ENOAFSFILE:
X case AF_EINTERNAL: fprintf (errfile, "\t%s called af_%s: %s (%s)\n", (char *) getlogin(), routine, errors [abs(errcd)], called);
X break;
X case AF_EMISC: fprintf (errfile, "\t%s called af_%s: %s\n", (char *) getlogin(), routine, called);
X (void) strcpy (diagstr, called);
X break;
X default: fprintf (errfile, "\t%s called af_%s: %s\n", (char *) getlogin(), routine, errors [abs(errcd)]);
X }
X#endif
X
X#ifdef SYSLOG
X closelog ();
X#else
X (void) fclose (errfile);
X#endif
X
X af_errno = errcd;
X return;
X}
X
X/*=========================================================================
X * af_wng -- write warning to error protocol
X *
X *=========================================================================*/
X
XEXPORT void af_wng (routine, comment)
X char *routine, *comment;
X{
X#ifndef SYSLOG
X FILE *errfile;
X char *af_asctime();
X#endif
X
X#ifdef SYSLOG
X if (!openlog ("AFS", LOG_PID, LOG_LOCAL1))
X#else
X if ((errfile = fopen (AF_ERRLOG, "a")) == (FILE *)0)
X#endif
X {
X fprintf (stderr, "AFS: cannot open Error-logfile\n");
X return;
X }
X (void) chmod (AF_ERRLOG, 0666);
X
X#ifdef SYSLOG
X syslog (LOG_WARNING, "%s called af_%s: %s", getlogin(), routine, comment);
X#else
X fprintf (errfile, "%s pid[%d] %s", af_gethostname(), getpid (), af_asctime ());
X fprintf (errfile, "\t%s called af_%s: %s\n", (char *) getlogin(), routine, comment);
X#endif
X
X#ifdef SYSLOG
X closelog ();
X#else
X (void) fclose (errfile);
X#endif
X return;
X}
X
X
X/*=========================================================================
X * af_perror -- print AFS-error message
X *
X *=========================================================================*/
X
XEXPORT void af_perror (string)
X char *string;
X{
X switch (af_errno)
X {
X case AF_ESYSERR: perror (string);
X break;
X case AF_EMISC: fprintf (stderr, "%s: %s\n", string, diagstr);
X break;
X default: fprintf (stderr, "%s: %s\n", string, errors [abs(af_errno)]);
X }
X}
X
X/**************************************************************************/
X
X/*================================================================
X * list of tmp files
X *
X *================================================================*/
X
Xstatic char *tmpfilelist[NOFILE];
X
XLOCAL void rmtmpfiles ()
X{
X register i;
X
X for (i=0; i < NOFILE; i++)
X if (tmpfilelist[i] != (char *)0)
X (void) af_unlink (tmpfilelist[i]);
X}
X
XEXPORT void af_regtmpfile (name) /* registrate tmp file */
X char *name;
X{
X register int i;
X
X#ifdef TMPDEBUG
X fprintf (tmpprot, "TMP: register %s\n", name);
X#endif
X /* look for free space in list */
X for (i=0; i < NOFILE; i++)
X if (tmpfilelist[i] == (char *)0)
X {
X tmpfilelist[i] = name;
X break;
X }
X if (i == NOFILE) /* list is full */
X af_wng ("regtmpfile", "tmpfile list is full -- couldn't register");
X}
X
XEXPORT void af_unregtmpfile (name) /* remove tmp file entry */
X char *name;
X{
X register i;
X#ifdef TMPDEBUG
X fprintf (tmpprot, "TMP: unregister %s\n", name);
X#endif
X for (i=0; i < NOFILE; i++)
X if (tmpfilelist[i] == name)
X {
X tmpfilelist[i] = (char *)0;
X break;
X }
X if (i == NOFILE) /* name not found */
X af_wng ("unregtmpfile", "name of tmpfile has not been registered before");
X}
X
X/*=========================================================================
X * af_reglckfile -- register lock file
X *
X *=========================================================================*/
X
Xstatic char *lckfilename;
X
XEXPORT af_reglckfile (name)
X char *name;
X{
X lckfilename = af_entersym (name);
X}
X
XLOCAL rmlckfiles ()
X{
X (void) unlink (lckfilename);
X}
X
X/*=========================================================================
X * af_cpfile -- copy files
X *
X *=========================================================================*/
X
XEXPORT af_cpfile (source, size, dest)
X char *source;
X off_t size;
X char *dest;
X{
X char cont[BUFSIZ];
X int bufsiz = BUFSIZ;
X FILE *sfile, *dfile;
X
X if ((sfile = fopen (source, "r")) == (FILE *)0)
X {
X free (cont);
X return (ERROR);
X }
X if ((dfile = fopen (dest, "w")) == (FILE *) 0)
X {
X free (cont);
X (void) fclose (sfile);
X return (ERROR);
X }
X
X while (size > 0)
X {
X if (size >= BUFSIZ)
X size -= BUFSIZ;
X else
X {
X bufsiz = size;
X size = 0;
X }
X if (!fread (cont, sizeof(char), bufsiz, sfile))
X {
X (void) fclose (sfile);
X (void) fclose (dfile);
X return (ERROR);
X }
X if (!fwrite (cont, sizeof(char), bufsiz, dfile))
X {
X (void) fclose (sfile);
X (void) fclose (dfile);
X return (ERROR);
X }
X }
X
X (void) fclose (sfile);
X (void) fclose (dfile);
X return (AF_OK);
X}
X
X
X/**************************************************************************/
X
X/*=========================================================================
X * af_cleanup -- do cleanup
X *
X *=========================================================================*/
X
XEXPORT af_cleanup ()
X{
X /* remove tmp files */
X rmtmpfiles ();
X rmlckfiles ();
X}
X
X/*=========================================================================
X * af_malloc -- allocate memory and registrate it
X * af_realloc -- reallocate memory and registrate it
X *
X * all memory allocated for data in an archive is preceeded by a pointer
X * pointing to the prevoiusly allocated memory segment.
X * So we get a chain of allocated memory segments.
X * ( probably not portable )
X *
X *=========================================================================*/
X
XEXPORT char *af_malloc (list, size)
X Af_revlist *list;
X unsigned size;
X{
X char **mem, *malloc();
X
X if ((mem = (char **)malloc ((unsigned) (size + sizeof (mem)))) == (char **)0)
X return (char *)0;
X#ifdef MEMDEBUG
X fprintf (memprot, "%x (alloc) %d bytes\n", mem, size + sizeof (mem));
X#endif
X
X *mem = list->af_mem;
X list->af_mem = (char *)mem;
X
X mem++; /* increment by sizeof ptr */
X
X return ((char *)mem);
X}
X
X
XEXPORT char *af_realloc (list, ptr, size)
X Af_revlist *list;
X char *ptr;
X unsigned size;
X{
X char **mem, **segptr, **nextptr, *realloc();
X
X if ((mem = (char **)realloc (ptr, (unsigned) (size + sizeof (mem)))) == (char **)0)
X return (char *)0;
X#ifdef MEMDEBUG
X fprintf (memprot, "realloc: old - %x , new - %x %d bytes\n", ptr, mem, size + sizeof (mem));
X#endif
X
X if ((char *)mem == ptr - sizeof ((char *)0)) /* no registration necessary */
X return ((char *)mem);
X
X segptr = &(list->af_mem); /* remove the implicitely freed memory segment */
X while (*segptr != ptr - sizeof ((char *)0))
X segptr = (char **)*segptr;
X nextptr = (char **)*segptr;
X *segptr = *nextptr;
X
X *mem = list->af_mem; /* registrate new segment */
X list->af_mem = (char *)mem;
X
X mem++; /* increment by sizeof ptr */
X
X return ((char *)mem);
X}
X
XEXPORT void af_free (list, ptr)
X Af_revlist *list;
X char *ptr;
X{
X char **segptr, **nextptr;
X
X#ifdef MEMDEBUG
X fprintf (memprot, "%x (free)\n", ptr - sizeof ((char *)0));
X#endif
X free (ptr - sizeof ((char *)0));
X
X segptr = &(list->af_mem); /* remove memory segment from registration list */
X while (*segptr != ptr - sizeof ((char *)0))
X segptr = (char **)*segptr;
X nextptr = (char **)*segptr;
X *segptr = *nextptr;
X}
X
X
XEXPORT void af_frmemlist (list)
X Af_revlist *list;
X{
X char **ptr;
X
X ptr = &(list->af_mem);
X while ((char *)*ptr)
X {
X#ifdef MEMDEBUG
X fprintf (memprot, "%x (free)\n", *ptr);
X#endif
X free (*ptr);
X ptr = (char **)*ptr;
X }
X list->af_mem = (char *)0;
X}
X
X/*========================================================================
X * af_bsearch -- do binary search on ordered list of strings
X * returns position (-1 if target not found)
X *
X *========================================================================*/
X
XEXPORT af_bsearch (list, size, target)
X char **list;
X int size;
X char *target;
X{
X int hi = size-1, lo=0, pos, res;
X
X pos = (hi+lo)/2;
X while (hi >= lo)
X {
X if ((res = strcmp (target, list[pos])) == 0)
X return (pos);
X else
X {
X if (res < 0)
X hi = pos - 1;
X else /* res > 0 */
X lo = pos + 1;
X pos = (hi+lo)/2;
X }
X }
X /* the target string was not found */
X return (ERROR);
X}
X
X
X/*====================================================================
X * af_checkread -- see if AF-file is readable
X *
X *====================================================================*/
X
XEXPORT af_checkread (key)
X Af_key *key;
X{
X Uid_t uid, auuid, ownuid;
X Gid_t augid, owngid;
X int i, ngroups, gidset[NGROUPS];
X
X if ((VATTR(key).af_mode & 0004) == 0004) /* readable for world */
X return (AF_OK);
X
X if ((VATTR(key).af_mode & 0040) == 0040) /* readable for group */
X {
X /* this then part is BSD specific */
X ngroups = getgroups (NGROUPS, gidset);
X augid = af_getgid (VATTR(key).af_auname, VATTR(key).af_auhost);
X owngid = af_getgid (CATTR(key).af_ownname, CATTR(key).af_ownhost);
X for (i=0; i < ngroups; i++)
X {
X if ((augid == (Gid_t)gidset[i]) || (owngid == (Gid_t)gidset[i]))
X return (AF_OK);
X }
X }
X
X if ((VATTR(key).af_mode & 0400) == 0400) /* readable by owner */
X {
X uid = getuid();
X auuid = af_getuid (VATTR(key).af_auname, VATTR(key).af_auhost);
X ownuid = af_getuid (CATTR(key).af_ownname, CATTR(key).af_ownhost);
X if ((auuid == uid) || (ownuid == uid))
X return (AF_OK);
X }
X
X return (ERROR);
X}
X
X
X/*====================================================================
X * af_checkperm -- check access permissions for AF-file
X *
X *====================================================================*/
X
XEXPORT af_checkperm (key, mode)
X Af_key *key;
X int mode;
X{
X Uid_t uid = getuid(), lockeruid;
X bool ok = FALSE;
X
X if (mode & AF_OWNER)
X {
X if (uid == af_getuid (CATTR(key).af_ownname, CATTR(key).af_ownhost))
X ok = TRUE;
X }
X if (!ok && (mode & AF_LOCKHOLDER))
X {
X if ((lockeruid = af_getuid (VATTR(key).af_lckname,
X VATTR(key).af_lckhost)) == uid)
X ok = TRUE;
X else
X {
X /* if object is locked by someone else */
X if (lockeruid != (Uid_t) ERROR)
X goto exit;
X }
X }
X if (!ok && (mode & AF_AUTHOR))
X {
X if (uid == af_getuid (VATTR(key).af_auname, VATTR(key).af_auhost))
X ok = TRUE;
X }
X if (!ok && (mode & AF_WORLD))
X {
X ok = TRUE;
X }
X
X exit:
X /* if access is not ok, or AFS subdir is not writable */
X if (!ok)
X SFAIL ("checkperm", "", AF_EACCES, ERROR);
X if (!(key->af_ldes->af_extent & AF_UXWRITE))
X SFAIL ("checkperm", "", AF_ENOAFSDIR, ERROR);
X return (AF_OK);
X}
END_OF_FILE
if test 16973 -ne `wc -c <'src/afs/aflib.c'`; then
echo shar: \"'src/afs/aflib.c'\" unpacked with wrong size!
fi
# end of 'src/afs/aflib.c'
fi
if test -f 'src/afs/afretr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/afs/afretr.c'\"
else
echo shar: Extracting \"'src/afs/afretr.c'\" \(16910 characters\)
sed "s/^X//" >'src/afs/afretr.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 * afretr.c - retrieve interface
X *
X * Author: Andreas Lampen, TU-Berlin (andy@coma.UUCP
X * andy@db0tui62.BITNET)
X *
X * $Header: afretr.c[1.4] Wed Feb 22 16:27:50 1989 andy@coma published $
X *
X * EXPORT:
X * af_bpfind -- find derived files by attributes
X * af_find -- find source files by attributes
X * af_getkey -- find single file by unique attributes
X * af_dropkey -- release memory associated with filekey
X * af_initattrs -- initialize attribute buffer
X */
X
X#include <stdio.h>
X#include <string.h>
X#ifdef SUNOS_4_0
X#include <strings.h>
X#endif
X#include <sys/types.h>
X#include <sys/stat.h>
X/* #include <sys/dir.h> */
X
X#include "typeconv.h"
X#include "afsys.h"
X#include "afs.h"
X#include "afarchive.h"
X
Xextern int af_errno;
X
Xextern Af_hashent af_hashentry;
X
X/*================= collect_lists ====================================*/
X
XLOCAL Af_revlist **collect_lists (pathname, name, type, revlist, nlists)
X char *pathname, *name, *type;
X Af_revlist **revlist;
X int *nlists; /* out */
X{
X DIR *dirp;
X struct direct *dirent;
X char *afpath, *afname, *aftype, dirpath[MAXNAMLEN*4];
X char fullname[MAXNAMLEN*4], *realloc();
X bool seconddir = FALSE, mode;
X int listsiz, i;
X Af_revlist *af_readattrs();
X
X listsiz = AF_SEGLEN;
X *nlists = 0;
X
X /* open named directory */
X if ((dirp = opendir (pathname)) == (DIR *)0)
X FAIL ("collect_lists", "opendir", AF_ESYSERR, (Af_revlist **)0);
X
X (void) strcpy (dirpath, pathname);
X
Xloop:
X /* lookup all files */
X while ((dirent = readdir (dirp)) != (struct direct *)0)
X {
X (void) sprintf (fullname, "%s/%s\0", dirpath, dirent->d_name);
X
X /* if entry belongs to binary pool */
X if (af_isbpfile (dirent->d_name))
X continue;
X
X afname = af_entersym (af_afname (fullname));
X aftype = af_entersym (af_aftype (fullname));
X
X /* if ((no name given || name equal) && (no type || type equal)) */
X if ( ((name[0] == '*') || !strcmp (name, afname)) &&
X ((type[0] == '*') || !strcmp (type, aftype)) )
X {
X (*nlists)++;
X if (*nlists >= listsiz)
X {
X /* realloc memory for revlist */
X if ((revlist = (Af_revlist **)realloc ((char *)revlist, (unsigned) (sizeof((Af_revlist *)0)*(listsiz + AF_SEGLEN)))) == (Af_revlist **)0)
X FAIL ("collect_lists","realloc", AF_ESYSERR, (Af_revlist **)0);
X listsiz += AF_SEGLEN;
X }
X afpath = af_entersym (af_afpath (fullname));
X mode = TRUE;
X if ((revlist[(*nlists)-1] =
X af_readattrs (afpath, afname, aftype, &mode))
X == (Af_revlist *)0)
X {
X if (af_errno == AF_ENOAFSFILE)
X {
X (*nlists)--;
X continue;
X }
X else
X return ((Af_revlist **)0);
X }
X if (mode)
X {
X /* see if list is already in "revlists" */
X /* this loop may be time-consuming */
X i = 0;
X while (i < (*nlists)-1)
X {
X if ((revlist[i]->af_list[0].af_name == afname) &&
X (revlist[i]->af_cattrs.af_syspath == afpath) &&
X (revlist[i]->af_list[0].af_type == aftype))
X {
X (*nlists)--;
X break;
X }
X i++;
X }
X }
X }
X }
X closedir (dirp);
X
X if (!seconddir)
X {
X (void) sprintf (dirpath, "%s%c%s\0", pathname, '/', AF_SUBDIR);
X /* open AFS subdirectory if it exists */
X if ((dirp = opendir (dirpath)) != (DIR *)0)
X {
X seconddir = TRUE;
X goto loop;
X }
X }
Xreturn (revlist);
X}
X
X/*====================================================================
X * af_abufcmp -- compare attrbuf with version attributes
X * returns TRUE if attrs do not match
X *
X *====================================================================*/
X
XLOCAL af_abufcmp (attrbuf, key)
X Af_attrs *attrbuf;
X Af_key *key;
X{
X int match, j;
X
X /* if (attribute is set && attributes does not match) -- return ERROR */
X
X /*** generation number ***/
X if ((attrbuf->af_gen != AF_NOVNUM) && (attrbuf->af_gen != VATTR(key).af_gen))
X return (ERROR);
X
X /*** revision number ***/
X if ((attrbuf->af_rev != AF_NOVNUM) && (attrbuf->af_rev != VATTR(key).af_rev))
X return (ERROR);
X
X /*** variant attribute ***/
X if ((attrbuf->af_variant[0]) &&
X (strcmp (attrbuf->af_variant, NOTNIL(VATTR(key).af_variant))))
X return (ERROR);
X
X /*** state ***/
X if ((attrbuf->af_state != AF_NOSTATE) &&
X (attrbuf->af_state != VATTR(key).af_state))
X return (ERROR);
X
X /*** owner ***/
X if ( (attrbuf->af_owner.af_username[0]) &&
X (strcmp (attrbuf->af_owner.af_username, CATTR(key).af_ownname)) )
X return (ERROR);
X if ( (attrbuf->af_owner.af_userhost[0]) &&
X (strcmp (attrbuf->af_owner.af_userhost, CATTR(key).af_ownhost)) )
X return (ERROR);
X
X /*** author ***/
X if ( (attrbuf->af_author.af_username[0]) &&
X (strcmp (attrbuf->af_author.af_username, VATTR(key).af_auname)) )
X return (ERROR);
X if ( (attrbuf->af_author.af_userhost[0]) &&
X (strcmp (attrbuf->af_author.af_userhost, VATTR(key).af_auhost)) )
X return (ERROR);
X
X /*** size ***/
X if ((attrbuf->af_size != AF_NOSIZE) &&
X (attrbuf->af_size != VATTR(key).af_fsize) )
X return (ERROR);
X
X /*** mode ***/
X if ((attrbuf->af_mode != AF_NOMODE) &&
X (attrbuf->af_mode != VATTR(key).af_mode))
X return (ERROR);
X
X /*** locker ***/
X if ( (attrbuf->af_locker.af_username[0]) &&
X (strcmp (attrbuf->af_locker.af_username,
X NOTNIL(VATTR(key).af_lckname))) )
X return (ERROR);
X if ( (attrbuf->af_locker.af_userhost[0]) &&
X (strcmp (attrbuf->af_locker.af_userhost,
X NOTNIL(VATTR(key).af_lckhost))) )
X return (ERROR);
X
X /*** date of last modification ***/
X if ((attrbuf->af_mtime != AF_NOTIME) &&
X (attrbuf->af_mtime != VATTR(key).af_mtime) )
X return (ERROR);
X
X /*** date of last access ***/
X if ((attrbuf->af_atime != AF_NOTIME) &&
X (attrbuf->af_atime != VATTR(key).af_atime) )
X return (ERROR);
X
X /*** date of last status change ***/
X if ((attrbuf->af_ctime != AF_NOTIME) &&
X (attrbuf->af_ctime != VATTR(key).af_ctime) )
X return (ERROR);
X
X /*** saving date ***/
X if ((attrbuf->af_stime != AF_NOTIME) &&
X (attrbuf->af_stime != VATTR(key).af_stime) )
X return (ERROR);
X
X /*** date of last lock change ***/
X if ((attrbuf->af_stime != AF_NOTIME) &&
X (attrbuf->af_stime != VATTR(key).af_stime) )
X return (ERROR);
X
X /*** user defined attributes ***/
X if (attrbuf->af_udattrs[0] != (char *)0)
X {
X /* if list of user defined attributes is not empty or there */
X /* are attributes */
X match = TRUE;
X if ((attrbuf->af_udattrs[0][0] != '\0') || (VATTR(key).af_udanum != 0))
X {
X /* test all given entries */
X j=0;
X while ((attrbuf->af_udattrs[j] != (char *)0)
X && (match = !af_match (attrbuf->af_udattrs[j],
X &(VATTR(key).af_uhtab))))
X j++;
X } /* if */
X if (match == FALSE)
X return (ERROR);
X } /* if */
Xreturn (AF_OK);
X}
X
X
X/*====================================================================
X * af_bpfind
X *
X *====================================================================*/
X
XEXPORT af_bpfind (attrbuf, set)
X Af_attrs *attrbuf;
X Af_set *set; /* out */
X{
X Af_revlist *bplist, *af_rbplist();
X int i, maxindex;
X char *pathname, *getwd(), *malloc();
X Af_key key;
X
X /* init set */
X set->af_nkeys = 0;
X set->af_setlen = 0;
X set->af_klist = (Af_key *)0;
X
X /* build pathname (default is current directory) */
X pathname = af_uniqpath (attrbuf->af_syspath);
X
X if ((bplist = af_rbplist (pathname)) == (Af_revlist *)0)
X if (af_errno == AF_ENOAFSDIR)
X return (0);
X else
X return (ERROR);
X
X /* alloacte memory for set */
X if ((set->af_klist = (Af_key *)malloc ((unsigned) (sizeof (Af_key) * bplist->af_nrevs))) == (Af_key *)0)
X FAIL ("bpfind", "malloc", AF_ESYSERR, ERROR);
X set->af_setlen = bplist->af_nrevs;
X
X /* add all desired bpfiles to set */
X maxindex = bplist->af_nrevs;
X for (i=0; i < maxindex; i++)
X {
X /* skip invalid bpfiles */
X if (!(bplist->af_list[i].af_class & AF_VALID))
X {
X maxindex++;
X continue;
X }
X if (((attrbuf->af_name[0] != '*') &&
X (strcmp (attrbuf->af_name, bplist->af_list[i].af_name))) ||
X ((attrbuf->af_type[0] != '*') &&
X (strcmp (attrbuf->af_type, NOTNIL(bplist->af_list[i].af_type)))))
X continue;
X
X key.af_ldes = bplist;
X key.af_lpos = i;
X if (af_abufcmp (attrbuf, &key))
X continue;
X
X /* else add bpfile to set */
X set->af_klist[set->af_nkeys].af_ldes = bplist;
X set->af_klist[set->af_nkeys].af_lpos = i;
X set->af_nkeys++;
X bplist->af_refcount++;
X bplist->af_list[i].af_nlinks++;
X }
X /* if set is empty */
X if (set->af_nkeys == 0)
X {
X free ((char *)set->af_klist);
X set->af_setlen = 0;
X }
X
X if (bplist->af_refcount <= 0)
X (void) af_detlist (bplist);
X
X return (set->af_nkeys);
X}
X
X
X/*====================================================================
X * af_find
X *
X *====================================================================*/
X
XEXPORT af_find (attrbuf, set)
X Af_attrs *attrbuf;
X Af_set *set; /* out */
X{
X char *pathname, *getwd(), *malloc();
X register int i;
X int nlists, maxindex;
X Af_revlist *af_readattrs(), **revlist;
X Af_key key;
X bool mode = FALSE;
X
X /* alloc memory for revlist */
X if ((revlist = (Af_revlist **)malloc ((unsigned) (sizeof((Af_revlist *)0)*AF_SEGLEN))) == (Af_revlist **)0)
X FAIL ("find", "malloc", AF_ESYSERR, ERROR);
X
X /* init set */
X set->af_nkeys = 0;
X set->af_setlen = 0;
X set->af_klist = (Af_key *)0;
X
X /* build pathname (default is current directory) */
X pathname = af_uniqpath (attrbuf->af_syspath);
X
X if ((attrbuf->af_name[0] == '*') || (attrbuf->af_type[0] == '*'))
X {
X if ((revlist = collect_lists (pathname, attrbuf->af_name,
X attrbuf->af_type, revlist, &nlists))
X == (Af_revlist **)0)
X return (ERROR);
X }
X else
X {
X if (!attrbuf->af_name[0] && !attrbuf->af_type[0])
X {
X free ((char *)revlist);
X return (set->af_nkeys); /* no Af-files found */
X }
X if ((revlist[0] =
X af_readattrs (pathname, attrbuf->af_name,
X attrbuf->af_type, &mode)) == (Af_revlist *)0)
X {
X free ((char *)revlist);
X if (af_errno == AF_ENOAFSFILE)
X nlists = 0;
X else
X return (ERROR);
X }
X else
X nlists = 1;
X }
X
X if (nlists == 0)
X return (set->af_nkeys); /* no Af-files found */
X
X /* alloacte memory for set */
X if ((set->af_klist = (Af_key *)malloc ((unsigned) (sizeof (Af_key) * AF_SEGLEN))) == (Af_key *)0)
X FAIL ("find", "malloc", AF_ESYSERR, ERROR);
X set->af_setlen = AF_SEGLEN;
X
X /* lookup all revisions in all lists */
X /* this part is implemented quite dull up to now */
X /* -- the number of "if"'s should be reduced */
X for (;nlists > 0; nlists--)
X {
X maxindex = revlist[nlists-1]->af_nrevs;
X for (i = 0; i < maxindex; i++)
X {
X /* skip holes in the list */
X if (!(revlist[nlists-1]->af_list[i].af_class & AF_VALID))
X {
X maxindex++;
X continue;
X }
X
X /* test all attributes -- returnes true if attrs do not match */
X key.af_ldes = revlist[nlists-1];
X key.af_lpos = i;
X if (af_abufcmp (attrbuf, &key))
X continue;
X
X /********************************************/
X /********** put AF-file into set ************/
X /********************************************/
X
X /* if set is full, enlarge it */
X if (set->af_nkeys == set->af_setlen)
X {
X if ((set->af_klist =
X (Af_key *)realloc ((char *)set->af_klist, (unsigned) (sizeof(Af_key) * (set->af_setlen + AF_SEGLEN)))) == (Af_key *)0)
X FAIL ("find", "realloc", AF_ESYSERR, ERROR);
X set->af_setlen += AF_SEGLEN;
X }
X
X /* add revision to key-set */
X set->af_klist[set->af_nkeys].af_ldes = revlist[nlists-1];
X set->af_klist[set->af_nkeys].af_lpos = i;
X set->af_nkeys++;
X revlist[nlists-1]->af_refcount++;
X revlist[nlists-1]->af_list[i].af_nlinks++;
X } /* for all revisions in archive */
X
X /* if revlist does not contribute to hit set */
X if (revlist[nlists-1]->af_refcount <= 0)
X (void) af_detlist (revlist[nlists-1]);
X
X } /* for all archives */
X
X /* if set is empty */
X if (set->af_nkeys == 0)
X {
X free ((char *)set->af_klist);
X set->af_setlen = 0;
X }
X
X free ((char *)revlist);
X return (set->af_nkeys);
X}
X
X
X/*====================================================================
X * af_getkey
X *
X *====================================================================*/
X
XEXPORT af_getkey (syspath, name, type, gen, rev, variant, key)
X char *syspath, *name, *type;
X int gen, rev;
X /*ARGSUSED*/
X char *variant; /* unused */
X Af_key *key;
X{
X Af_revlist *list, *af_readattrs();
X char *path;
X bool mode = FALSE;
X
X /* build pathname (default is current directory) */
X path = af_uniqpath (syspath);
X
X if ((list = af_readattrs (path, name, type, &mode)) == (Af_revlist *)0)
X SFAIL ("getkey", "", AF_ENOREV, ERROR);
X key->af_ldes = list;
X
X /* handle special cases */
X if ((gen < 0) || (rev < 0))
X {
X switch (gen)
X {
X case AF_BUSYVERS: if (af_buildkey (list, gen, rev, key) == ERROR)
X SFAIL ("getkey", "", AF_ENOREV, ERROR);
X break;
X case AF_LASTVERS: if ((rev != AF_LASTVERS) || (list->af_nrevs == 0))
X SFAIL ("getkey", "", AF_ENOREV, ERROR);
X /* if busy version is valid */
X key->af_lpos = list->af_listlen-1;
X while (!(VATTR(key).af_class & AF_VALID) ||
X (VATTR(key).af_state == AF_BUSY))
X {
X if (key->af_lpos-- == 0)
X SFAIL ("getkey", "", AF_ENOREV, ERROR);
X }
X break;
X case AF_FIRSTVERS: if ((rev != AF_FIRSTVERS) || (list->af_nrevs == 0))
X SFAIL ("getkey", "", AF_ENOREV, ERROR);
X key->af_lpos = 0;
X while ((VATTR(key).af_state == AF_BUSY) ||
X (!(VATTR(key).af_class & AF_VALID)))
X {
X if (key->af_lpos++ == list->af_listlen-1)
X SFAIL ("getkey", "", AF_ENOREV, ERROR);
X }
X break;
X default: SFAIL ("getkey", "", AF_ENOREV, ERROR);
X }
X }
X else
X {
X if (af_buildkey (list, gen, rev, key) == ERROR)
X SFAIL ("getkey", "", AF_ENOREV, ERROR);
X }
X
X list->af_refcount++;
X VATTR(key).af_nlinks++;
X return (AF_OK);
X}
X
X
X/*====================================================================
X * af_dropkey
X *
X *====================================================================*/
X
XEXPORT af_dropkey (key)
X Af_key *key;
X{
X if (af_keytest (key))
X SFAIL ("dropkey", "", AF_EINVKEY, ERROR);
X
X /* decrease reference count in corresponding archive and in attrbuf */
X if (--(key->af_ldes)->af_refcount <= 0)
X (void) af_detlist (key->af_ldes);
X else
X VATTR(key).af_nlinks--;
X return (AF_OK);
X}
X
X
X/*====================================================================
X * af_initattrs
X *
X *====================================================================*/
X
XEXPORT af_initattrs (attrs)
X Af_attrs *attrs;
X{
X attrs->af_host[0] = '\0';
X attrs->af_syspath[0] = '\0';
X attrs->af_name[0] = '*';
X attrs->af_name[1] = '\0';
X attrs->af_type[0] = '*';
X attrs->af_type[1] = '\0';
X attrs->af_gen = AF_NOVNUM;
X attrs->af_rev = AF_NOVNUM;
X attrs->af_variant[0] = '\0';
X attrs->af_state = AF_NOSTATE;
X attrs->af_owner.af_username[0] = '\0';
X attrs->af_owner.af_userhost[0] = '\0';
X attrs->af_author.af_username[0] = '\0';
X attrs->af_author.af_userhost[0] = '\0';
X attrs->af_size = AF_NOSIZE;
X attrs->af_mode = AF_NOMODE;
X attrs->af_locker.af_username[0] = '\0';
X attrs->af_locker.af_userhost[0] = '\0';
X attrs->af_mtime = AF_NOTIME;
X attrs->af_atime = AF_NOTIME;
X attrs->af_ctime = AF_NOTIME;
X attrs->af_stime = AF_NOTIME;
X attrs->af_ltime = AF_NOTIME;
X attrs->af_udattrs[0] = (char *)0;
X}
X
END_OF_FILE
if test 16910 -ne `wc -c <'src/afs/afretr.c'`; then
echo shar: \"'src/afs/afretr.c'\" unpacked with wrong size!
fi
# end of 'src/afs/afretr.c'
fi
if test -f 'src/afsit/rcsit.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/afsit/rcsit.c'\"
else
echo shar: Extracting \"'src/afsit/rcsit.c'\" \(16773 characters\)
sed "s/^X//" >'src/afsit/rcsit.c' <<'END_OF_FILE'
X/*
X * $Header: rcsit.c,v 1.20 87/05/04 21:50:53 src Exp $
X *---------------------------------------------------------
X * $Source: /src/tools/rcs/src/rcsit/RCS/rcsit.c,v $
X * $Revision: 1.20 $
X * $Date: 87/05/04 21:50:53 $
X * $State: Exp $
X * $Author: src $
X * $Locker: src $
X *---------------------------------------------------------
X * Michael Cooper (mcooper@usc-oberon.arpa)
X * University of Southern California,
X * University Computing Services,
X * Los Angeles, California, 90089-0251
X * (213) 743-3469
X *---------------------------------------------------------
X *
X * $Log: rcsit.c,v $
X * Revision 1.20 87/05/04 21:50:53 src
X * added -F - flag. This option causes an additional header field for
X * inclusion of compile-time options into object-files to be inserted
X * into the C-source. The man-entry is also updated.
X *
X * Revision 1.19 86/06/12 20:29:43 src
X * The previous version was unable to look up templates in the
X * directory $TEMPLATES, when -t - option is absent but the
X * environment-variable TEMPLATES is set. Fixed that. If no -t - option
X * was given, but $TEMPLATES is non NULL, then -t is assumed and
X * $TEMPLATES is used as path to template-files.
X *
X * Revision 1.18 85/11/26 17:03:32 mcooper
X * Change message telling of what header was added.
X *
X * Revision 1.17 85/11/26 16:40:55 mcooper
X * Changed the default -t option to FALSE.
X * Added specifying directory to look for .template.*
X * files in via -tdirectory.
X *
X * Revision 1.16 85/11/11 21:35:34 mcooper
X * Added call to access() to see if the file
X * could be read.
X *
X * Revision 1.15 85/11/11 21:22:33 mcooper
X * Changed comment char for fortran files
X * from "*" to "c". This is what RCS uses.
X *
X * Revision 1.14 85/11/11 20:08:43 mcooper
X * Added descriptions for fortran (.f) files.
X *
X * Revision 1.13 85/11/11 19:52:17 mcooper
X * Modified default header templates to not bother specifying
X * the RCS file name of the file. co(1) worries about it.
X *
X * Revision 1.12 85/10/27 19:10:07 mcooper
X * Fixed bug that would not use template files if a file
X * type was forced with -c, -h, etc.
X *
X * Revision 1.11 85/10/27 18:48:27 mcooper
X * Extended template file. You can now have template
X * files describing all the types of files that
X * rcsit "knows" about. The file $HOME/.template.*
X * (where ``*'' is a ``.'' suffix rcsit can guess at or
X * the type of file that is specified with an override)
X * is checked for existance. If not present, the default
X * header (built into rcsit) will be used.
X *
X * Revision 1.10 85/10/27 16:15:53 mcooper
X * Added printing of what rcsit is doing if tflag is
X * true. Also added new headers.
X *
X * Revision 1.9 85/10/27 14:47:39 mcooper
X * Added new template feature. If the file
X * .template exists in the users HOME directory,
X * then that file is used as the header file instead
X * of the defaults for each type of file. This can
X * be disabled with the -t option in case the file
X * is say a shell script. With the template feature
X * turned off, the auto guessing is re-inabled.
X * Also, rcsit now removes its temporary files.
X *
X * Revision 1.8 85/09/28 14:11:45 mcooper
X * Added feature: if the environment variable RCSDIR is
X * present, rcsit will attempt to make a symbolic
X * link to the directory when the -I flag is used.
X * This is done only when -I is specified AND the
X * directory RCS is not present. You may disable this
X * feature with the -d option. Note also that if RCSDIR
X * is not in the environment and the above conditions
X * are true, that a normal directory called RCS will
X * be created.
X *
X * Revision 1.7 85/09/19 15:59:53 mcooper
X * Kludge part 2 -- If you specify a ci -l of a
X * man file, then the header is messed up.
X * Fix: After initializing the comment string,
X * unlink the file and then run co -l.
X *
X * Revision 1.6 85/09/19 15:39:57 mcooper
X * Now knows about ``Manual'' type files.
X *
X * Revision 1.5 85/09/19 14:23:24 mcooper
X * Added lineprint() function to print things out
X * nicely. Fixed bug for Manual type files. Due
X * to the fact that RCS does not not the suffixes of
X * manuals, it therefor does not know what kind of
X * comment string to use. Thus, I kludge by running
X * a ``rcs -c`... ' file'' to tell rcs the comment
X * string.
X *
X * Revision 1.4 85/09/19 13:28:22 mcooper
X * Fixed bug in auto_guess. Would not continue through function
X * when file type was ``Makefile''.
X *
X * Revision 1.3 85/09/19 13:19:50 mcooper
X * Added ``Shell Script'' file type.
X *
X * Revision 1.2 85/09/19 10:08:36 mcooper
X * Added code to run RCS commands (rcs & ci) on files.
X * Fixed bug that limited number of command line files specified to
X * nine. Several other minor fixes and improvements.
X *
X * Revision 1.1 85/09/17 11:33:33 mcooper
X * Initial revision
X *
X */
X
X/*
X * rcsit -- Prepare files for RCS. rcsit puts the correct headings
X * at the top of files to prepare them for RCS headings
X * and log tracking.
X *
X * Michael Cooper (mcooper@usc-oberon.arpa)
X * University Computing Services, USC
X *
X * 9-16-85
X */
X
X#include <sys/file.h>
X#include <stdio.h>
X#include <ctype.h>
X#include <strings.h>
X
X#ifdef NULL
X#undef NULL
X#endif
X#define NULL '\0'
X#define LENGTH 512 /* length of line */
X#define TRUE 1
X#define FALSE 0
X
X#ifdef DEBUG
X int debugon = TRUE;
X#else
X int debugon = FALSE;
X#endif
X
Xstatic char *progname; /* program name */
Xstatic char *rcsdir;
X
X/*
X * Messages to be printed for the user.
X */
Xstatic char *msg_name;
Xstatic char *m_stdc = "Standard C",
X *m_stdcflg = "Standard C with compile flags",
X *m_include = "C Include",
X *m_fortran = "Fortran",
X *m_pascal = "Pascal",
X *m_make = "Makefile",
X *m_shell = "Shell Script",
X *m_manual = "Manual";
X
X/*
X * The headers to put at the beginning of the file(s).
X * Notice that the words Header and Log do not appear here
X * because RCS will put in the keyword substitutions when rcsit.c
X * is co'ed.
X */
Xstatic char *header;
X#ifdef AFSIT
Xstatic char *h_stdc =
X "#ifndef lint\nstatic char *AFSid = \"$%s$\";\n#endif\n/*\n * $%s$\n */\n\n";
Xstatic char *h_stdcflg =
X "#ifndef lint\nstatic char *AFSid = \"$%s$\";\n#ifdef CFFLGS\n\
Xstatic char *ConfFlg = CFFLGS;\n\t/* should be defined from within\
X Makefile */\n#endif\n#endif\n/*\n * $%s$\n */\n\n";
X#else
Xstatic char *h_stdc =
X "#ifndef lint\nstatic char *RCSid = \"$%s$\";\n#endif\n/*\n * $%s$\n */\n\n";
Xstatic char *h_stdcflg =
X "#ifndef lint\nstatic char *RCSid = \"$%s$\";\n#ifdef CFFLGS\n\
Xstatic char *ConfFlg = CFFLGS;\n\t/* should be defined from within\
X Makefile */\n#endif\n#endif\n/*\n * $%s$\n */\n\n";
X#endif
Xstatic char *h_include =
X "/*\n * $%s$\n *\n * $%s$\n */\n\n";
Xstatic char *h_make =
X "#\n# $%s$\n#\n# $%s$\n#\n";
Xstatic char *h_manual =
X "...\n... $%s$\n... \n... $%s$\n...\n";
Xstatic char *h_fortran =
X "c\nc $%s$\nc\nc $%s$\nc\n";
X
X/*
X * Template file names
X */
Xstatic char *template_c = ".template.c"; /* .c template */
Xstatic char *template_h = ".template.h"; /* .h template */
Xstatic char *template_f = ".template.f"; /* .f template */
Xstatic char *template_p = ".template.p"; /* .p template */
Xstatic char *template_man = ".template.man"; /* man template */
Xstatic char *template_make = ".template.make"; /* make template */
Xstatic char *template_sh = ".template.sh"; /* sh script template */
Xstatic char *tpath; /* path to template */
Xstatic char tfile[BUFSIZ]; /* template file */
Xstatic char tbuf[BUFSIZ]; /* current tfile */
X
X/*
X * Command line flags
X */
Xint Iflag = FALSE; /* run ci(1) */
Xint rcsflag = FALSE; /* run rcs(1) */
Xint aflag = TRUE; /* do auto guess */
Xint dflag = TRUE; /* creat RCS dir. */
Xint qflag = FALSE; /* be quiet! */
Xint cflag = FALSE; /* std c file */
Xint fflag = FALSE; /* fortran file */
Xint Fflag = FALSE; /* insert C-Flags header */
Xint pflag = FALSE; /* pascal file */
Xint hflag = FALSE; /* include file */
Xint sflag = FALSE; /* shell script */
Xint mflag = FALSE; /* Makefile */
Xint Mflag = FALSE; /* manual */
Xint tflag = FALSE; /* template flag */
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X int x;
X char tmp[LENGTH];
X char *file;
X char *flags;
X char tmpfile[32];
X char *cp;
X char *mktemp();
X char *gettmp();
X char *getenv();
X FILE *fd,
X *fdtmp,
X *fopen();
X
X progname = (cp = rindex (argv[0], '/')) ? ++cp : argv[0];
X sprintf (tmpfile, "/tmp/%sXXXXXX", progname);
X for (x = 1; x < argc; x++) {
X if (argv[x][0] != '-')
X break;
X switch (argv[x][1]) {
X case 'a':
X aflag = FALSE;
X break;
X case 'q':
X qflag = TRUE;
X break;
X case 'd':
X dflag = FALSE;
X break;
X case 'f':
X fflag = TRUE;
X break;
X case 'F':
X Fflag = TRUE;
X cflag = TRUE; /* Only for C-files yet */
X break;
X case 'h':
X hflag = TRUE;
X break;
X case 's':
X sflag = TRUE;
X break;
X case 'm':
X mflag = TRUE;
X break;
X case 'M':
X Mflag = TRUE;
X break;
X case 'i':
X case 'I':
X Iflag = TRUE;
X flags = &argv[x][2];
X break;
X case 'r':
X case 'R':
X rcsflag = TRUE;
X flags = &argv[x][2];
X break;
X case 't':
X tflag = TRUE;
X tpath = &argv[x][2];
X break;
X case 'c':
X cflag = TRUE;
X break;
X default:
X fatal("Unknown flag %s.",argv);
X }
X }
X argc -= (x - 1);
X argv += (x - 1);
X
X if((hflag && (mflag || Mflag || cflag)) ||
X (mflag && (hflag || cflag || Mflag)) ||
X (Mflag && (cflag || hflag || mflag)) ||
X (cflag && (hflag || Mflag || mflag))) {
X fatal("Only ONE of -c,-f,-m,-M,-h,-s may be specified.");
X }
X if(Iflag && rcsflag) {
X fatal("Only ONE of ``-i'' and ``-r'' may be specified.");
X }
X
X if(cflag || hflag || mflag || Mflag || fflag || sflag)
X aflag = FALSE;
X
X if((rcsdir = getenv("RCSDIR")) == NULL)
X rcsdir = "RCS";
X if(Iflag && dflag)
X checkdir(); /* Make RCS directory for ci */
X if((!tflag) && ((tpath = getenv ("TEMPLATE")) != NULL))
X tflag = TRUE; /* fixed by axel@coma.uucp */
X if((*tpath == NULL) && ((tpath = getenv("TEMPLATE")) == NULL))
X if((tpath = getenv("HOME")) == NULL)
X fatal("Cannot find environment variable HOME or TEMPLATE");
X
X /*
X * make tmp file once.
X */
X mktemp(tmpfile);
X
X while (--argc) { /* Main loop */
X file = *++argv;
X debug(sprintf(tmp, "...file (*++argv) = %s...", file));
X
X if(access(file, 4) != 0)
X fatal("Cannot access %s. No read permission OR file does not exist.",
X file);
X if((fdtmp = fopen(tmpfile, "w")) == NULL) {
X fatal("Cannot open tmpfile (%s).", tmpfile);
X }
X
X if(aflag)
X auto_guess(file); /* try and guess file type */
X else
X set_flags(); /* check and set flags */
X
X if(tflag) {
X /*
X * first get names of templates, then create
X * path name to it.
X */
X get_temp();
X sprintf(tfile, "%s/%s", tpath, tbuf);
X }
X if(access(tfile, 0) == 0 && tflag) {
X if(!qflag || debugon)
X printf("Adding %s header file to %s...",
X msg_name, file);
X copy(tfile, tmpfile, "w");
X copy(file, tmpfile, "a");
X } else {
X if(!qflag || debugon)
X printf(
X "Adding default header (%s format) to %s...",
X msg_name, file);
X /*
X * put the Keywords into header string
X */
X#ifdef AFSIT
X sprintf(tmp, header, "__Header", "__Log");
X#else
X sprintf(tmp, header, "Header", "Log");
X#endif
X fputs(tmp, fdtmp);
X /*
X * fclose'em, just in case.
X */
X fclose(fdtmp);
X copy(file, tmpfile, "a");
X }
X unlink(file);
X copy(tmpfile, file, "w");
X unlink(tmpfile);
X
X if(!qflag || debugon)
X printf("done.\n");
X if (Fflag)
X puts ("-> Don't forget to define CFFLGS on compiler\
X commandline <-\n");
X
X if(Iflag){
X rcs("ci", file, flags);
X if(Mflag){ /* kludge to tell rcs about manuals */
X rcs("rcs", file, "c'... '");
X /*
X * kludge part 2 - if the user tried a ci
X * with a -l option, then the header is
X * messed up in the currently checked out
X * man file. So we have to co the file to
X * clean up the header. Plus we use the
X * -l option of co to insure file locking.
X */
X if(checkfor("l", flags)){
X unlink(file);
X rcs("co", file, "l");
X }
X }
X }
X if(rcsflag)
X rcs("rcs", file, flags);
X }
X}
X
X/*
X * debug - print (useless) debugging info.
X */
X
Xdebug(msg)
Xchar *msg;
X{
X#ifdef DEBUG
X fprintf(stderr, msg);
X putchar ('\n');
X#endif
X}
X
X/*
X * auto_guess - try and be intelligent and guess type of file
X * by looking at the suffix or the whole name
X * in the case of a makefile.
X */
X
Xauto_guess(file)
Xchar *file;
X{
X char *suffix;
X char *rindex();
X
X suffix = rindex(file, '.')+1;
X if((strcmp(file, "makefile") == 0) || (strcmp(file, "Makefile") == 0) ||
X (strcmp(suffix, "mk") == 0)) { /* sys V std suffix */
X mflag = TRUE;
X sflag = FALSE;
X cflag = FALSE;
X hflag = FALSE;
X Mflag = FALSE;
X fflag = FALSE;
X }
X if((strcmp(suffix, "sh") == 0) || (strcmp(suffix, "csh") == 0)) {
X sflag = TRUE;
X cflag = FALSE;
X hflag = FALSE;
X mflag = FALSE;
X Mflag = FALSE;
X fflag = FALSE;
X }
X if(strcmp(suffix, "c") == 0){
X cflag = TRUE;
X hflag = FALSE;
X mflag = FALSE;
X Mflag = FALSE;
X sflag = FALSE;
X fflag = FALSE;
X }
X if(strcmp(suffix, "h") == 0){
X hflag = TRUE;
X cflag = FALSE;
X mflag = FALSE;
X Mflag = FALSE;
X sflag = FALSE;
X fflag = FALSE;
X }
X if(strcmp(suffix, "f") == 0){
X fflag = TRUE;
X hflag = FALSE;
X cflag = FALSE;
X mflag = FALSE;
X Mflag = FALSE;
X sflag = FALSE;
X }
X if(isdigit(*suffix) != 0) {
X Mflag = TRUE;
X hflag = FALSE;
X cflag = FALSE;
X mflag = FALSE;
X sflag = FALSE;
X fflag = FALSE;
X }
X set_flags();
X if(!qflag || debugon)
X printf("Hmm. This file looks like a %s file.\n", msg_name);
X}
X
X/*
X * set_flags - set & check flags
X */
X
Xset_flags()
X{
X if(cflag || hflag || mflag || Mflag || sflag || fflag) {
X if(cflag) {
X msg_name = m_stdc;
X header = h_stdc;
X }
X if (Fflag) { /* This is more than just cflag - axel@coma */
X msg_name = m_stdcflg;
X header = h_stdcflg;
X }
X if(hflag) {
X msg_name = m_include;
X header = h_include;
X }
X if(mflag) {
X msg_name = m_make;
X header = h_make;
X }
X if(Mflag) {
X msg_name = m_manual;
X header = h_manual;
X }
X if(sflag) {
X msg_name = m_shell;
X header = h_make;
X }
X if(fflag) {
X msg_name = m_fortran;
X header = h_fortran;
X }
X } else {
X cflag = TRUE;
X set_flags();
X }
X}
X
X/*
X * copy from -> to
X */
X
Xcopy(from, to, mode)
Xchar *from;
Xchar *to;
Xchar *mode;
X{
X FILE *fdfrom, *fdto, *fopen();
X char tmp[LENGTH];
X char s[LENGTH];
X
X if((fdfrom = fopen(from, "r")) == NULL) {
X fatal("Cannot open %s for reading.",from);
X }
X if((fdto = fopen(to, mode)) == NULL) {
X fatal("Cannot open %s for \"%s\".",to,mode);
X }
X while(fgets(s, sizeof(s), fdfrom) != NULL)
X fputs(s, fdto);
X fclose(fdfrom);
X fclose(fdto);
X}
X
X/*
X * Run RCS's rcsprog on file with flags.
X */
X
Xrcs(rcsprog, file, flags)
Xchar *rcsprog;
Xchar *file;
Xchar *flags;
X{
X char buf[LENGTH];
X char tmp[LENGTH];
X
X if(!checkfor("q", flags) && qflag)
X flags = "q";
X if(strcmp(flags, NULL) == 0)
X sprintf(buf, "%s %s", rcsprog, file);
X else
X sprintf(buf, "%s -%s %s", rcsprog, flags, file);
X debug(sprintf(tmp,"Running ``%s''...\n", buf));
X if(!qflag)
X lineprint(sprintf(tmp, "Start of ``%s''", buf));
X system(buf);
X if(!qflag)
X lineprint(sprintf(tmp, "End of ``%s''", buf));
X}
X
X/*
X * checkdir - make RCS directory if not present.
X */
X
Xcheckdir()
X{
X if(access("RCS", 0) != 0){
X if(!qflag || debugon)
X printf("Cannot find \"RCS\" directory. Creating...\n");
X if(strcmp(rcsdir, "RCS") != 0) {
X if(symlink(rcsdir, "RCS") != 0)
X fatal("Symbolic link of %s to RCS failed.",
X rcsdir);
X } else {
X if(mkdir(rcsdir, 0755) != 0)
X fatal("Cannot create \"%s\" directory.",
X rcsdir);
X }
X }
X}
X
X/*
X * checkfor(x, str) -- check for x in str. Return 1 (TRUE) if exists.
X * Otherwise 0 (FALSE).
X */
X
Xcheckfor(x, str)
Xchar *x;
Xchar *str;
X{
X while(*str) {
X if(strcmp(str, x) == 0)
X return(TRUE);
X *str++;
X }
X return(FALSE);
X}
X
X/*
X * lineprint - print msg in a nice line
X */
X
Xlineprint(msg)
Xchar *msg;
X{
X int len, left, right, x;
X
X len = strlen(msg);
X right = (75-len)/2;
X left = right;
X for(x = 0; x < right; ++x)
X putchar('-');
X printf("[ %s ]", msg);
X for(x = 0; x < left; ++x)
X putchar('-');
X putchar('\n');
X}
X
X/*
X * fatal - print error and then exit(1).
X */
Xfatal(format, str)
Xchar *format;
X{
X static char namefmt[100];
X
X sprintf(namefmt, "%s: %s\n", progname, format);
X _doprnt(namefmt, &str, stderr);
X exit(1);
X}
X
X/*
X * zap str with NULL's
X */
X
Xzap(str)
Xchar str[];
X{
X int i, x;
X
X i = strlen(str);
X for(x = 0; x <= i; )
X str[x++] = NULL;
X}
X
X/*
X * get template names
X */
X
Xget_temp()
X{
X zap(tbuf);
X if(mflag)
X strcpy(tbuf, template_make);
X if(Mflag)
X strcpy(tbuf, template_man);
X if(hflag)
X strcpy(tbuf, template_h);
X if(cflag)
X strcpy(tbuf, template_c);
X if(sflag)
X strcpy(tbuf, template_sh);
X if(fflag)
X strcpy(tbuf, template_f);
X}
END_OF_FILE
if test 16773 -ne `wc -c <'src/afsit/rcsit.c'`; then
echo shar: \"'src/afsit/rcsit.c'\" unpacked with wrong size!
fi
# end of 'src/afsit/rcsit.c'
fi
echo shar: End of archive 18 \(of 33\).
cp /dev/null ark18isdone
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