Logo Search packages:      
Sourcecode: zoo version File versions  Download package

zoodel.c

#ifndef LINT
/* @(#) zoodel.c 2.19 88/02/06 21:23:36 */
/*$Source: /usr/home/dhesi/zoo/RCS/zoodel.c,v $*/
/*$Id: zoodel.c,v 1.4 91/07/09 01:54:11 dhesi Exp $*/
static char sccsid[]="$Source: /usr/home/dhesi/zoo/RCS/zoodel.c,v $\n\
$Id: zoodel.c,v 1.4 91/07/09 01:54:11 dhesi Exp $";
#endif /* LINT */

/*
Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
(C) Copyright 1988 Rahul Dhesi -- All rights reserved
*/
#include "options.h"
/* Deletes or undeletes entries from an archive.  choice=1 requests
   deletion and choice=0 requests undeletion. */
#include "zoo.h"
#include "portable.h"
#ifndef     OK_STDIO
#include <stdio.h>
#define     OK_STDIO
#endif
#include "various.h" /* may not be needed */
#include "zooio.h"
#include "zoofns.h"
#include "errors.i"

#ifndef NOSIGNAL
#include <signal.h>
#endif

int needed PARMS((char *, struct direntry *, struct zoo_header *));
int ver_too_high PARMS((struct zoo_header *));

extern int quiet;

