v19i028: A software configuration management system, Part15/33
Rich Salz
rsalz at uunet.uu.net
Tue Jun 6 00:25:54 AEST 1989
Submitted-by: Axel Mahler <unido!coma!axel>
Posting-number: Volume 19, Issue 28
Archive-name: shape/part15
#! /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 15 (of 33)."
# Contents: src/afs/afvers.c src/misc/ParseArgs.c src/shape/misc.c
# src/vc/retrv.c
# Wrapped by rsalz at papaya.bbn.com on Thu Jun 1 19:27:05 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/afs/afvers.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/afs/afvers.c'\"
else
echo shar: Extracting \"'src/afs/afvers.c'\" \(13536 characters\)
sed "s/^X//" >'src/afs/afvers.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 at coma.uucp or shape at db0tui62.bitnet
X */
X/*LINTLIBRARY*/
X/*
X * Shape/AFS
X *
X * afversions.c - operations on revisions
X *
X * Author: Andreas Lampen, TU-Berlin (andy at coma.UUCP
X * andy at db0tui62.BITNET)
X *
X * $Header: afvers.c[1.3] Wed Feb 22 16:28:25 1989 andy at coma published $
X *
X * EXPORT:
X * af_savebinary -- save derived file
X * af_saverev -- save busy version
X * af_newgen -- increase gen number and reset rev number
X * af_setbusy -- set revision busy
X * af_svnum -- set version number
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
X#include "typeconv.h"
X#include "afsys.h"
X#include "afs.h"
X
X/*====================================================================
X * af_savebinary
X *
X *====================================================================*/
X
XEXPORT af_savebinary (busykey, savekey)
X Af_key *busykey;
X Af_key *savekey; /* out */
X{
X int oldpredgen, oldpredrev;
X short oldnlinks;
X time_t oldatime;
X
X if (af_keytest (busykey))
X SFAIL ("savebinary", "", AF_EINVKEY, ERROR);
X
X if (VATTR(busykey).af_state != AF_BUSY)
X SFAIL ("savebinary", "", AF_ENOTBUSY, ERROR);
X
X if ((VATTR(busykey).af_mode & S_IFMT) != S_IFREG)
X SFAIL ("savebinary", "", AF_ENOTREGULAR, ERROR);
X
X if (VATTR(busykey).af_nlinks > 1)
X af_wng ("savebinary", "busykey has more than one reference");
X
X if (af_checkperm (busykey, AF_WORLD) == ERROR)
X return (ERROR);
X
X /* this then part is a little bit "hacked", it should better look like:
X *
X * get key for new bp entry
X * modify attributes
X * add new file to binary pool
X */
X
X /* modify some attributes for saving */
X VATTR(busykey).af_state = AF_NOSTATE;
X VATTR(busykey).af_class |= AF_DERIVED;
X oldatime = VATTR(busykey).af_atime;
X VATTR(busykey).af_atime = (time_t) af_acttime ();
X oldpredgen = VATTR(busykey).af_predgen;
X VATTR(busykey).af_predgen = AF_NOVNUM;
X oldpredrev = VATTR(busykey).af_predrev;
X VATTR(busykey).af_predrev = AF_NOVNUM;
X oldnlinks = VATTR(busykey).af_nlinks;
X VATTR(busykey).af_nlinks = 1;
X
X if (af_rplbpentry ((Af_key *)0, busykey, savekey) == ERROR)
X return (ERROR);
X
X /* restore attributes */
X VATTR(busykey).af_state = AF_BUSY;
X VATTR(busykey).af_class &= ~AF_DERIVED;
X VATTR(busykey).af_atime = oldatime;
X VATTR(busykey).af_predgen = oldpredgen;
X VATTR(busykey).af_predrev = oldpredrev;
X VATTR(busykey).af_nlinks = oldnlinks;
X
X /* update binary pool descriptor */
X savekey->af_ldes->af_refcount++;
X
X return (AF_OK);
X}
X
X
X/*====================================================================
X * af_saverev
X *
X *====================================================================*/
X
XEXPORT af_saverev (busykey, savekey)
X
X Af_key *busykey;
X Af_key *savekey; /* out */
X{
X Af_key *lastkey, predkey, *af_glastkey();
X Af_user *author;
X struct stat ibuf;
X int af_fhash();
X
X if (af_keytest (busykey))
X SFAIL ("saverev", "", AF_EINVKEY, ERROR);
X
X if (VATTR(busykey).af_state != AF_BUSY)
X SFAIL ("saverev", "", AF_ENOTBUSY, ERROR);
X
X if ((VATTR(busykey).af_mode & S_IFMT) != S_IFREG)
X SFAIL ("saverev", "", AF_ENOTREGULAR, ERROR);
X
X if (af_checkperm (busykey, AF_LOCKHOLDER) == ERROR)
X SFAIL ("saverev", "", AF_ENOTLOCKED, ERROR);
X
X /* get attribute buffer (pointed to by "savekey") for new version */
X if (af_newvers (busykey->af_ldes, savekey, AF_SOURCE) == ERROR)
X return (ERROR);
X
X /* set key and attributes of new version */
X VATTR(savekey).af_name = VATTR(busykey).af_name;
X VATTR(savekey).af_type = VATTR(busykey).af_type;
X VATTR(savekey).af_lckname = VATTR(busykey).af_lckname;
X VATTR(savekey).af_lckhost = VATTR(busykey).af_lckhost;
X VATTR(savekey).af_ltime = (time_t) af_acttime ();
X
X /* if there is only one (the busy-) revision (..nrevs == 1) */
X /* then do initial save */
X if (busykey->af_ldes->af_nrevs == 1)
X {
X VATTR(savekey).af_gen = AF_INITGEN;
X VATTR(savekey).af_rev = AF_INITREV;
X VATTR(savekey).af_predgen = AF_NOVNUM;
X VATTR(savekey).af_predrev = AF_NOVNUM;
X VATTR(busykey).af_predgen = AF_INITGEN;
X VATTR(busykey).af_predrev = AF_INITREV;
X (void) af_nodelta (busykey, savekey);
X }
X else /* get some attributes from preceding revision */
X {
X lastkey = af_glastkey (busykey->af_ldes);
X VATTR(savekey).af_gen = VATTR(lastkey).af_gen;
X VATTR(savekey).af_rev = VATTR(lastkey).af_rev+1;
X VATTR(savekey).af_predgen = VATTR(busykey).af_predgen;
X VATTR(savekey).af_predrev = VATTR(busykey).af_predrev;
X VATTR(busykey).af_predgen = VATTR(savekey).af_gen;
X VATTR(busykey).af_predrev = VATTR(savekey).af_rev;
X if (af_buildkey (busykey->af_ldes, VATTR(savekey).af_predgen, VATTR(savekey).af_predrev, &predkey) == ERROR)
X predkey.af_ldes = (Af_revlist *)0;
X (void) af_dodelta (busykey, &predkey, savekey);
X }
X
X if (VATTR(busykey).af_variant)
X VATTR(savekey).af_variant = VATTR(busykey).af_variant;
X else
X VATTR(savekey).af_variant = (char *)0;
X
X VATTR(savekey).af_state = AF_SAVED;
X VATTR(savekey).af_class = VATTR(busykey).af_class;
X author = af_getuser (getuid());
X VATTR(savekey).af_auname = af_entersym (author->af_username);
X VATTR(savekey).af_auhost = af_enterhost (author->af_userhost);
X (void) lstat (busykey->af_ldes->af_busyfilename, &ibuf);
X VATTR(savekey).af_mode = ibuf.st_mode;
X VATTR(savekey).af_mtime = (time_t) af_cvttime (ibuf.st_mtime);
X VATTR(savekey).af_atime = (time_t) af_acttime ();
X VATTR(savekey).af_ctime = (time_t) af_cvttime (ibuf.st_mtime);
X VATTR(savekey).af_stime = (time_t) af_acttime ();
X VATTR(savekey).af_notesize = 1;
X VATTR(savekey).af_note = (char *)0;
X VATTR(savekey).af_nlinks = 1;
X
X VATTR(savekey).af_udanum = VATTR(busykey).af_udanum;
X (void) af_hashinit (&(VATTR(savekey).af_uhtab), AF_MAXUDAS, af_fhash);
X (void) af_hashcopy (&(VATTR(busykey).af_uhtab), &(VATTR(savekey).af_uhtab));
X
X VATTR(savekey).af_hashname = (char *)0;
X VATTR(savekey).af_succgen = AF_NOVNUM;
X VATTR(savekey).af_succrev = AF_NOVNUM;
X
X /* update list descriptor */
X busykey->af_ldes->af_nrevs++;
X busykey->af_ldes->af_datasize += VATTR(savekey).af_notesize;
X busykey->af_ldes->af_refcount++;
X
X /* save changes */
X if (af_addvers (savekey) == ERROR)
X return (ERROR);
X
X return (AF_OK);
X} /* af_saverev */
X
X
X
X/*====================================================================
X * af_newgen
X *
X *====================================================================*/
X
XEXPORT af_newgen (key, newkey)
X Af_key *key;
X Af_key *newkey; /* out */
X{
X Af_key *lastkey, *busykey, *af_gbuskey(), *af_glastkey();
X int af_fhash();
X
X if (af_keytest (key))
X SFAIL ("newgen", "", AF_EINVKEY, ERROR);
X
X if (key->af_ldes->af_nrevs == 1)
X SFAIL ("newgen", "", AF_ENOTVERS, ERROR);
X
X if (VATTR(key).af_class & AF_DERIVED)
X SFAIL ("newgen", "", AF_EDERIVED, ERROR);
X
X if ((VATTR(key).af_mode & S_IFMT) != S_IFREG)
X SFAIL ("newgen", "", AF_ENOTREGULAR, ERROR);
X
X busykey = af_gbuskey (key->af_ldes);
X if (af_checkperm (busykey, AF_LOCKHOLDER) == ERROR)
X SFAIL ("newgen", "", AF_ENOTLOCKED, ERROR);
X
X if (af_newvers (key->af_ldes, newkey, AF_SOURCE) == ERROR)
X return (ERROR);
X
X lastkey = af_glastkey (key->af_ldes);
X
X if ((VATTR(key).af_predgen == VATTR(lastkey).af_gen) &&
X (VATTR(key).af_predrev == VATTR(lastkey).af_rev))
X {
X VATTR(key).af_predgen++;
X VATTR(key).af_predrev = 0;
X }
X
X /* duplicate last revision */
X
X VATTR(newkey).af_gen = VATTR(lastkey).af_gen+1;
X VATTR(newkey).af_rev = 0;
X VATTR(newkey).af_variant = VATTR(lastkey).af_variant;
X VATTR(newkey).af_predgen = VATTR(lastkey).af_gen;
X VATTR(newkey).af_predrev = VATTR(lastkey).af_rev;
X
X (void) af_dodelta ((Af_key *)0, lastkey, newkey);
X
X VATTR(newkey).af_name = VATTR(lastkey).af_name;
X VATTR(newkey).af_type = VATTR(lastkey).af_type;
X VATTR(newkey).af_variant = VATTR(lastkey).af_variant;
X VATTR(newkey).af_state = VATTR(lastkey).af_state;
X VATTR(newkey).af_class = VATTR(lastkey).af_class;
X VATTR(newkey).af_auname = VATTR(lastkey).af_auname;
X VATTR(newkey).af_auhost = VATTR(lastkey).af_auhost;
X VATTR(newkey).af_mode = VATTR(lastkey).af_mode;
X VATTR(newkey).af_mtime = VATTR(lastkey).af_mtime;
X VATTR(newkey).af_atime = VATTR(lastkey).af_atime;
X VATTR(newkey).af_ctime = VATTR(lastkey).af_ctime;
X VATTR(newkey).af_stime = VATTR(lastkey).af_stime;
X VATTR(newkey).af_notesize = VATTR(lastkey).af_notesize;
X VATTR(newkey).af_note = VATTR(lastkey).af_note;
X VATTR(newkey).af_lckname = (char *)0;
X VATTR(newkey).af_lckhost = (char *)0;
X VATTR(newkey).af_nlinks = 1;
X
X VATTR(newkey).af_udanum = VATTR(lastkey).af_udanum;
X (void) af_hashinit (&(VATTR(newkey).af_uhtab), AF_MAXUDAS, af_fhash);
X (void) af_hashcopy (&(VATTR(lastkey).af_uhtab), &(VATTR(newkey).af_uhtab));
X
X VATTR(newkey).af_succgen = AF_NOVNUM;
X VATTR(newkey).af_succrev = AF_NOVNUM;
X
X /* update list descriptor */
X key->af_ldes->af_nrevs++;
X key->af_ldes->af_datasize += VATTR(newkey).af_notesize;
X
X /* update predecessor of busy version */
X if ((VATTR(busykey).af_predgen == VATTR(lastkey).af_gen) &&
X (VATTR(busykey).af_predrev == VATTR(lastkey).af_rev))
X {
X VATTR(busykey).af_predgen = VATTR(newkey).af_gen;
X VATTR(busykey).af_predrev = VATTR(newkey).af_rev;
X }
X
X if (af_addvers (newkey) == ERROR)
X return (ERROR);
X
X key->af_ldes->af_refcount++;
X return (AF_OK);
X}
X
X
X/*====================================================================
X * af_setbusy
X *
X *====================================================================*/
X
XEXPORT af_setbusy (busykey, newkey)
X Af_key *busykey, *newkey;
X{
X Af_key *af_gbuskey();
X
X if (af_keytest (newkey))
X SFAIL ("setbusy", "", AF_EINVKEY, ERROR);
X
X if (busykey != (Af_key *)0)
X {
X if (af_keytest (busykey))
X SFAIL ("setbusy", "", AF_EINVKEY, ERROR);
X if (VATTR(busykey).af_state != AF_BUSY)
X SFAIL ("setbusy", "", AF_ENOTBUSY, ERROR);
X if (VATTR(busykey).af_class & AF_DERIVED)
X SFAIL ("setbusy", "", AF_EDERIVED, ERROR);
X }
X else
X {
X busykey = af_gbuskey (newkey->af_ldes);
X }
X
X if (af_checkperm (busykey, AF_LOCKHOLDER) == ERROR)
X SFAIL ("setbusy", "", AF_ENOTLOCKED, ERROR);
X
X /* if the two versions belong to one line of development */
X if (busykey->af_ldes->af_busyfilename == newkey->af_ldes->af_busyfilename)
X {
X VATTR(busykey).af_predgen = VATTR(newkey).af_gen;
X VATTR(busykey).af_predrev = VATTR(newkey).af_rev;
X }
X else
X {
X VATTR(busykey).af_predgen = AF_NOVNUM;
X VATTR(busykey).af_predrev = AF_NOVNUM;
X }
X if (af_updtvers (busykey, AF_CHANGE) == ERROR)
X return (ERROR);
X
X return (AF_OK);
X}
X
X
X/*====================================================================
X * af_svnum
X *
X *====================================================================*/
X
XEXPORT af_svnum (key, gen, rev)
X Af_key *key;
X int gen, rev;
X{
X Af_key predkey, *lastkey, *af_glastkey();
X
X if (af_keytest (key))
X SFAIL ("svnum", "", AF_EINVKEY, ERROR);
X
X if ((VATTR(key).af_state == AF_BUSY) || (VATTR(key).af_state > AF_PROPOSED))
X SFAIL ("svnum", "", AF_EWRONGSTATE, ERROR);
X
X if (!(VATTR(key).af_class & AF_DERIVED)) /* derived files can get any vnum */
X {
X if (af_checkperm (key, AF_LOCKHOLDER) == ERROR)
X SFAIL ("svnum", "", AF_ENOTLOCKED, ERROR);
X
X /* only the version number of the last saved version can be modified */
X lastkey = af_glastkey (key->af_ldes);
X if (af_keycmp (key, lastkey))
X SFAIL ("svnum", "can set version number only for last saved version",
X AF_EMISC, ERROR);
X
X /* if new version number is smaller than the old one */
X if (gen < VATTR(key).af_gen)
X SFAIL ("svnum", "", AF_EINVVNUM, ERROR);
X if (gen == VATTR(key).af_gen)
X {
X if (rev < VATTR(key).af_rev)
X SFAIL ("svnum", "", AF_EINVVNUM, ERROR);
X }
X /* read data file in order to get it updated */
X if (af_readdata (key->af_ldes) == ERROR)
X return (ERROR);
X }
X
X VATTR(key).af_gen = (short)gen;
X VATTR(key).af_rev = (short)rev;
X
X /* if a predecessor exists, update its successor field */
X if (af_buildkey (key->af_ldes, VATTR(key).af_predgen,
X VATTR(key).af_predrev, &predkey) == AF_OK)
X {
X VATTR((&predkey)).af_succgen = (short)gen;
X VATTR((&predkey)).af_succrev = (short)rev;
X }
X
X /* the predecessor is updated implicitely by af_updtvers (key) */
X if (af_updtvers (key, AF_CHANGE) == ERROR)
X return (ERROR);
X
X return (AF_OK);
X}
X
END_OF_FILE
if test 13536 -ne `wc -c <'src/afs/afvers.c'`; then
echo shar: \"'src/afs/afvers.c'\" unpacked with wrong size!
fi
# end of 'src/afs/afvers.c'
fi
if test -f 'src/misc/ParseArgs.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/misc/ParseArgs.c'\"
else
echo shar: Extracting \"'src/misc/ParseArgs.c'\" \(12926 characters\)
sed "s/^X//" >'src/misc/ParseArgs.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 at coma.uucp or shape at db0tui62.bitnet
X */
Xstatic char *AFSid = "$Header: ParseArgs.c[2.1] Thu Feb 23 21:24:12 1989 axel at coma published $";
X
X/*
X * Log for /u/shape/dist-tape/src/misc/ParseArgs.c[1.1]
X * Thu Feb 23 21:24:12 1989 axel at coma save $
X * --- empty log message ---
X * ParseArgs.c[2.0] Thu Feb 23 21:24:12 1989 axel at coma published $
X * --- empty log message ---
X * ParseArgs.c[2.1] Thu Feb 23 21:24:12 1989 axel at coma published $
X * --- empty log message ---
X */
X
X#include <stdio.h>
X#include <strings.h>
X
X#include "ParseArgs.h"
X
Xstatic char *RCSid = "$Header: ParseArgs.c,v 2.0 88/06/29 16:14:32 axel Stable $";
X#ifdef CFFLGS
Xstatic char *Cflags = CFFLGS;
X#endif CFFLGS
X
X/*
X * $Log: ParseArgs.c,v $
X * Revision 2.0 88/06/29 16:14:32 axel
X * New System Generation
X *
X * Revision 1.1 88/06/07 17:10:01 axel
X * This version is part of a release
X *
X * Revision 1.8 88/03/12 20:34:34 uli
X * *** empty log message ***
X *
X * Revision 1.7 88/03/10 14:06:47 uli
X * ParseArgs returns now the number of error encountered during parse.
X * A return value of 0 means no error. This is incompatible to the previous
X * versions. Is this a so called "variant" ? Should i release the previous
X * version ?
X * Uli
X *
X * Revision 1.6 88/03/08 20:48:53 uli
X * blabla.
X *
X * Revision 1.5 88/03/08 20:03:01 uli
X * pa_ShortUsage added. If called, builds a usage.
X *
X * Revision 1.4 88/03/08 15:34:58 uli
X * Order of options is no longer important. Options are rearrange in
X * longest first order.
X *
X * Revision 1.3 88/03/04 15:36:23 uli
X * Some bugs fixed.
X *
X *
X * Revision 1.2 88/02/23 13:53:34 uli
X * Error in ParseArguments fixed: newav is now (unsigned long*).
X *
X * Revision 1.1 88/02/23 12:42:27 uli
X * Initial revision
X *
X * Revision 1.2 88/02/18 14:33:52 uli
X * *** empty log message ***
X *
X */
X
X/*
X * Exports:
X *
X * Type: OptDesc;
X * Function: ParseArgs (ac, av, newac, newav, optdesc)
X * int ac;
X * char **av;
X * int newac;
X * char **newav;
X * OptDesc *optdesc;
X *
X * ParseArgs returns 1 on success, 0 on failure.
X *
X */
X
X/*
X * Description:
X *
X * ParseArgs scans and tokenizes the argument string in its components.
X * Components are the name of the called program, the options, the
X * arguments of options, and the pure arguments (i.e. non options).
X *
X * An Option is specified by its name, kind, and a function, that
X * handles this option. Name is a (possible multi character) string.
X * The kind specifies iff the option is an ordinary switch,
X * an options with an optional argument, * or an option that
X * requires an argument. The function is called whenever the options
X * is detected in the argument string. The number of the function
X * parameters depends on the options' kind. The detected option
X * is passed everytime as the first parameter. If this option
X * has a (possible optional) argument, it is passed to the handler as the
X * second parameter. If the argument is missed in the argument string,
X * then a string which contains only a null byte is passed to the handler.
X *
X * Example:
X *
X * OptDesc odesc[] = {
X * { "l", OPT_IS_SWITCH, handle_i_option },
X * { "f", OPT_HAS_ARG, handle_f_options },
X * { "o", OPT_HAS_OPT_ARG, handle_o_option}
X * }
X *
X * In this example we have declared 'l', 'f', and 'o' to be options.
X * 'l' is a ordinary switch, 'f' requires an argument, and 'o' may
X * have an argument. Handle_i_options, handle_f_option, and
X * and handle_o_option are the option handlers called. The handler
X * are declared:
X *
X * int handle_i_option (option)
X * char *option;
X *
X * int handle_f_option (option, options_argument);
X * char *option, *options_argument;
X *
X * int handle_o_option (option, options_argument);
X * char *option, *options_argument;
X *
X * Everytime '-i' is detected, handle_i_option is called
X * handle_i_option ("i");
X * handle_f_option is called
X * handle_f_option ("f", argument);
X * and handle_o_option is called
X * handle_o_option ("o", argument);
X *
X * If the argument of the options 'f' or 'o' are missed,
X * the handler are called with
X * handler ("<options name>", "");
X *
X *
X * BUGS:
X * The longest options is matched. If you have declared
X * 'o' as an options with an argument and 'op' as a
X * switch, the option 'o' is never detected, because
X * 'op' is longer.
X */
X
X/*
X * Externals
X */
Xextern char *malloc();
X
X#define MINUS_CHAR_REQUIRED 1
X
X/*
X * Variables
X */
X
X#ifdef DEBUG_PARSE
Xstatic int debug_parse = 0;
X#endif DEBUG_PARSE
X
Xstatic
Xint GetNextOption (str, odesc, minus_char_required)
X char *str;
X OptDesc odesc[];
X int minus_char_required;
X{
X int i, j;
X
X if (!str) return -1;
X
X if (minus_char_required) {
X if (*str != '-')
X return -1;
X }
X
X if (*str == '-') {
X str++;
X }
X
X for (i = 0; odesc[i].opt_name; i++) {
X if (!(j = strncmp (odesc[i].opt_name,
X str, strlen (odesc[i].opt_name))))
X return i;
X }
X return -1;
X}
X
X
Xstatic
Xint IsOption (str, odesc, minus_char_required)
X char *str;
X OptDesc odesc[];
X int minus_char_required;
X{
X return (GetNextOption (str, odesc, minus_char_required) >= 0 ? 1 : 0);
X}
X
Xstatic
Xchar *SkipThisOption (str, length)
X char *str;
X int length;
X{
X if (*str == '-') str++;
X return (str + length);
X}
X
Xstatic
Xint cmp_length (left, right)
X OptDesc *left, *right;
X{
X return (strlen (right->opt_name) - strlen (left->opt_name));
X}
X
Xstatic
Xint cmp_alpha (left, right)
X OptDesc *left, *right;
X{
X return (strcmp (left->opt_name, right->opt_name));
X}
X
Xstatic
Xint RearrangeOptDesc (odesc, cmp_function)
X OptDesc *odesc;
X int (*cmp_function)(); /* function that compares */
X{
X int nelem;
X
X for (nelem = 0; odesc[nelem].opt_name; nelem++) ;
X
X qsort (odesc, nelem, sizeof (struct optdesc), cmp_function);
X}
X
Xint ParseArgs (pac, pav, newac, newav, odesc)
X int pac; /* number arguments */
X char **pav; /* the arguments itself */
X int *newac; /* number arguments after parsing */
X unsigned long *newav; /* the arguments after parsing */
X OptDesc odesc[]; /* the options descriptions */
X{
X
X char **cpp; /* temporary points to pav */
X char **ArgV;
X char *this_arg; /* points to the current argument */
X int option, minus_char_required, opterr = 0;
X char *optrepr;
X int optkind;
X int (*opthandler)();
X
X /*
X * inititialization phase
X */
X *newac = 0;
X
X /* allocate some memory for newav */
X if ((ArgV = (char **) malloc (sizeof (char **) * (pac + 1))) == (char **) NULL) {
X perror ("malloc");
X exit (1);
X }
X
X RearrangeOptDesc (odesc, cmp_length); /* sort by length */
X
X#ifdef DEBUG_PARSE
X if (!strcmp (pav[1], "\001\002")) { /* ^A^B */
X debug_parse++;
X fprintf (stderr, "ParseArgs: debugging enabled.\n");
X }
X#endif DEBUG_PARSE
X
X /*
X * scanning phase
X */
X pav++; /* skip program name */
X
X#ifdef DEBUG_PARSE
X if (debug_parse) pav++;
X#endif DEBUG_PARSE
X
X while (pav && *pav) {
X this_arg = *pav; /* beginning of next argument */
X minus_char_required = 1; /* require a '-' if argument is a option */
X
X while (this_arg && *this_arg) {
X if ((option = GetNextOption (this_arg, odesc, minus_char_required)) >= 0) {
X optrepr = odesc[option].opt_name; /* option's name */
X optkind = odesc[option].opt_kind; /* option's kind */
X opthandler = odesc[option].opt_handler; /* option's handler */
X
X this_arg = SkipThisOption (this_arg, strlen (optrepr));
X minus_char_required = 0; /* -fe f AND e are options */
X
X switch (optkind) {
X case OPT_IS_SWITCH:
X opterr += opthandler (optrepr);
X break;
X case OPT_HAS_OPT_ARG:
X /*
X * at this point, this_arg points to the next char after
X * the detected option or this_arg has reached the end.
X */
X if (!*this_arg) { /* *this_arg == '\0' */
X if (*++pav) { /* next arg exists */
X this_arg = *pav;
X if (IsOption (this_arg, odesc, MINUS_CHAR_REQUIRED)) { /* always '-' required */
X opterr += opthandler (optrepr, "");
X this_arg = NULL;
X pav--;
X }
X else {
X opterr += opthandler (optrepr, this_arg);
X this_arg = NULL;
X }
X }
X else { /* end of pav reached */
X opterr += opthandler (optrepr, "");
X this_arg = NULL;
X pav--;
X }
X }
X else {
X if (! IsOption (this_arg, odesc, (! MINUS_CHAR_REQUIRED))) { /* rest of this_arg contains arg */
X opterr += opthandler (optrepr, this_arg);
X this_arg = NULL;
X }
X else {
X opterr += opthandler (optrepr, "");
X }
X }
X break;
X case OPT_HAS_ARG:
X if (!*this_arg) { /* end of this arg reached */
X pav++;
X this_arg = *pav;
X if (!this_arg) { /* end of pav reached */
X opterr += opthandler (optrepr, "");
X this_arg = NULL;
X pav--;
X }
X else {
X opterr += opthandler (optrepr, this_arg);
X this_arg = NULL;
X }
X }
X else {
X opterr += opthandler (optrepr, this_arg);
X this_arg = NULL;
X }
X break;
X default:
X fprintf (stderr, "ParseOpt: Non option detected as option: %s.\n",
X odesc[option].opt_name);
X exit (1);
X break;
X } /* end switch */
X } /* end then */
X else { /* argument is not a options */
X ArgV[*newac] = this_arg;
X (*newac)++;
X this_arg = NULL;
X }
X }
X pav++; /* select next argument */
X }
X
X /* finalization phase */
X ArgV[*newac] = (char *) NULL;
X
X#ifdef DEBUG_PARSE
X if (debug_parse) {
X int j;
X fprintf (stderr, "ParseArgs: Pure Arguments are:\nParseArgs:\t");
X
X if (!*ArgV) fprintf (stderr, "<none>\n");
X else {
X for (j = 0; ArgV[j]; j++) {
X fprintf (stderr, "%s ", ArgV[j]);
X }
X fprintf (stderr, "\n");
X }
X debug_parse = 0;
X fprintf (stderr, "ParseArgs: Debugging disabled.\n");
X }
X#endif DEBUG_PARSE
X
X *newav = (unsigned long) ArgV;
X return opterr; /* return # of errors. 0 means no error */
X}
X
Xpa_ShortUsage (progname, odesc, extra_text)
X char *progname;
X struct optdesc odesc[];
X char *extra_text;
X{
X int i;
X int twidth = 80;
X int c_printed = 6;
X int length = 0;
X int nextlineoff;
X char buf[80];
X
X RearrangeOptDesc (odesc, cmp_alpha);
X
X#define GetTerminalWidth(x) 80
X twidth = GetTerminalWidth();
X
X fprintf (stderr, "usage:");
X
X if (progname && *progname) {
X fprintf (stderr, " %s:", progname);
X c_printed += strlen (progname) + 2;
X }
X
X nextlineoff = c_printed + 3;
X
X /* first switches than option requiring an agrument */
X fprintf (stderr, " [-");
X c_printed += 3;
X
X for (i = 0; odesc[i].opt_name; i++) {
X if (odesc[i].opt_kind == OPT_IS_SWITCH) {
X length = strlen (odesc[i].opt_name); length++;
X if (c_printed + length > twidth) {
X c_printed = length + nextlineoff;
X sprintf (buf, "\n%%%dc", nextlineoff);
X fprintf (stderr, buf, ' ');
X }
X else {
X c_printed += length;
X }
X
X fprintf (stderr, " %s", odesc[i].opt_name);
X }
X }
X
X fprintf (stderr, "]"); c_printed++;
X nextlineoff -= 3;
X
X for (i = 0; odesc[i].opt_name; i++) {
X length = strlen (odesc[i].opt_name);
X
X switch (odesc[i].opt_kind) {
X case OPT_IS_SWITCH:
X break;
X case OPT_HAS_OPT_ARG:
X if ((c_printed + 14 + length) > 80) {
X c_printed = length + nextlineoff + 14;
X sprintf (buf, "\n%%%dc", nextlineoff);
X fprintf (stderr, buf, ' ');
X }
X else {
X c_printed += length + 14;
X }
X
X fprintf (stderr, " [-%s <opt arg>]", odesc[i].opt_name);
X break;
X case OPT_HAS_ARG:
X if ((c_printed + 10 + length) > 80) {
X c_printed = length + nextlineoff + 10;
X sprintf (buf, "\n%%%dc", nextlineoff);
X fprintf (stderr, buf, ' ');
X }
X else {
X c_printed += length + 10;
X }
X
X fprintf (stderr, " [-%s <arg>]", odesc[i].opt_name);
X break;
X default:
X break;
X }
X }
X
X if ((strlen (extra_text) + c_printed + 1) > twidth) {
X sprintf (buf, "\n%%%dc", nextlineoff);
X fprintf (stderr, buf, ' ');
X }
X
X fprintf (stderr, " %s\n", extra_text);
X}
END_OF_FILE
if test 12926 -ne `wc -c <'src/misc/ParseArgs.c'`; then
echo shar: \"'src/misc/ParseArgs.c'\" unpacked with wrong size!
fi
# end of 'src/misc/ParseArgs.c'
fi
if test -f 'src/shape/misc.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/shape/misc.c'\"
else
echo shar: Extracting \"'src/shape/misc.c'\" \(13128 characters\)
sed "s/^X//" >'src/shape/misc.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 at coma.uucp or shape at db0tui62.bitnet
X */
X#ifndef lint
Xstatic char *RCSid = "$Header: misc.c,v 3.5 89/02/21 17:11:54 wolfgang Exp $";
X#endif
X#ifndef lint
Xstatic char *ConfFlg = CFFLGS; /* should be defined from within Makefile */
X#endif
X/*
X * $Log: misc.c,v $
X * Revision 3.5 89/02/21 17:11:54 wolfgang
X * append_mtime changed
X *
X * Revision 3.4 89/02/20 16:26:08 wolfgang
X * NET-RELEASE
X *
X * Revision 3.3 89/02/08 16:19:55 wolfgang
X * one comment added for lint.
X * ..
X *
X * Revision 3.2 89/02/08 12:46:32 wolfgang
X * performance improved.
X *
X * Revision 3.1 89/02/06 14:26:41 wolfgang
X * bug fixed.
X *
X * Revision 3.0 89/01/24 11:36:12 wolfgang
X * New System Generation
X *
X * Revision 2.19 89/01/23 16:14:42 wolfgang
X * inheritance of uda's is now suppressed
X *
X * Revision 2.18 89/01/03 13:12:23 wolfgang
X * changes done for lint
X *
X * Revision 2.17 88/12/22 12:36:39 wolfgang
X * dummy procedure free_linklist()m added.
X *
X * Revision 2.16 88/12/21 15:11:10 wolfgang
X * changes done for lint
X *
X * Revision 2.15 88/12/19 13:21:27 wolfgang
X * is_in_forcelist added().
X *
X * Revision 2.14 88/11/23 12:35:48 wolfgang
X * Another dorpkey added.
X *
X * Revision 2.13 88/11/21 20:55:10 wolfgang
X * changes done for sun
X *
X * Revision 2.12 88/11/09 16:25:59 wolfgang
X * bugs fixed
X *
X * Revision 2.11 88/11/08 11:05:02 wolfgang
X * This version is part of a release
X *
X * Revision 2.10 88/11/03 17:29:46 wolfgang
X * calls of af_dropset added in compare_attrstring().
X *
X * Revision 2.9 88/10/10 16:54:43 wolfgang
X * changed for the -t option. if (touchflg) nothing is restored.
X *
X * Revision 2.8 88/09/23 15:54:20 wolfgang
X * bug fixed in get_attr_type (retrn values).
X *
X * Revision 2.7 88/09/22 16:15:06 wolfgang
X * clleanup_links() changed (now recursive).
X *
X * Revision 2.6 88/09/07 11:23:30 wolfgang
X * unlinking of tmp file added to cleanup_links().
X *
X * Revision 2.5 88/08/25 16:09:07 wolfgang
X * Message: ... restored from bpool changed; [busy] is supreesed and if
X * type = "" the "." is supressed.
X *
X * Revision 2.4 88/08/22 15:30:43 wolfgang
X * Two types added: syspath & host; are necessary for confid.
X *
X * Revision 2.3 88/08/22 11:24:06 wolfgang
X * Attribute string changed: added "." between name & type.
X *
X * Revision 2.2 88/08/19 10:05:59 wolfgang
X * bug fixed; if attrs were too long for bpool file, the identification
X * of the busy version had not been correct.
X * Furthermore the format of the string "... version restored ..." has
X * been changed, so that -2 .-2 for busy Version is supressed.
X *
X * Revision 2.1 88/08/18 13:19:41 wolfgang
X * minor bug fixes; mtime added to identification string of derived objects
X *
X */
X
X#include <sys/types.h>
X#include <sys/dir.h>
X#include "shape.h"
X
Xextern char *forcelist[];
Xextern Bool is_in_forcelist();
Xextern char *template;
Xextern int af_cleanup();
X
X/* Struct for registering links */
Xstruct linkreg *link_reg = (struct linkreg *) NIL;
Xstruct linkreg *last_link;
X
Xchar *longattrs[MAXDEPTH];
X
Xchar *types[] = { "generation", /* 0 int */
X "revision", /* 1 int */
X "state", /* 2 short */
X "author", /* 3 short */
X "group", /* 4 short */
X "version", /* 5 char * */
X "variant", /* 6 char * */
X "syspath", /* 7 char * */
X "host", /* 8 char * */
X "0"}; /* 99 default = char *
X (for userdefined attributes */
X
X
Xchar *states[] = { "busy",
X "saved",
X "proposed",
X "published",
X "accessed",
X "frozen",
X "0"};
X
X
Xint get_attr_type(name)
X char *name;
X{
X int i = 0;
X
X if (name == NIL)
X return(99);
X
X while(strcmp(types[i],"0") != 0)
X {
X if((strcmp(types[i],name) == 0))
X return(i);
X i++;
X }
X return(99);
X}
X
Xint get_state_no(state)
X char *state;
X{
X int i = 0;
X while(strcmp(states[i],"0") != 0)
X {
X if((strcmp(states[i],state) == 0))
X return(i);
X i++;
X }
X return(99);
X}
X
X
Xstruct linkreg *init_linkreg()
X{
X struct linkreg *lreg = (struct linkreg *) NIL;
X
X if ((lreg = (struct linkreg *) malloc(sizeof(struct linkreg))) ==
X (struct linkreg *) NIL)
X errexit(10,"malloc");
X if((lreg->fn = malloc(MAXNAMLEN)) == NIL)
X errexit(10,"malloc");
X if((lreg->newfn = malloc(MAXNAMLEN)) == NIL)
X errexit(10,"malloc");
X lreg->fn[0] = '\0';
X lreg->newfn[0] = '\0';
X lreg->next = (struct linkreg *) NIL;
X
X return(lreg);
X}
X
X
Xregister_link(fn, newfn, busy_exist)
X char *fn;
X char *newfn;
X Bool busy_exist;
X{
X if (link_reg == (struct linkreg *) NIL)
X {
X link_reg = init_linkreg();
X (void) strcpy(link_reg->fn, fn);
X (void) strcpy(link_reg->newfn, newfn);
X link_reg->busy_exist = busy_exist;
X last_link = link_reg;
X }
X else
X {
X last_link->next = init_linkreg();
X last_link = last_link->next;
X (void) strcpy(last_link->fn, fn);
X (void) strcpy(last_link->newfn, newfn);
X last_link->busy_exist = busy_exist;
X }
X}
X
Xcleanup_links(cur_link)
X struct linkreg *cur_link;
X{
X char filename[MAXNAMLEN];
X char afsname[MAXNAMLEN];
X if(cur_link != (struct linkreg *) NIL)
X {
X cleanup_links(cur_link->next);
X }
X if(cur_link != (struct linkreg *) NIL)
X {
X if(rindex(cur_link->fn,'/') == 0)
X {
X (void) strcpy(filename, "./");
X (void) strcat(filename, cur_link->fn);
X (void) strcpy(afsname, "./");
X (void) strcat(afsname, cur_link->newfn);
X }
X else
X {
X (void) strcpy(filename, cur_link->fn);
X (void) strcpy(afsname, cur_link->newfn);
X }
X if (unlink(filename) != 0)
X {
X fprintf(stderr, "shape - Aaaaaaaaaaaaaaaaargh !!!!!\n");
X fprintf(stderr, "error while cleaning up links :\n");
X fprintf(stderr, "can't unlink %s\n", filename);
X fprintf(stderr, "contact guru immediately !\n");
X af_cleanup();
X exit(1);
X }
X if (cur_link->busy_exist)
X {
X if (link(afsname,filename) != 0)
X {
X fprintf(stderr, "shape - Aaaaaaaaaaaaaaaaargh !!!!!\n");
X fprintf(stderr, "error while cleaning up links :\n");
X fprintf(stderr, "can't link %s to %s\n", filename, afsname);
X fprintf(stderr, "contact guru immediately !\n");
X af_cleanup();
X exit(1);
X }
X if (unlink(afsname) != 0)
X {
X fprintf(stderr, "shape - Aaaaaaaaaaaaaaaaargh !!!!!\n");
X fprintf(stderr, "error while cleaning up links :\n");
X fprintf(stderr, "can't unlink %s\n", filename);
X fprintf(stderr, "contact guru immediately !\n");
X af_cleanup();
X exit(1);
X }
X }
X }
X}
X
Xint free_linklist()
X{
X/* not yet implemented */
X/* should free memory of linklist */
X ;
X}
X
XBool compare_attrstring(attr, rulename, name, objrulename)
X /*ARGSUSED*/
X char *attr;
X struct rules *rulename;
X char *name;
X struct rules *objrulename;
X{
X Af_set aset;
X Af_set bset;
X Af_attrs buf;
X Af_attrs buf1;
X Af_attrs buf2;
X Af_key akey;
X Af_key bkey;
X Af_key key1;
X Af_key key2;
X Af_key restorekey;
X
X int retcode;
X int retcode1;
X char bname[MAXNAMLEN];
X char *type;
X char *p;
X char *d;
X char sysp[MAXNAMLEN];
X
X if (touchflg)
X return(0);
X
X sysp[0] = '\0';
X
X (void) strcpy(bname,name);
X if ((p = rindex(bname,'.')) == 0)
X {
X type = NIL;
X }
X else
X {
X p[0] = '\0';
X *p++;
X type = p;
X }
X
X if ((d = rindex(bname,'/')) != 0)
X {
X (void) strcpy(sysp, bname);
X d = rindex(sysp, '/');
X d[0] = '\0';
X *d++;
X (void) strcpy(bname,d);
X }
X af_initattrs(&buf);
X
X buf.af_gen = AF_BUSYVERS;
X buf.af_rev = AF_BUSYVERS;
X
X if(sysp[0] != '\0')
X (void) strcpy(buf.af_syspath,sysp);
X else
X (void) strcpy(buf.af_syspath,curvpath[0]);
X
X (void) strcpy(buf.af_name,bname);
X if (p != NIL)
X (void) strcpy(buf.af_type,p);
X else
X (void) strcpy(buf.af_type,"");
X
X if (forceflg)
X {
X if (is_in_forcelist(name,type))
X return(3);
X }
X
X if ((retcode1 = af_find(&buf, &aset)) == -1)
X errexit(10,"af_find");
X
X buf.af_gen = AF_NOVNUM;
X buf.af_rev = AF_NOVNUM;
X
X buf.af_udattrs[0] = attr;
X buf.af_udattrs[1] = NIL;
X
X if ((retcode = af_bpfind(&buf,&bset)) == -1)
X errexit(10,"af_bpfind");
X
X if ((retcode1 == 1) && (retcode == 0))
X /* derived object is not in binary pool (attr had been too long */
X {
X if((retcode = af_find(&buf, &bset)) == -1)
X {
X errexit(10,"af_find");
X }
X else
X {
X if (af_dropset(&bset) == -1)
X errexit(10,"af_dropset");
X if (af_dropset(&aset) == -1)
X errexit(10,"af_dropset");
X
X if (retcode == 1)
X /* busy version owns the correct attribute */
X return (0);
X else
X return(3);
X }
X }
X
X if ((retcode1 == 1) && (retcode == 1))
X {
X if(af_setgkey(&aset,0,&key1) == -1)
X errexit(10,"af_setgkey");
X if(af_setgkey(&bset,0,&key2) == -1)
X errexit(10,"af_setgkey");
X if(af_gattrs(&key1,&buf1) == -1)
X errexit(10,"af_gattrs");
X if(af_gattrs(&key2,&buf2) == -1)
X errexit(10,"af_gattrs");
X if(buf1.af_mtime == buf2.af_mtime)
X {
X if (af_dropset(&bset) == -1)
X errexit(10,"af_dropset");
X if (af_dropset(&aset) == -1)
X errexit(10,"af_dropset");
X return (0);
X }
X }
X if (retcode == 0)
X {
X if (af_dropset(&bset) == -1)
X errexit(10,"af_dropset");
X if (af_dropset(&aset) == -1)
X errexit(10,"af_dropset");
X return (3);
X }
X else
X {
X if (af_setgkey(&bset,0,&bkey) == -1)
X errexit(10,"af_setgkey");
X if (retcode1 == 1)
X {
X if (af_setgkey(&aset,0,&akey) == -1)
X errexit(10,"af_setgkey");
X if (af_dropkey(&akey) == -1)
X errexit(10,"af_dropkey");
X }
X if (af_restore(&bkey,&restorekey) == -1)
X errexit(10,"af_restore");
X
X if (af_sudattr(&restorekey,AF_REPLACE,attr) == -1)
X errexit(10,"af_sudattr");
X
X if (af_gattrs(&bkey,&buf) == -1)
X errexit(10,"af_gattrs");
X
X if (af_dropkey(&bkey) == -1)
X errexit(10,"af_dropkey");
X
X if (buf.af_gen != AF_BUSYVERS)
X {
X printf ("... %s.%s[%d.%d] restored from bpool\n",
X buf.af_name, buf.af_type, buf.af_gen, buf.af_rev);
X }
X else
X {
X if (strcmp(buf.af_type,""))
X printf ("... %s.%s restored from bpool\n",
X buf.af_name, buf.af_type);
X else
X printf ("... %s restored from bpool\n",
X buf.af_name);
X }
X if (af_dropset(&bset) == -1)
X errexit(10,"af_dropset");
X if (af_dropset(&aset) == -1)
X errexit(10,"af_dropset");
X return(0);
X }
X}
X
X
Xint append_attrs(buf,recdepth)
X Af_attrs *buf;
X int recdepth;
X{
X char attributes[MAX_ATTR];
X
X (void) sprintf(attributes,"%s%s%s%s%s%d%d%d%d",
X buf->af_name,
X ".",
X buf->af_type,
X buf->af_host,
X buf->af_syspath,
X buf->af_gen,
X buf->af_rev,
X buf->af_state,
X buf->af_mtime /* ,
X buf->af_owner.af_username,
X buf->af_owner.af_userhost,
X buf->af_author.af_username,
X buf->af_author.af_userhost,
X buf->af_locker.af_username,
X buf->af_locker.af_userhost,
X buf->af_size,
X buf->af_mode,
X buf->af_atime,
X buf->af_ctime,
X buf->af_stime,
X buf->af_ltime */
X );
X
X/* i = 0;
X while(buf->af_udattrs[i] != NIL)
X {
X if ((strlen(attributes) + strlen(buf->af_udattrs[i])) >= MAX_ATTR)
X errexit(29,NIL);
X (void) strcat(attributes,buf->af_udattrs[i]);
X i++;
X }
X*/
X if ((strlen(attributes) + strlen(longattrs[recdepth])) >= MAX_ATTR)
X errexit(29,NIL);
X
X (void) strcat(longattrs[recdepth],attributes);
X
X#ifdef DEBUG_MISC
Xprintf("depth=%d;longattr=%s\n", recdepth, longattrs[recdepth]);
X#endif DEBUG_MISC
X
X}
X
Xappend_mtime(testbuf,recdepth)
X Af_attrs *testbuf;
X /*ARGSUSED*/
X int recdepth;
X{
X char time[64];
X /* (void) sprintf(time,"%d",testbuf->af_mtime);
X (void) strcat(longattrs[recdepth],time); */
X}
X
X
XBool is_in_forcelist(name,type)
X char *name;
X char *type;
X{
X char fullname[MAXNAMLEN];
X int i = 0;
X fullname[0] = '\0';
X (void) strcpy(fullname,name);
X if (strcmp(type,""))
X {
X (void) strcat(fullname,".");
X (void) strcat(fullname,type);
X }
X
X while(forcelist[i] != NIL)
X {
X if (!strcmp(forcelist[i],fullname))
X return(TRUE);
X i++;
X }
X return(FALSE);
X}
X
X
END_OF_FILE
if test 13128 -ne `wc -c <'src/shape/misc.c'`; then
echo shar: \"'src/shape/misc.c'\" unpacked with wrong size!
fi
# end of 'src/shape/misc.c'
fi
if test -f 'src/vc/retrv.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/vc/retrv.c'\"
else
echo shar: Extracting \"'src/vc/retrv.c'\" \(13192 characters\)
sed "s/^X//" >'src/vc/retrv.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 at coma.uucp or shape at db0tui62.bitnet
X */
X#ifndef lint
Xstatic char *AFSid = "$Header: retrv.c[3.7] Thu Feb 23 18:13:45 1989 axel at coma published $";
X#ifdef CFFLGS
Xstatic char *ConfFlg = CFFLGS;
X /* should be defined from within Makefile */
X#endif
X#endif
X/*
X * Log for /u/shape/dist-tape/src/vc/retrv.c[3.2]
X * Thu Feb 23 18:13:46 1989 axel at coma save $
X * --- empty log message ---
X * retrv.c[3.3] Thu Feb 23 18:13:46 1989 axel at coma save $
X * --- empty log message ---
X * retrv.c[3.4] Thu Feb 23 18:13:46 1989 axel at coma published $
X * --- empty log message ---
X * retrv.c[3.5] Thu Feb 23 18:13:46 1989 axel at coma published $
X * --- empty log message ---
X * retrv.c[3.6] Thu Feb 23 18:13:46 1989 axel at coma save $
X * --- empty log message ---
X * retrv.c[3.7] Thu Feb 23 18:13:46 1989 axel at coma published $
X * --- empty log message ---
X */
X
X/*
X * retrv [-fmqtx] [-V version] [-a attrs] [-d date] [-g generation]
X * [-n author] [-p pname] [-s state] [-lock] [-dest path] fn [fn1 ...]
X *
X * Retrieve a previously saved version of a file. We orient us pretty much
X * towards the check-out operation of RCS. Retrieve determines the
X * archive name to be searched from the given file names. Unless otherwise
X * specified by the project context (-p), the archive is expected to
X * reside in the AFS subdirectory. The retrieved version will be created
X * in the current directory. Retrieve tries to be careful if an
X * attempt is made to overwrite an existing busy-version: unless -f
X * is specified, retrv will ask the caller for permission.
X * If no busy version exists, one is created with the modes of the
X * formerly saved version. If one exists, it's modes are kept unless
X * -m is given.
X * There's a number of ways to specify which version should be retrieved.
X * With -V an explicit version can be selected. Another argument to -V
X * could be a symbolic name (hopefully unique). Alternatively, versions
X * can be selected by supplying certain attribute values to retrv, such as
X * the name of the author, the version state, a generation number or a
X * set of user defined attributes, possibly describing a variant. In case
X * that more than one version fits the desired attributes, the newest
X * of them is selected, unless -x (exact!) is specified. -V implies -x.
X */
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <stdio.h>
X#include <strings.h>
X#include "ParseArgs.h"
X#include "afs.h"
X#include "retrv.h"
X#include "project.h"
X
Xchar *progname;
X
Xstruct Transaction ThisTransaction;
X
X/* forward decls for option handlers */
Xextern handle_R_switch ();
Xextern handle_f_switch ();
Xextern handle_l_switch ();
Xextern handle_m_switch ();
Xextern handle_q_switch ();
Xextern handle_t_switch ();
Xextern handle_x_switch ();
Xextern handle_V_opt ();
Xextern handle_a_opt ();
Xextern handle_d_opt ();
Xextern handle_dest_opt ();
Xextern handle_g_opt ();
Xextern handle_n_opt ();
Xextern handle_p_opt ();
Xextern handle_s_opt ();
Xextern usage ();
X
Xunsigned int options;
X
Xstatic OptDesc retrvargs[] = {
X { "version", OPT_IS_SWITCH, handle_R_switch },
X { "f", OPT_IS_SWITCH, handle_f_switch },
X { "l", OPT_IS_SWITCH, handle_l_switch },
X { "lock", OPT_IS_SWITCH, handle_l_switch },
X { "m", OPT_IS_SWITCH, handle_m_switch },
X { "q", OPT_IS_SWITCH, handle_q_switch },
X { "t", OPT_IS_SWITCH, handle_t_switch },
X { "x", OPT_IS_SWITCH, handle_x_switch },
X { "V", OPT_HAS_ARG, handle_V_opt },
X { "a", OPT_HAS_ARG, handle_a_opt },
X { "d", OPT_HAS_ARG, handle_d_opt },
X { "date", OPT_HAS_ARG, handle_d_opt },
X { "dest", OPT_HAS_ARG, handle_dest_opt },
X { "g", OPT_HAS_ARG, handle_g_opt },
X { "n", OPT_HAS_ARG, handle_n_opt },
X { "p", OPT_HAS_ARG, handle_p_opt },
X { "s", OPT_HAS_ARG, handle_s_opt },
X { "h", OPT_IS_SWITCH, usage },
X/* { "?", OPT_HAS_ARG, usage }, */
X { (char *) NULL, NULL, NULL }
X};
Xstatic OptDesc vcatargs[] = {
X { "version", OPT_IS_SWITCH, handle_R_switch },
X { "q", OPT_IS_SWITCH, handle_q_switch },
X { "t", OPT_IS_SWITCH, handle_t_switch },
X { "x", OPT_IS_SWITCH, handle_x_switch },
X { "V", OPT_HAS_ARG, handle_V_opt },
X { "a", OPT_HAS_ARG, handle_a_opt },
X { "d", OPT_HAS_ARG, handle_d_opt },
X { "date", OPT_HAS_ARG, handle_d_opt },
X { "g", OPT_HAS_ARG, handle_g_opt },
X { "n", OPT_HAS_ARG, handle_n_opt },
X { "p", OPT_HAS_ARG, handle_p_opt },
X { "s", OPT_HAS_ARG, handle_s_opt },
X { "h", OPT_IS_SWITCH, usage },
X/* { "?", OPT_HAS_ARG, usage }, */
X { (char *) NULL, NULL, NULL }
X};
X
Xstatic int nfnms;
X
Xstatic struct Vdesc dversion;
X
Xchar *dp = NULL; /* nasty sideeffect here - see 'handle_dest_opt' */
X
Xmain (ac, av) char **av; {
X register int i;
X int nac, bound_vid = 0, rc = 0;
X unsigned int options_bak = 0;
X char messg[80], *es, *getenv(), **nav, *version(), vstring[16], *cp;
X Project pdesc;
X struct Vdesc *vdescr = &dversion, alt_dversion;
X
X progname = (cp = rindex (av[0], '/')) ? ++cp : av[0];
X /* make prog-name available to entire program */
X
X if (ac < 2) {
X pa_ShortUsage (progname, vcatargs, "files ...");
X }
X
X if (!strcmp (progname, TONAME)) {
X options |= TYPEOUT;
X if (ParseArgs (ac, av, &nac, &nav, vcatargs)) {
X pa_ShortUsage (progname, vcatargs, "files...");
X }
X }
X else {
X if (ParseArgs (ac, av, &nac, &nav, retrvargs)) {
X pa_ShortUsage (progname, retrvargs, "files...");
X }
X }
X
X if (!(options & (TYPEOUT | COPY | LOCKIT))) options |= COPY;
X
X if (!(options & ATTRDEF)) {
X es = getenv (RTRATTR);
X if ((es) && (es[0] != '\0')) {
X options |= ATTRDEF;
X (void)strcpy (dversion.v_attrf, es);
X }
X }
X
X if ((options & PROJCSET) && fail(GetProject (dversion.v_pname, &pdesc))) {
X (void)sprintf (messg, "%s %s", EINVALPROJ, dversion.v_pname);
X logerr (messg);
X exit (1);
X }
X
X CatchSigs ();
X nfnms = nac;
X ThisTransaction.tr_rc = 0;
X for (i = 0, vdescr = &dversion; i < nfnms; i++) {
X if (!setjmp (ThisTransaction.tr_env)) {
X if (bound_vid) {
X bound_vid = FALSE;
X options = options_bak; /* restore original selection options */
X vdescr = &dversion;
X }
X ThisTransaction.tr_seqno = i;
X if (BoundVersion (nav[i], ThisTransaction.tr_fname, vstring)) {
X alt_dversion.v_vno = mkvno (vstring);
X options_bak = options; /* save original selection options */
X options |= (VSPECSET | XACT);
X options &= ~(ATTRDEF | GENSET | AUNSET | STATSET | DATESET);
X vdescr = &alt_dversion;
X bound_vid = TRUE;
X }
X else {
X (void)strcpy (ThisTransaction.tr_fname, nav[i]);
X }
X ThisTransaction.tr_done = FALSE;
X RetrieveAFile (ThisTransaction.tr_fname, vdescr, &pdesc, dp);
X }
X else { /* ThisTransaction was aborted */
X rc += ThisTransaction.tr_rc;
X }
X }
X logdiag ("done.");
X return (rc);
X}
X
XSfunc_t interrupt_action () { /* is executed by appropriate signal handler */
X char messg[80];
X
X if ((nfnms - ThisTransaction.tr_seqno) > 1) {
X (void)sprintf (messg, "\ncompletely stop retrieving (%d files pending) ?",
X nfnms - ThisTransaction.tr_seqno);
X if (ask_confirm (messg, "no")) {
X if (ThisTransaction.tr_done) {
X (void)sprintf (messg, "\ntoo late, %s already restored",
X ThisTransaction.tr_fname);
X logdiag (messg);
X return; /* continue where we've been interrupted */
X }
X (void)sprintf (messg, NORESTORE, ThisTransaction.tr_fname);
X logdiag (messg);
X longjmp (ThisTransaction.tr_env, 1);
X }
X else {
X (void)sprintf (messg, NORESTORE, ThisTransaction.tr_fname);
X logmsg (messg);
X exit (1);
X }
X }
X else {
X (void)sprintf (messg, "\n%s not restored", ThisTransaction.tr_fname);
X logdiag (messg);
X exit (1);
X }
X}
X
Xlogmsg (msg) char *msg; {
X if (!(options & QUIETPLEASE)) {
X fprintf (stdout, "%s\n", msg);
X }
X}
X
Xlogdiag (msg) char *msg; {
X if (!(options & QUIETPLEASE)) {
X fprintf (stderr, "%s\n", msg);
X }
X}
X
Xlogerr (msg) char *msg; {
X fprintf (stderr, "%s: %s\n", progname, msg);
X}
X
X/*ARGSUSED*/
Xhandle_R_switch (o, a) char *o, *a; {
X printf ("This is %s version %s.\n", progname, version ());
X printf ("AFS version %s.\n", af_version());
X exit (0);
X}
X
X/*ARGSUSED*/
Xhandle_f_switch (o, a) char *o, *a; {
X options |= FORCE;
X return 0;
X}
X
X/*ARGSUSED*/
Xhandle_l_switch (o, a) char *o, *a; {
X char messg[128];
X
X if (options & TYPEOUT) {
X logerr ("Locking makes no sense in TYPEOUT mode of operation - ignored.");
X return 0;
X }
X if (options & COPY) {
X (void)sprintf (messg, "No checkout (with lock) to distant directory %s.", dp);
X logerr (messg);
X exit (1);
X }
X options |= LOCKIT;
X return 0;
X}
X
X/*ARGSUSED*/
Xhandle_m_switch (o, a) char *o, *a; {
X options |= KEEPMODE;
X return 0;
X}
X
X/*ARGSUSED*/
Xhandle_q_switch (o, a) char *o, *a; {
X options |= QUIETPLEASE;
X return 0;
X}
X
X/*ARGSUSED*/
Xhandle_t_switch (o, a) char *o, *a; {
X if (options & LOCKIT) {
X logerr ("Locking makes no sense in TYPEOUT mode of operation - ignored.");
X options &= ~LOCKIT;
X }
X if (options & COPY) {
X logerr ("TYPEOUT mode of operation overrides COPY mode.");
X options &= ~COPY;
X dp = NULL;
X }
X options |= TYPEOUT;
X return 0;
X}
X
X/*ARGSUSED*/
Xhandle_x_switch (o, a) char *o, *a; {
X options |= XACT;
X return 0;
X}
X
X/*ARGSUSED*/
Xhandle_V_opt (o, a) char *o, *a; {
X dversion.v_vno = mkvno (a);
X (void)strcpy (dversion.v_spec, a);
X options |= VSPECSET;
X options |= XACT;
X return 0;
X}
X
X/*ARGSUSED*/
Xhandle_a_opt (o, a) char *o, *a; {
X options |= ATTRDEF;
X (void)strcpy (dversion.v_attrf, a);
X return 0;
X}
X
X/*ARGSUSED*/
Xhandle_d_opt (o, a) char *o, *a; {
X char messg[128];
X time_t mktime();
X
X if ((options & STATSET) && (dversion.v_state == AF_BUSY)) {
X logmsg (WDOVRBS);
X options &= ~STATSET;
X }
X if (dversion.v_time = mktime (a)) {
X options |= DATESET;
X return 0;
X }
X else {
X (void)sprintf (messg, "invalid date specification: %s.", a);
X logerr (messg);
X tusage ();
X return 1;
X }
X}
X
X/*ARGSUSED*/
Xhandle_dest_opt (o, a) char *o, *a; {
X char messg[128];
X static char dpath[256];
X struct stat statbuf;
X
X if (!a) return 1;
X if (options & LOCKIT) {
X (void)sprintf (messg, "No checkout (with lock) to distant directory %s.", a);
X logerr (messg);
X exit (1);
X }
X if (options & TYPEOUT) {
X logerr ("Already TYPEOUT mode of operation selected.");
X return 0;
X }
X if (options & COPY) {
X (void)sprintf (messg, "Destination path already set to %s. %s ignored.", dpath,
X a);
X logerr (messg);
X return 0;
X }
X options |= COPY;
X (void)strcpy (dpath, a);
X if (stat (dpath, &statbuf) < 0) {
X (void)sprintf (messg, "Destination path %s does not exist.", dpath);
X logerr (messg);
X exit (1);
X }
X if (!(statbuf.st_mode & S_IFDIR)) {
X (void)sprintf (messg, "Destination %s is not a directory.", dpath);
X logerr (messg);
X exit (1);
X }
X dp = dpath;
X return 0;
X}
X
X/*ARGSUSED*/
Xhandle_g_opt (o, a) char *o, *a; {
X char messg[128];
X
X if (dversion.v_genno = mkgenno (a)) {
X options |= GENSET;
X return 0;
X }
X else {
X (void)sprintf (messg, "'%s' is not a legal generation number.", a);
X logerr (messg);
X return 1;
X }
X}
X
X/*ARGSUSED*/
Xhandle_n_opt (o, a) char *o, *a; {
X char *cp;
X
X options |= AUNSET;
X if (cp=index (a, '@')) {
X *cp = '\0';
X (void)strcpy (dversion.v_auhost, ++cp);
X }
X (void)strcpy (dversion.v_aunam, a);
X return 0;
X}
X
X/*ARGSUSED*/
Xhandle_p_opt (o, a) char *o, *a; {
X options |= PROJCSET;
X (void)strcpy (dversion.v_pname, a);
X return 0;
X}
X
X/*ARGSUSED*/
Xhandle_s_opt (o, a) char *o, *a; {
X char messg[128];
X
X if (!fail((dversion.v_state = mkstate (a)))) {
X if ((options & DATESET) && (dversion.v_state == AF_BUSY)) {
X logmsg (WDOVRBS);
X }
X else {
X options |= STATSET;
X }
X }
X else {
X (void)sprintf (messg, "unrecognized version state: %s.\n", a);
X logerr (messg);
X helpstates ();
X exit (1);
X }
X return 0;
X}
X
Xtusage () {
X fputs ("specify time as yy/mm/dd[/hh:mm].\n", stderr);
X}
X
Xhelpstates () {
X fputs ("The following states are recognized:\n", stderr);
X fputs ("\tbusy, save, proposed, published, accessed, frozen\n", stderr);
X}
X
Xusage () {
X if (strcmp (progname, "vcat"))
X pa_ShortUsage (progname, retrvargs, "files ...");
X else
X pa_ShortUsage (progname, vcatargs, "files ...");
X}
END_OF_FILE
if test 13192 -ne `wc -c <'src/vc/retrv.c'`; then
echo shar: \"'src/vc/retrv.c'\" unpacked with wrong size!
fi
# end of 'src/vc/retrv.c'
fi
echo shar: End of archive 15 \(of 33\).
cp /dev/null ark15isdone
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 at uunet.uu.net.
More information about the Comp.sources.unix
mailing list