Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!bbn!bbn.com!rsalz From: rsalz@uunet.uu.net (Rich Salz) Newsgroups: comp.sources.unix Subject: v19i039: A software configuration management system, Part26/33 Message-ID: <1797@papaya.bbn.com> Date: 6 Jun 89 21:48:35 GMT Lines: 1060 Approved: rsalz@uunet.UU.NET Submitted-by: Axel Mahler Posting-number: Volume 19, Issue 39 Archive-name: shape/part26 #! /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 'src/afs/afsrepair.c' <<'END_OF_FILE' X/* X * Copyright (C) 1989, 1990 W. Koch, A. Lampen, A. Mahler, W. Obst, X * and U. Pralle X * X * This software is published on an as-is basis. There is ABSOLUTELY NO X * WARRANTY for any part of this software to work correctly or as described X * in the manuals. We do not accept any liability for any kind of damage X * caused by use of this software, such as loss of data, time, money, or X * effort. X * X * Permission is granted to use, copy, modify, or distribute any part of X * this software as long as this is done without asking for charge, and X * provided that this copyright notice is retained as part of the source X * files. You may charge a distribution fee for the physical act of X * transferring a copy, and you may at your option offer warranty X * protection in exchange for a fee. X * X * Direct questions to: Tech. Univ. Berlin X * Wilfried Koch X * Sekr. FR 5-6 X * Franklinstr. 28/29 X * D-1000 Berlin 10, West Germany X * X * Tel: +49-30-314-22972 X * E-mail: shape@coma.uucp or shape@db0tui62.bitnet X */ X/* X * X * AFS-test -- try to repair corrupted archive X * X * $Header: afsrepair.c[1.4] Wed Feb 22 16:28:01 1989 andy@coma published $ X */ X X#include X#include X#ifdef SUNOS_4_0 X#include X#endif X#include X#include X#include X#include X X#include "typeconv.h" X#include "afs.h" X#include "afarchive.h" X#include "afsrepair.h" X Xint givenVLevel = NORMAL; XInput attrIn, dataIn; XConstAttrs cAttrs; XRevision revList[MAXREVS]; XUdas udaList[MAXREVS]; XNote noteList[MAXREVS]; XData dataList[MAXREVS]; Xint curRev, curUda, curNote, curData; X Xchar *malloc(), *verifyString(), *complainString(); Xextern char *optarg; Xextern int optind; X Xjmp_buf env; X Xmain (argc, argv) X int argc; X char **argv; X{ X int cleanup(), getopt(); X short c, i, nfiles; X X if (argc < 2) X { usage (); exit (-1); } X X while ((c = getopt (argc, argv, "l:v")) != EOF) X { X switch (c) X { X case 'l': /* level */ X givenVLevel = atoi (optarg); X if ((givenVLevel < 0) || (givenVLevel > 3)) X { X fprintf (stderr, "illegal level of verbosity (%s)\n", X "must be 0, 1, 2 or 3"); X exit (-1); X } X break; X case 'v': /* print current version of this program */ X printf ("This is %s version %s.\n", argv[0], af_version()); X exit (0); X default: X usage (); X exit (-1); X } X } /* end of command line parsing */ X X (void) signal (SIGINT, cleanup); X X nfiles = argc - optind; X for (i = 0; i < nfiles; i++) X { X if (setjmp (env) == 0) X (void) repair (argv[i+optind]); X } X} /* end of main */ X Xusage () X{ X fprintf (stderr, "Usage: afsrepair [-l level] [-v] files\n"); X} X Xchar lckFilename[4*MAXNAMLEN]; X Xcleanup () X{ X fprintf (stderr, "abort processing of this file\n"); X (void) af_unlink (lckFilename); X longjmp (env, 1); X} X Xrepair (filename) X char *filename; X{ X char *fullname = af_uniqpath (filename), *sPtr, commandLine[1024]; X char *arFilename, datFilename[4*MAXNAMLEN]; X char arTmpFilename[4*MAXNAMLEN], datTmpFilename[4*MAXNAMLEN]; X int size, i, j; X Af_user *owner, *af_garown(); X bool error, writeOk, confirm, busyEx = FALSE; X FILE *inFile, *tmpFile, *lckFile; X struct stat ibuf; X X if (!strcmp (filename, "binary_pool")) X { X fprintf (stdout, "cannot repair binary pools yet -- \nthe only way "); X fprintf (stdout, "to fix a binary pool is to clear it ! (y/n) ? "); X if (askConfirm ("y")) X { X fprintf (stdout, "clearing binary pool...\n", filename); X (void) sprintf (commandLine, "rm -f AFS/%s*\0", AF_BPFILEID); X (void) system (commandLine); X } X exit (0); X } X X cAttrs.host = af_gethostname (); X cAttrs.syspath = af_afpath (fullname); X cAttrs.name = af_afname (fullname); X cAttrs.type = af_aftype (fullname); X X fprintf (stdout, "%s:\n", af_unixname ((char *)0, cAttrs.name, cAttrs.type)); X X arFilename = af_garname (cAttrs.syspath, cAttrs.name, cAttrs.type); X X if ((owner = af_garown (arFilename, &writeOk)) == (Af_user *)0) X { X fprintf (stdout, "cannot determine owner of AFS subdirectory !!\n"); X owner = af_getuser (getuid()); X } X cAttrs.ownerName = af_entersym (owner->af_username); X cAttrs.ownerHost = af_enterhost (owner->af_userhost); X X /* look for Lockfile */ X (void) strcpy (lckFilename, arFilename); X lckFilename [strlen (lckFilename) - sizeof (char)] = AF_LCKEXT; X if (stat (lckFilename, &ibuf) != ERROR) /* lock file present */ X { X fprintf (stdout, "Archive file is locked!\n"); X fprintf (stdout, " There might be a spurious lockfile,\n"); X fprintf (stdout, " or another application is currently modifying the archive file.\n"); X fprintf (stdout, " Ignore the lock (y/n) ? "); X if (!askConfirm ("y")) X exit (0); X else /* create lockfile */ X { X lckFile = fopen (lckFilename, "w"); X (void) fclose (lckFile); X } X } X X /* read the two archive files (if present) */ X if (inFile = fopen (arFilename, "r")) X { X attrIn.length = af_retfsize (arFilename); X if ((attrIn.string = malloc ((unsigned) attrIn.length)) == (char *)0) X { X fprintf (stdout, "repair (malloc): not enough memory\n"); X cleanup (); X } X (void) fread (attrIn.string, sizeof (char), (Size_t) attrIn.length, inFile); X (void) fclose (inFile); X attrIn.curPos = 0; X } X X (void) strcpy (datFilename, arFilename); X datFilename[strlen(datFilename)-sizeof(char)] = AF_DATAEXT; X if (inFile = fopen (datFilename, "r")) X { X dataIn.length = af_retfsize (datFilename); X if ((dataIn.string = malloc ((unsigned) dataIn.length)) == (char *)0) X { X fprintf (stdout, "repair (malloc): not enough memory\n"); X cleanup (); X } X (void) fread (dataIn.string, sizeof (char), (Size_t) dataIn.length, inFile); X (void) fclose (inFile); X } X else X { X if (attrIn.string == (char *)0) X { X fprintf (stdout, "repair: no archive files for %s\n", X af_unixname ((char *)0, cAttrs.name, cAttrs.type)); X cleanup (); X } X } X X /* test existence of busy file */ X if (access (fullname, 0) == 0) X busyEx = TRUE; X X /*========= X * Phase 1 X *=========*/ X fprintf (stdout, "*** Phase 1 (check version independent attributes) ***\n"); X X (void) lookup (&attrIn, AF_NAMEID, 0); X X (void) nextItem (&attrIn); /* host */ X sPtr = verifyString ("hostname", attrIn, VERBOSE); X if (strcmp (sPtr, cAttrs.host)) X sPtr = complainString ("hostname", sPtr, cAttrs.host, NORMAL); X cAttrs.host = af_entersym (sPtr); X X (void) nextItem (&attrIn); /* syspath */ X sPtr = verifyString ("syspath", attrIn, VERBOSE); X if (strcmp (sPtr, cAttrs.syspath)) X sPtr = complainString ("syspath", sPtr, cAttrs.syspath, NORMAL); X cAttrs.syspath = af_entersym (sPtr); X X (void) nextItem (&attrIn); /* name */ X sPtr = verifyString ("name", attrIn, VERBOSE); X if (strcmp (sPtr, cAttrs.name)) X sPtr = complainString ("name", sPtr, cAttrs.name, NORMAL); X cAttrs.name = af_entersym (sPtr); X X (void) nextItem (&attrIn); /* type */ X sPtr = verifyString ("type", attrIn, VERBOSE); X if (strcmp (sPtr, cAttrs.type)) X sPtr = complainString ("type", sPtr, cAttrs.type, NORMAL); X cAttrs.type = af_entersym (sPtr); X X (void) lookup (&attrIn, AF_OWNID, 0); X X (void) nextItem (&attrIn); /* owner's name */ X sPtr = verifyString ("owner's name", attrIn, VERBOSE); X if (strcmp (sPtr, cAttrs.ownerName)) X sPtr = complainString ("owner's name", sPtr, cAttrs.ownerName, NORMAL); X cAttrs.ownerName = af_entersym (sPtr); X X (void) nextItem (&attrIn); /* owner's host */ X sPtr = verifyString ("owner's host", attrIn, VERBOSE); X if (strcmp (sPtr, cAttrs.ownerHost)) X sPtr = complainString ("owner's host", sPtr, cAttrs.ownerHost, NORMAL); X cAttrs.ownerHost = af_entersym (sPtr); X X /*========= X * Phase 2 X *=========*/ X fprintf (stdout, "*** Phase 2 (check version attributes) ***\n"); X X /* initialize busy version --- not *all* attributes get initialized !!! */ X revList[0].generation = AF_BUSYVERS; X revList[0].revision = AF_BUSYVERS; X (void) lookup (&attrIn, AF_NAMEID, 0); X (void) nextItem (&attrIn); (void) nextItem (&attrIn); X (void) nextItem (&attrIn); (void) nextItem (&attrIn); X (void) nextItem (&attrIn); X sPtr = verifyString ("variant", attrIn, VERBOSE); X revList[0].variant = af_entersym (sPtr); X X (void) lookup (&attrIn, AF_LOCKID, 0); X (void) nextItem (&attrIn); X sPtr = verifyString ("locker's name", attrIn, VERBOSE); X revList[0].lockerName = af_entersym (sPtr); X (void) nextItem (&attrIn); X sPtr = verifyString ("locker's host", attrIn, VERBOSE); X revList[0].lockerHost = af_entersym (sPtr); X X if ((revList[0].lockerName == (char *)0) && revList[0].lockerHost) X { X fprintf (stdout, "Warning: lockerID inconsistent -- lock cancelled\n"); X revList[0].lockerName = (char *)0; X revList[0].lockerHost = (char *)0; X } X if (revList[0].lockerName && (revList[0].lockerHost == (char *)0)) X { X fprintf (stdout,"locker's host missing - inserting author's host\n"); X revList[0].lockerHost = revList[0].authorHost; X } X X (void) nextItem (&attrIn); X revList[0].lockTime = verifyDate ("locking date", attrIn, EVERYTHING); X if (revList[0].lockerName && (revList[0].lockTime == AF_NOTIME)) X { X fprintf (stdout, "Warning: locking date inconsistent -- %s\n", X "setting actual date"); X revList[0].lockTime = (time_t) af_acttime(); X } X X (void) lookup (&attrIn, AF_PRDID, 0); X (void) nextItem (&attrIn); X revList[0].predGen = X verifyInt ("pred(gen) of busy version", attrIn, EVERYTHING); X (void) nextItem (&attrIn); X revList[0].predRev = X verifyInt ("pred(rev) of busy version", attrIn, EVERYTHING); X X attrIn.curPos = 0; X curRev = 0; X while (lookup (&attrIn, AF_REVID, 1) != -1) X { X curRev++; X (void) nextItem (&attrIn); X revList[curRev].generation = verifyInt ("gen", attrIn, EVERYTHING); X (void) nextItem (&attrIn); X revList[curRev].revision = verifyInt ("rev", attrIn, EVERYTHING); X (void) nextItem (&attrIn); X revList[curRev].state = verifyInt ("state", attrIn, EVERYTHING); X (void) nextItem (&attrIn); X revList[curRev].mode = (u_short) verifyOct ("mode", attrIn, EVERYTHING); X (void) nextItem (&attrIn); X sPtr = verifyString ("variant", attrIn, VERBOSE); X revList[curRev].variant = af_entersym (sPtr); X X (void) lookup (&attrIn, AF_AUTHORID, 1); X (void) nextItem (&attrIn); /* author's name */ X sPtr = verifyString ("author's name", attrIn, VERBOSE); X if (sPtr == (char *)0) X { X fprintf (stdout,"author's name missing -- inserting owner's name\n"); X revList[curRev].authorName = cAttrs.ownerName; X } X else X revList[curRev].authorName = af_entersym (sPtr); X X (void) nextItem (&attrIn); /* authort's host */ X sPtr = verifyString ("author's host", attrIn, VERBOSE); X if (sPtr == (char *)0) X { X fprintf (stdout,"author's host missing -- inserting owner's host\n"); X revList[curRev].authorHost = cAttrs.ownerHost; X } X else X revList[curRev].authorHost = af_entersym (sPtr); X X (void) nextItem (&attrIn); /* locker's name */ X sPtr = verifyString ("locker's name", attrIn, VERBOSE); X revList[curRev].lockerName = af_entersym (sPtr); X X (void) nextItem (&attrIn); /* locker's host */ X sPtr = verifyString ("locker's host", attrIn, VERBOSE); X if ((sPtr == (char *)0) && (revList[curRev].lockerName != (char *)0)) X { X fprintf (stdout,"locker's host missing - inserting author's host\n"); X revList[curRev].lockerHost = revList[curRev].authorHost; X } X else X revList[curRev].lockerHost = af_entersym (sPtr); X X (void) lookup (&attrIn, AF_DATEID, 1); X (void) nextItem (&attrIn); X revList[curRev].modTime = verifyDate ("mod. date", attrIn, EVERYTHING); X if (revList[curRev].modTime == AF_NOTIME) X { X fprintf (stdout, "Warning: modification date missing -- %s\n", X "inserting actual date"); X revList[curRev].modTime = (time_t) af_acttime(); X } X (void) nextItem (&attrIn); X revList[curRev].accessTime = verifyDate ("acc. date", attrIn,EVERYTHING); X if (revList[curRev].accessTime == AF_NOTIME) X { X fprintf (stdout, "Warning: access date missing -- %s\n", X "inserting actual date"); X revList[curRev].accessTime = (time_t) af_acttime(); X } X (void) nextItem (&attrIn); X revList[curRev].statChangeTime = X verifyDate ("status change date", attrIn, EVERYTHING); X if (revList[curRev].statChangeTime == AF_NOTIME) X { X fprintf (stdout, "Warning: status change date missing -- %s\n", X "inserting actual date"); X revList[curRev].statChangeTime = (time_t) af_acttime(); X } X (void) nextItem (&attrIn); X revList[curRev].saveTime = verifyDate ("save date", attrIn, EVERYTHING); X if (revList[curRev].saveTime == AF_NOTIME) X { X fprintf (stdout, "Warning: save date missing -- %s\n", X "inserting actual date"); X revList[curRev].saveTime = (time_t) af_acttime(); X } X (void) nextItem (&attrIn); X revList[curRev].lockTime = verifyDate ("lock date", attrIn, EVERYTHING); X if ((revList[curRev].lockTime == AF_NOTIME) && X (revList[curRev].lockerName != (char *)0)) X { X fprintf (stdout, "Warning: locking date missing -- %s\n", X "inserting actual date"); X revList[curRev].lockTime = (time_t) af_acttime(); X } X X (void) lookup (&attrIn, AF_REPRID, 1); X (void) nextItem (&attrIn); X revList[curRev].representation = verifyInt ("repr", attrIn, EVERYTHING); X (void) nextItem (&attrIn); X revList[curRev].fileSize = verifyInt ("filesize", attrIn, EVERYTHING); X (void) nextItem (&attrIn); X revList[curRev].deltaSize = verifyInt ("deltasize", attrIn, EVERYTHING); X (void) nextItem (&attrIn); X revList[curRev].succGen = verifyInt ("succ. gen", attrIn, EVERYTHING); X (void) nextItem (&attrIn); X revList[curRev].succRev = verifyInt ("succ. rev", attrIn, EVERYTHING); X (void) nextItem (&attrIn); X revList[curRev].predGen = verifyInt ("pred. gen", attrIn, EVERYTHING); X (void) nextItem (&attrIn); X revList[curRev].predRev = verifyInt ("pred. rev", attrIn, EVERYTHING); X } /* revision loop */ X X /*========= X * Phase 3 X *=========*/ X fprintf (stdout, "*** Phase 3 (check user defined attributes) ***\n"); X X attrIn.curPos = 0; X curUda = 0; X while (lookup (&attrIn, AF_UDAID, 1) != -1) X { X (void) nextItem (&attrIn); X udaList[curUda].generation = verifyInt ("gen", attrIn, EVERYTHING); X (void) nextItem (&attrIn); X udaList[curUda].revision = verifyInt ("rev", attrIn, EVERYTHING); X (void) nextItem (&attrIn); X i = 0; X size = 0; X while (i < MAXUDAS) X { X udaList[curUda].uda[i] = &attrIn.string[attrIn.curPos]; X udaList[curUda].size = udaList[curUda].size + X (strlen (udaList[curUda].uda[i]) + sizeof (char)); X while (attrIn.string[attrIn.curPos] != '\0') X attrIn.curPos++; X attrIn.curPos++; X i++; X if (!strcmp (&attrIn.string[attrIn.curPos], AF_UDAID)) X break; X if (attrIn.string[attrIn.curPos] == '\0') X { X udaList[curUda].size++; X break; X } X } /* uda loop */ X udaList[curUda].uda[i] = (char *)0; X curUda++; X } /* revision loop */ X X /*========= X * Phase 4 X *=========*/ X fprintf (stdout, "*** Phase 4 (check notes) ***\n"); X X dataIn.curPos = 0; X curNote = 0; X while (lookup (&dataIn, AF_NOTEID, 1) != -1) X { X (void) nextItem (&dataIn); X noteList[curNote].generation = verifyInt ("gen", dataIn, EVERYTHING); X (void) nextItem (&dataIn); X noteList[curNote].revision = verifyInt ("rev", dataIn, EVERYTHING); X (void) nextItem (&dataIn); X (void) nextLine (&dataIn); /* skip size */ X size = 0; X noteList[curNote].contents = &dataIn.string[dataIn.curPos]; X while (((noteList[curNote].contents)[size] != AF_DATAID[0]) && X ((noteList[curNote].contents)[size] != '\0')) X size++; X if (size == 0) X { X noteList[curNote].contents = (char *)0; X size = 1; X } X else X (noteList[curNote].contents)[size-1] = '\0'; X noteList[curNote].size = size; X curNote++; X } /* revision loop */ X X /*========= X * Phase 5 X *=========*/ X fprintf (stdout, "*** Phase 5 (check data) ***\n"); X X dataIn.curPos = 0; X curData = 0; X while (lookup (&dataIn, AF_DATAID, 1) != -1) X { X (void) nextItem (&dataIn); X dataList[curData].generation = verifyInt ("gen", dataIn, EVERYTHING); X (void) nextItem (&dataIn); X dataList[curData].revision = verifyInt ("rev", dataIn, EVERYTHING); X (void) nextItem (&dataIn); X dataList[curData].representation = verifyInt ("repr",dataIn, EVERYTHING); X (void) nextItem (&dataIn); X (void) nextLine (&dataIn); /* skip size */ X size = 0; X dataList[curData].contents = &dataIn.string[dataIn.curPos]; X while (itemCmp (&(dataList[curData].contents)[size], X AF_NOTEID, AF_IDSTRLEN) && X itemCmp (&(dataList[curData].contents)[size], X AF_DATAID, AF_IDSTRLEN)) X { X size++; X while ((dataList[curData].contents)[size] != AF_NOTEID[0]) X { X size++; X if ((dataIn.curPos + size) == dataIn.length) X goto loopexit; X } X } X loopexit: X if (size == 0) X dataList[curData].contents = (char *)0; X dataList[curData].size = size; X curData++; X } /* revision loop */ X X /*========= X * Phase 6 X *=========*/ X fprintf (stdout, "*** Phase 6 (check connectivity) ***\n"); X X /* test order of revisions -- not yet implemented */ X /* test existence on successors and predecessors -- not yet implemented */ X X /* calculate number of revisions and size of data */ X cAttrs.noOfRevisions = curRev; X X cAttrs.datasize = 0; X for (i=0; icurPos = 0; X if (input->curPos == input->length) X return (-1); X X while (itemCmp (&(input->string[input->curPos]), X searchStr, strlen (searchStr))) X { X input->curPos++; X while (input->string[input->curPos] != searchStr[0]) X { X input->curPos++; X if (input->curPos == input->length) X return (-1); X } X } X return (input->curPos); X} X XnextItem (input) X Input *input; X{ X if (input->curPos == input->length) X return (-1); X /* search next white space */ X while ((input->string[input->curPos] != ' ') && X (input->string[input->curPos] != '\t') && X (input->string[input->curPos] != '\n')) X if (++input->curPos == input->length) X return (-1); X X /* skip white spaces */ X while ((input->string[input->curPos] == ' ') || X (input->string[input->curPos] == '\t') || X (input->string[input->curPos] == '\n')) X if (++input->curPos == input->length) X return (-1); X X return (input->curPos); X} X XnextLine(input) X Input *input; X{ X if (input->curPos == input->length) X return (-1); X /* search beginning of next line */ X while (input->string[input->curPos] != '\n') X if (++input->curPos == input->length) X return (-1); X X /* skip newline */ X if (++input->curPos == input->length) X return (-1); X X return (input->curPos); X} X Xchar *itemCopy (str1, str2) X char *str1, *str2; X{ X if (!strncmp (str2, AF_NOSTRING, 2)) X { X str1[0] = '\0'; X return (str1); X } X X while (*str1 = *str2) X { X if ((*str2 ==' ') || (*str2 =='\t') || (*str2 =='\n')) X { *str1 = '\0'; return (str1); } X str1++; X str2++; X } X return (str1); X} X XitemCmp (baseStr, searchStr, len) X char *baseStr, *searchStr; X int len; X{ X int i=0; X while (baseStr[i] == searchStr[i]) X { X i++; X if (i == len) X { X if ((baseStr[i] == ' ') || (baseStr[i] == '\t') || X (baseStr[i] == '\0') || (baseStr[i] == '\n')) X return (0); X else X return (1); X } X } X return (1); X} X X/*========================================================================= X * verifyString, verifyInt, verifyDate X * complainString X * X *=========================================================================*/ X Xchar *verifyString (name, input, level) X char *name; X Input input; X int level; X{ X static char value[256]; X X (void) itemCopy (value, &input.string[input.curPos]); X X if (level <= givenVLevel) X { X fprintf (stdout, "assume %s to be: ->%s<-, ok ? (y/n) ", name, value); X if (askConfirm ("y")) X goto exit; X fprintf (stdout, "enter new %s (*0* for empty string): ", name); X (void) fscanf (stdin, "%s", value); X if (!strncmp (value, "*0*", 3)) X return ((char *)0); X } X exit: X if (value[0]) X return (value); X else X return ((char *)0); X} X Xchar *complainString (name, string1, string2, level) X char *name, *string1, *string2; X int level; X{ X if (level <= givenVLevel) X { X fprintf (stdout, X "Inconsistency: value for %s is ->%s<- (should be ->%s<-), %s", X name, string1, string2, "fix ? (y/n) "); X if (askConfirm ("y")) X return (string1); X } X return (string2); X} X XverifyInt (name, input, level) X char *name; X Input input; X int level; X{ X int value; X X value = atoi (&input.string[input.curPos]); X X if (level <= givenVLevel) X { X fprintf (stdout, "assume %s to be: ->%d<-, ok ? (y/n) ", name, value); X if (askConfirm ("y")) X return (value); X fprintf (stdout, "enter new %s: ", name); X (void) fscanf (stdin, "%d", value); X } X return (value); X} X XverifyOct (name, input, level) X char *name; X Input input; X int level; X{ X int value; X X (void) sscanf (&input.string[input.curPos], "%o", &value); X X if (level <= givenVLevel) X { X fprintf (stdout, "assume %s to be: ->%o<-, ok ? (y/n) ", name, value); X if (askConfirm ("y")) X return (value); X fprintf (stdout, "enter new %s: ", name); X (void) fscanf (stdin, "%o", value); X } X return (value); X} X XverifyDate (name, input, level) X char *name; X Input input; X int level; X{ X int value; X X value = atoi (&input.string[input.curPos]); X X if (level <= givenVLevel) X { X fprintf (stdout, "assume %s to be: ->%d<-, ok ? (y/n) ", name, value); X if (askConfirm ("y")) X return (value); X fprintf (stdout, "enter new date: "); X (void) fscanf (stdin, "%d", value); X } X return (value); X} X END_OF_FILE if test 30386 -ne `wc -c <'src/afs/afsrepair.c'`; then echo shar: \"'src/afs/afsrepair.c'\" unpacked with wrong size! fi # end of 'src/afs/afsrepair.c' fi echo shar: End of archive 26 \(of 33\). cp /dev/null ark26isdone 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.