home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / zoo_src / z201src2 / zoodel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-25  |  9.3 KB  |  309 lines

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