home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / arc / zoosrc2-10.zoo / zoodel.c < prev    next >
C/C++ Source or Header  |  1991-07-17  |  10KB  |  307 lines

  1. #ifndef LINT
  2. /* @(#) zoodel.c 2.19 88/02/06 21:23:36 */
  3. /*$Source: /usr/home/dhesi/zoo/RCS/zoodel.c,v $*/
  4. /*$Id: zoodel.c,v 1.4 91/07/09 01:54:11 dhesi Exp $*/
  5. static char sccsid[]="$Source: /usr/home/dhesi/zoo/RCS/zoodel.c,v $\n\
  6. $Id: zoodel.c,v 1.4 91/07/09 01:54:11 dhesi Exp $";
  7. #endif /* LINT */
  8.  
  9. /*
  10. Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  11. (C) Copyright 1988 Rahul Dhesi -- All rights reserved
  12. */
  13. #include "options.h"
  14. /* Deletes or undeletes entries from an archive.  choice=1 requests
  15.    deletion and choice=0 requests undeletion. */
  16. #include "zoo.h"
  17. #include "portable.h"
  18. #ifndef    OK_STDIO
  19. #include <stdio.h>
  20. #define    OK_STDIO
  21. #endif
  22. #include "various.h" /* may not be needed */
  23. #include "zooio.h"
  24. #include "zoofns.h"
  25. #include "errors.i"
  26.  
  27. #ifndef NOSIGNAL
  28. #include <signal.h>
  29. #endif
  30.  
  31. int needed PARMS((char *, struct direntry *, struct zoo_header *));
  32. int ver_too_high PARMS((struct zoo_header *));
  33.  
  34. extern int quiet;
  35.  
  36. void zoodel (zoo_path, option, choice)
  37. char *zoo_path;
  38. char *option;
  39. int choice;
  40. {
  41. #ifndef NOSIGNAL
  42.    T_SIGNAL (*oldsignal)();        /* to save previous SIGINT handler */
  43. #endif
  44.    int delcount = 0;          /* how many entries we [un]deleted */
  45.    char matchname[PATHSIZE];  /* will hold full pathname */
  46.    register ZOOFILE zoo_file;
  47.    struct zoo_header zoo_header;
  48.    struct direntry direntry;
  49.    unsigned int latest_date = 0;      /* so we can set time of archive later */
  50.    unsigned int latest_time = 0;
  51.    int pack = 0;              /* pack after deletion? */
  52.    int file_deleted = 0;      /* any files deleted? */
  53.    int one = 0;               /* del/undel one file only */
  54.    int done;                  /* loop control */
  55.     int action;                        /* delete/undelete or adjust generation */
  56.     int subopt;                        /* sub option to action */
  57.     long gencount;                    /* generation count */
  58.     int doarchive = 0;            /* whether to adjust archive gen count */
  59.     unsigned valtoshow;            /* value to show in informative message */
  60.     int dodel = 0;                    /* selection of deleted files */
  61.     int selected;                    /* if current direntry selected */
  62.  
  63. /* values for action */
  64. #define NO_ACTION    0    /* nothing */
  65. #define DEL_UNDEL    1    /* delete or undelete file */
  66. #define ADJ_LIM    2    /* adjust generation limit */
  67. #define ADJ_GCNT    3    /* adjust generation count */
  68. #define GEN_ON        4    /* turn on generations */
  69. #define GEN_OFF        5    /* turn off generations */
  70.  
  71. /* values for subopt */
  72. #define    SET        0
  73. #define    INC        1
  74.  
  75. action = NO_ACTION;
  76. if (*option == 'g') {
  77.     while (*(++option)) {
  78.         switch (*option) {
  79.             case 'A': doarchive = 1; break;
  80.             case 'q': quiet++; break;
  81.             case 'l': action = ADJ_LIM; break;
  82.             case 'c': action = ADJ_GCNT; break;
  83.             case '=':
  84.                 subopt = SET; gencount = calc_ofs (++option);
  85.                 if (action == ADJ_GCNT && gencount == 0)
  86.                     prterror ('f', "Generation count must be nonzero.\n");
  87.                 goto opts_done;
  88.             case '+':
  89.                 if (action == NO_ACTION) {
  90.                     if (option[1] =='\0') {
  91.                         action = GEN_ON;
  92.                         goto opts_done;
  93.                     } else
  94.                         prterror ('f', garbled);
  95.                 } else {
  96.                     subopt = INC; gencount = calc_ofs (++option);
  97.                     goto opts_done;
  98.                 }
  99.             case '-':
  100.                 if (action == NO_ACTION) {
  101.                     if (option[1] =='\0') {
  102.                         action = GEN_OFF;
  103.                         goto opts_done;
  104.                     } else
  105.                         prterror ('f', garbled);
  106.                 } else {
  107.                     subopt = INC; gencount = - calc_ofs (++option);
  108.                     goto opts_done;
  109.                 }
  110.             case 'd':
  111.                 dodel++; break;
  112.             default:
  113.                 prterror ('f', garbled);
  114.         } /* end switch */
  115.     } /* end while */
  116.     /* if normal exit from while loop, it means bad command string */
  117.     prterror ('f', garbled);
  118.     opts_done:                             /* jump here from exit in while loop above */
  119.         if (action == NO_ACTION)
  120.             prterror ('f', garbled);
  121. } else {
  122.     action = DEL_UNDEL;
  123.     while (*(++option)) {
  124.         switch (*option) {
  125.             case 'P': pack++; break;            /* pack after adding */
  126.             case 'q': quiet++; break;           /* be quiet */
  127.             case '1': one++; break;             /* del or undel only one file */
  128.             default:
  129.                 prterror ('f', inv_option, *option);
  130.         }
  131.     } /* end while */
  132. }
  133.  
  134.    /* Open archive for read/write/binary access.  It must already exist */
  135.    if ((zoo_file = zooopen (zoo_path, Z_RDWR)) == NOFILE) {
  136.       prterror ('f', could_not_open, zoo_path);
  137.    }
  138.    
  139.    /* read archive header */
  140.    frd_zooh (&zoo_header, zoo_file);
  141.    if ((zoo_header.zoo_start + zoo_header.zoo_minus) != 0L)
  142.       prterror ('f', failed_consistency);
  143.    if (ver_too_high (&zoo_header))
  144.       prterror ('f', wrong_version, zoo_header.major_ver, zoo_header.minor_ver);
  145.  
  146.     if (doarchive) {                                    /* manipulate archive gen val */
  147.         unsigned zoo_date, zoo_time;
  148. #ifdef GETUTIME
  149.         getutime (zoo_path, &zoo_date, &zoo_time);    /* save archive timestamp */
  150. #else
  151.         gettime (zoo_file, &zoo_date, &zoo_time);
  152. #endif
  153.         if (zoo_header.type == 0)
  154.             prterror ('f', packfirst);
  155.         if (action == ADJ_LIM)    {
  156.             unsigned newgencount;    
  157.             if (subopt == SET)
  158.                 newgencount = (unsigned) gencount;
  159.             else                                                                        /* INC */
  160.                 newgencount = (zoo_header.vdata & VFL_GEN) + (unsigned) gencount;
  161.             newgencount &= VFL_GEN;            /* reduce to allowed bits */
  162.             zoo_header.vdata &= (~VFL_GEN);
  163.             zoo_header.vdata |= newgencount;
  164.             prterror ('M', "Archive generation limit is now %u\n", newgencount);
  165.         } else if (action == GEN_ON) {
  166.             zoo_header.vdata |= VFL_ON;
  167.             prterror ('M', "Archive generations on\n");
  168.         } else if (action == GEN_OFF) {
  169.             zoo_header.vdata &= (~VFL_ON);
  170.             prterror ('M', "Archive generations off\n");
  171.         } else 
  172.             prterror ('f', garbled);
  173.         zooseek (zoo_file, 0L, 0);        /* back to begining of file */
  174.         fwr_zooh (&zoo_header, zoo_file);
  175. #ifdef NIXTIME
  176.         zooclose (zoo_file);
  177.         setutime (zoo_path, zoo_date, zoo_time);    /* restore archive timestamp */
  178. #else
  179.         settime (zoo_file, zoo_date, zoo_time);
  180.         zooclose (zoo_file);
  181. #endif
  182.         return;
  183.     }
  184.  
  185.    zooseek (zoo_file, zoo_header.zoo_start, 0); /* seek to where data begins */
  186.  
  187.    done = 0;            /* loop not done yet */
  188.    while (1) {
  189.       long this_dir_offset;
  190.       this_dir_offset = zootell (zoo_file);   /* save pos'n of this dir entry */
  191.       frd_dir (&direntry, zoo_file);
  192.       if (direntry.zoo_tag != ZOO_TAG) {
  193.          prterror ('f', bad_directory);
  194.       }
  195.       if (direntry.next == 0L) {                /* END OF CHAIN */
  196.          break;                                 /* EXIT on end of chain */
  197.       }
  198.  
  199.         /* select directory entry if it matches criteria */
  200.         selected = (
  201.                           (action == DEL_UNDEL && direntry.deleted != choice)
  202.                   ||
  203.                           (action != DEL_UNDEL &&
  204.                          (dodel && direntry.deleted ||
  205.                                 (dodel < 2 && !direntry.deleted))
  206.                           )
  207.                       );
  208.  
  209.         /* WARNING: convention of choice=1 for deleted entry must be same as
  210.         in direntry definition in zoo.h */
  211.     
  212.         /* Test for "done" so if "one" option requested, [un]del only 1 file */
  213.         /* But we go through the whole archive to adjust archive time */
  214.  
  215.         strcpy (matchname, fullpath (&direntry));        /* get full pathname */
  216.         if (zoo_header.vdata & VFL_ON)
  217.             add_version (matchname, &direntry);            /* add version suffix */
  218.  
  219.         if (!done && selected && needed(matchname, &direntry, &zoo_header)) {
  220.             prterror ('m', "%-14s -- ", matchname);
  221.             delcount++;
  222.             if (action == DEL_UNDEL) {
  223.                 direntry.deleted = choice;
  224.                 if (choice)
  225.                     file_deleted++;      /* remember if any files actually deleted */
  226.             } else {                            /* ADJ_LIM or ADJ_GENCNT */
  227.                 if (direntry.vflag & VFL_ON) {        /* skip if no versions */
  228.                     if (action == ADJ_LIM) {
  229.                         unsigned newgencount;
  230.                         if (subopt == SET)
  231.                             newgencount = (unsigned) gencount;
  232.                         else                                                     /* INC */
  233.                             newgencount =
  234.                                 (int) (direntry.vflag & VFL_GEN) + (int) gencount;
  235.                         newgencount &= VFL_GEN;
  236.                         direntry.vflag &= (~VFL_GEN);
  237.                         direntry.vflag |= newgencount;
  238.                         valtoshow = newgencount;
  239.                     } else {                                                    /* ADJ_GCNT */
  240.                         if (subopt == SET)
  241.                             direntry.version_no = (unsigned) gencount;
  242.                         else                                                     /* INC */
  243.                             direntry.version_no += (int) gencount;
  244.                         direntry.version_no &= VER_MASK; /* avoid extra bits */
  245.                         valtoshow = direntry.version_no;
  246.                     }
  247.                 }
  248.             }
  249.  
  250.             zooseek (zoo_file, this_dir_offset, 0);
  251.  
  252. #ifndef NOSIGNAL
  253.             oldsignal = signal (SIGINT, SIG_IGN);  /* disable ^C for write */
  254. #endif
  255.             if (fwr_dir (&direntry, zoo_file) == -1)
  256.                 prterror ('f', "Could not write to archive\n");
  257. #ifndef NOSIGNAL
  258.             signal (SIGINT, oldsignal);
  259. #endif
  260.             if (action == DEL_UNDEL)
  261.                 prterror ('M', choice ? "deleted\n" : "undeleted\n");
  262.             else {
  263.                 if (direntry.vflag & VFL_ON)
  264.                     prterror ('M', "adjusted to %u\n", valtoshow);
  265.                 else
  266.                     prterror ('M', "no generations\n");
  267.             }
  268.             if (one)
  269.                 done = 1;            /* if 1 option, done after 1 file */
  270.         }
  271.  
  272.       /* remember most recent date and time if entry is not deleted */
  273.       if (!direntry.deleted)
  274.          if (direntry.date > latest_date ||
  275.             (direntry.date == latest_date && direntry.time > latest_time)) {
  276.                latest_date = direntry.date;
  277.                latest_time = direntry.time;
  278.          }
  279.       zooseek (zoo_file, direntry.next, 0); /* ..seek to next dir entry */
  280.    } /* endwhile */
  281.  
  282.    if (!delcount)
  283.       printf ("Zoo:  No files matched.\n");
  284.    else {
  285. #ifdef NIXTIME
  286.       zooclose (zoo_file);
  287.       setutime (zoo_path, latest_date, latest_time);
  288. #else
  289. #if 0
  290.       fflush (zoo_file);         /* superstition:  might help time stamp */
  291. #endif
  292.       settime (zoo_file, latest_date, latest_time);
  293. #endif
  294.    }
  295.  
  296. #ifndef NIXTIME
  297. zooclose (zoo_file);
  298. #endif
  299.  
  300. if (file_deleted && pack) {   /* pack if files were deleted and user asked */
  301.    prterror ('M', "-----\nPacking...");
  302.    zoopack (zoo_path, "PP");
  303.    prterror ('M', "done\n");
  304. }
  305.  
  306. }
  307.