void zoodel (zoo_path, option, choice)
char *zoo_path;
char *option;
int choice;
{
#ifndef NOSIGNAL
   T_SIGNAL (*oldsignal)();        /* to save previous SIGINT handler */
#endif
   int delcount = 0;          /* how many entries we [un]deleted */
   char matchname[PATHSIZE];  /* will hold full pathname */
   register ZOOFILE zoo_file;
   struct zoo_header zoo_header;
   struct direntry direntry;
   unsigned int latest_date = 0;      /* so we can set time of archive later */
   unsigned int latest_time = 0;
   int pack = 0;              /* pack after deletion? */
   int file_deleted = 0;      /* any files deleted? */
   int one = 0;               /* del/undel one file only */
   int done;                  /* loop control */
      int action;                               /* delete/undelete or adjust generation */
      int subopt;                               /* sub option to action */
      long gencount;                            /* generation count */
      int doarchive = 0;                  /* whether to adjust archive gen count */
      unsigned valtoshow;                 /* value to show in informative message */
      int dodel = 0;                            /* selection of deleted files */
      int selected;                             /* if current direntry selected */

/* values for action */
#define NO_ACTION 0     /* nothing */
#define DEL_UNDEL 1     /* delete or undelete file */
#define ADJ_LIM   2     /* adjust generation limit */
#define ADJ_GCNT  3     /* adjust generation count */
#define GEN_ON          4     /* turn on generations */
#define GEN_OFF         5     /* turn off generations */

/* values for subopt */
#define     SET         0
#define     INC         1

action = NO_ACTION;
if (*option == 'g') {
      while (*(++option)) {
            switch (*option) {
                  case 'A': doarchive = 1; break;
                  case 'q': quiet++; break;
                  case 'l': action = ADJ_LIM; break;
                  case 'c': action = ADJ_GCNT; break;
                  case '=':
                        subopt = SET; gencount = calc_ofs (++option);
                        if (action == ADJ_GCNT && gencount == 0)
                              prterror ('f', "Generation count must be nonzero.\n");
                        goto opts_done;
                  case '+':
                        if (action == NO_ACTION) {
                              if (option[1] =='\0') {
                                    action = GEN_ON;
                                    goto opts_done;
                              } else
                                    prterror ('f', garbled);
                        } else {
                              subopt = INC; gencount = calc_ofs (++option);
                              goto opts_done;
                        }
                  case '-':
                        if (action == NO_ACTION) {
                              if (option[1] =='\0') {
                                    action = GEN_OFF;
                                    goto opts_done;
                              } else
                                    prterror ('f', garbled);
                        } else {
                              subopt = INC; gencount = - calc_ofs (++option);
                              goto opts_done;
                        }
                  case 'd':
                        dodel++; break;
                  default:
                        prterror ('f', garbled);
            } /* end switch */
      } /* end while */
      /* if normal exit from while loop, it means bad command string */
      prterror ('f', garbled);
      opts_done:                                      /* jump here from exit in while loop above */
            if (action == NO_ACTION)
                  prterror ('f', garbled);
} else {
      action = DEL_UNDEL;
      while (*(++option)) {
            switch (*option) {
                  case 'P': pack++; break;            /* pack after adding */
                  case 'q': quiet++; break;           /* be quiet */
                  case '1': one++; break;             /* del or undel only one file */
                  default:
                        prterror ('f', inv_option, *option);
            }
      } /* end while */
}

   /* Open archive for read/write/binary access.  It must already exist */
   if ((zoo_file = zooopen (zoo_path, Z_RDWR)) == NOFILE) {
      prterror ('f', could_not_open, zoo_path);
   }
   
   /* read archive header */
   frd_zooh (&zoo_header, zoo_file);
   if ((zoo_header.zoo_start + zoo_header.zoo_minus) != 0L)
      prterror ('f', failed_consistency);
   if (ver_too_high (&zoo_header))
      prterror ('f', wrong_version, zoo_header.major_ver, zoo_header.minor_ver);

      if (doarchive) {                                                  /* manipulate archive gen val */
            unsigned zoo_date, zoo_time;
#ifdef GETUTIME
            getutime (zoo_path, &zoo_date, &zoo_time);      /* save archive timestamp */
#else
            gettime (zoo_file, &zoo_date, &zoo_time);
#endif
            if (zoo_header.type == 0)
                  prterror ('f', packfirst);
            if (action == ADJ_LIM)  {
                  unsigned newgencount;   
                  if (subopt == SET)
                        newgencount = (unsigned) gencount;
                  else                                                                                                        /* INC */
                        newgencount = (zoo_header.vdata & VFL_GEN) + (unsigned) gencount;
                  newgencount &= VFL_GEN;             /* reduce to allowed bits */
                  zoo_header.vdata &= (~VFL_GEN);
                  zoo_header.vdata |= newgencount;
                  prterror ('M', "Archive generation limit is now %u\n", newgencount);
            } else if (action == GEN_ON) {
                  zoo_header.vdata |= VFL_ON;
                  prterror ('M', "Archive generations on\n");
            } else if (action == GEN_OFF) {
                  zoo_header.vdata &= (~VFL_ON);
                  prterror ('M', "Archive generations off\n");
            } else 
                  prterror ('f', garbled);
            zooseek (zoo_file, 0L, 0);          /* back to begining of file */
            fwr_zooh (&zoo_header, zoo_file);
#ifdef NIXTIME
            zooclose (zoo_file);
            setutime (zoo_path, zoo_date, zoo_time);  /* restore archive timestamp */
#else
            settime (zoo_file, zoo_date, zoo_time);
            zooclose (zoo_file);
#endif
            return;
      }

   zooseek (zoo_file, zoo_header.zoo_start, 0); /* seek to where data begins */

   done = 0;            /* loop not done yet */
   while (1) {
      long this_dir_offset;
      this_dir_offset = zootell (zoo_file);   /* save pos'n of this dir entry */
      frd_dir (&direntry, zoo_file);
      if (direntry.zoo_tag != ZOO_TAG) {
         prterror ('f', bad_directory);
      }
      if (direntry.next == 0L) {                /* END OF CHAIN */
         break;                                 /* EXIT on end of chain */
      }

            /* select directory entry if it matches criteria */
            selected = (
                                      (action == DEL_UNDEL && direntry.deleted != choice)
                  ||
                                      (action != DEL_UNDEL &&
                        (dodel && direntry.deleted ||
                                    (dodel < 2 && !direntry.deleted))
                                      )
                                );

            /* WARNING: convention of choice=1 for deleted entry must be same as
            in direntry definition in zoo.h */
      
            /* Test for "done" so if "one" option requested, [un]del only 1 file */
            /* But we go through the whole archive to adjust archive time */

            strcpy (matchname, fullpath (&direntry));       /* get full pathname */
            if (zoo_header.vdata & VFL_ON)
                  add_version (matchname, &direntry);             /* add version suffix */

            if (!done && selected && needed(matchname, &direntry, &zoo_header)) {
                  prterror ('m', "%-14s -- ", matchname);
                  delcount++;
                  if (action == DEL_UNDEL) {
                        direntry.deleted = choice;
                        if (choice)
                              file_deleted++;      /* remember if any files actually deleted */
                  } else {                                        /* ADJ_LIM or ADJ_GENCNT */
                        if (direntry.vflag & VFL_ON) {            /* skip if no versions */
                              if (action == ADJ_LIM) {
                                    unsigned newgencount;
                                    if (subopt == SET)
                                          newgencount = (unsigned) gencount;
                                    else                                                                          /* INC */
                                          newgencount =
                                                (int) (direntry.vflag & VFL_GEN) + (int) gencount;
                                    newgencount &= VFL_GEN;
                                    direntry.vflag &= (~VFL_GEN);
                                    direntry.vflag |= newgencount;
                                    valtoshow = newgencount;
                              } else {                                                                            /* ADJ_GCNT */
                                    if (subopt == SET)
                                          direntry.version_no = (unsigned) gencount;
                                    else                                                                          /* INC */
                                          direntry.version_no += (int) gencount;
                                    direntry.version_no &= VER_MASK; /* avoid extra bits */
                                    valtoshow = direntry.version_no;
                              }
                        }
                  }

                  zooseek (zoo_file, this_dir_offset, 0);

#ifndef NOSIGNAL
                  oldsignal = signal (SIGINT, SIG_IGN);  /* disable ^C for write */
#endif
                  if (fwr_dir (&direntry, zoo_file) == -1)
                        prterror ('f', "Could not write to archive\n");
#ifndef NOSIGNAL
                  signal (SIGINT, oldsignal);
#endif
                  if (action == DEL_UNDEL)
                        prterror ('M', choice ? "deleted\n" : "undeleted\n");
                  else {
                        if (direntry.vflag & VFL_ON)
                              prterror ('M', "adjusted to %u\n", valtoshow);
                        else
                              prterror ('M', "no generations\n");
                  }
                  if (one)
                        done = 1;            /* if 1 option, done after 1 file */
            }

      /* remember most recent date and time if entry is not deleted */
      if (!direntry.deleted)
         if (direntry.date > latest_date ||
            (direntry.date == latest_date && direntry.time > latest_time)) {
               latest_date = direntry.date;
               latest_time = direntry.time;
         }
      zooseek (zoo_file, direntry.next, 0); /* ..seek to next dir entry */
   } /* endwhile */

   if (!delcount)
      printf ("Zoo:  No files matched.\n");
   else {
#ifdef NIXTIME
      zooclose (zoo_file);
      setutime (zoo_path, latest_date, latest_time);
#else
#if 0
      fflush (zoo_file);         /* superstition:  might help time stamp */
#endif
      settime (zoo_file, latest_date, latest_time);
#endif
   }

#ifndef NIXTIME
zooclose (zoo_file);
#endif

if (file_deleted && pack) {   /* pack if files were deleted and user asked */
   prterror ('M', "-----\nPacking...");
   zoopack (zoo_path, "PP");
   prterror ('M', "done\n");
}

}

Generated by  Doxygen 1.6.0   Back to index