rsalz@uunet.uu.net (Rich Salz) (06/05/89)
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 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.