home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / util / zoo-2.1.lha / zoo / zooadd.c < prev    next >
C/C++ Source or Header  |  1991-10-08  |  25KB  |  745 lines

  1. #ifndef LINT
  2. /* derived from: zooadd.c 2.34 88/08/15 10:53:11 */
  3. static char sccsid[]="$Source: /usr/home/dhesi/zoo/RCS/zooadd.c,v $\n\
  4. $Id: zooadd.c,v 1.10 91/07/08 23:48:39 dhesi Exp $";
  5. #endif /* LINT */
  6.  
  7. /*
  8. Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  9. (C) Copyright 1988 Rahul Dhesi -- All rights reserved
  10. (C) Copyright 1991 Rahul Dhesi -- All rights reserved
  11. */
  12. #include "options.h"
  13. /* Adds files specified in parameter-list to archive zoo_path. */
  14.  
  15. #define LONGEST    20                 /* assumed length of longest filename */
  16. #include "zoomem.h"             /* to define MAXADD */
  17. #include "zoo.h"
  18. #include "zooio.h"
  19. #include "various.h"
  20. #include "parse.h"
  21. #include "debug.h"
  22.  
  23. #include "portable.h"
  24.  
  25. #include "zoofns.h"
  26. #include "errors.i"
  27. extern int break_hit;
  28. extern int quiet;
  29.  
  30. void show_comment PARMS ((struct direntry *, ZOOFILE, int, char *));
  31. void dosname PARMS ((char *, char *));
  32. void modpath PARMS ((char *));
  33. void opts_add PARMS ((char *, int *, int *, int *, int *, int *, int *,
  34.                     int *, int *, int *, int *, int *, int *, int *, int *));
  35. int ver_too_high PARMS ((struct zoo_header *));
  36. void get_comment PARMS ((struct direntry *, ZOOFILE, char *));
  37. void copyfields PARMS ((struct direntry *, struct tiny_header *));
  38. void storefname PARMS ((struct direntry *, char *, int));
  39. char *choosefname PARMS ((struct direntry *));
  40.  
  41. extern struct zoo_header zoo_header;
  42.  
  43. extern char file_leader[];
  44. extern unsigned int crccode;
  45.  
  46. void zooadd(zoo_path, argc, argv, option)
  47. char *zoo_path;        /* pathname of zoo archive to add to */
  48. int argc;                /* how many filespecs supplied */
  49. char **argv;            /* array of pointers to filespecs */
  50. char *option;            /* option string */
  51. {
  52. char *whichname;                                    /* which name to show user */
  53. char **flist;                                        /* list of ptrs to input fnames */
  54. int fptr;                                            /* will point to within flist */
  55. ZOOFILE this_file;                                /* file to add */
  56. char zoo_fname[LFNAMESIZE];                    /* basename of archive itself */
  57. char zoo_bak[LFNAMESIZE];                        /* name of archive's backup */
  58. char this_fname[LFNAMESIZE];                    /* just filename of file to add */
  59. char latest_name[LFNAMESIZE];                 /* latest name in archive */
  60. long last_old = 0L;                                /* last direntry in old chain */
  61. ZOOFILE zoo_file;                                 /* stream for open archive */
  62. char *this_path;                                    /* pathname of file to add */
  63.  
  64. #ifdef NOENUM
  65. #define NEW_ZOO 1
  66. #define OLD_ZOO 2
  67. int zoo_status;
  68. #else
  69. enum {NEW_ZOO, OLD_ZOO} zoo_status;         /* newly created or not */
  70. #endif
  71.  
  72. long this_dir_offset;                            /* pointers to within archive */
  73. long save_position;                                /* pointer to within archive */
  74. long prev_pos;                                     /* posn of prev file of same name */
  75. struct direntry direntry;                        /* directory entry */
  76. struct direntry dir2entry;                     /* spare */
  77. int status;                                         /* error status */
  78. int success;                                        /* successful addition of file? */
  79. int addcount = 0;                                 /* number added */
  80. int update=0;                                        /* only files already in archive */
  81. int suppress=0;                                    /* suppress compression */
  82. int new=0;                                            /* add only files not in archive */
  83. int zootime = 0;                                    /* just set archive time */
  84. int add_comment = 0;                             /* add comment */
  85. int add_global_comment = 0;                    /* archive comment */
  86. int pack = 0;                                        /* pack after adding */
  87. int need_dir = 1;                                 /* store directories too */
  88. int delcount = 0;                                 /* count of deleted entries */
  89. int exit_status = 0;                             /* exit status to set */
  90.  
  91. unsigned int latest_date = 0;                 /* to set time on archive itself */
  92. unsigned int latest_time = 0;                 /* .. same */
  93. int move = 0;                                        /* delete after adding to archive */
  94. int longest;                                        /* length of longest pathname added */
  95. int firstfile = 1;                                /* first file being added? */
  96. int z_fmt = 0;                                     /* look for Z format files? */
  97. int inargs = 0;                                    /* read filenames from stdin? */
  98.  
  99. #ifdef FAST_EXT
  100. struct tiny_header tiny_header;                /* for Z format archives */
  101. #endif
  102.  
  103. unsigned this_version_no;                            /* version no. of old file */
  104. unsigned  high_vflag;                                /* version flag of old file */
  105. unsigned high_version_no;                            /* highest version no of this file */
  106. long high_pos;                                     /* offset of file w/highest ver no */
  107. unsigned int fgens;                                /* gens. to preserve -- file */
  108. unsigned int zgens;                                /* gens. to preserve -- archive */
  109. long oldcmtpos;                                    /* to save old comment */
  110. unsigned int oldcmtsiz;                         /* to save old comment */
  111. int genson = 0;                                    /* whether to turn generations on */
  112.  
  113. int use_lzh = 1;                                    /* whether to use lzh compression OIS*/
  114.  
  115. /* on entry option points to first letter */
  116.  
  117. opts_add (option, &zootime, &quiet, &suppress, &move, &new, &pack,
  118.              &update, &add_comment, &z_fmt, &need_dir, &inargs, &genson,
  119.              &use_lzh, &add_global_comment);
  120.  
  121. /* POSSIBLE RACE CONDITION BETWEEN TESTING EXISTENCE AND CREATING FILE */
  122. if (exists (zoo_path)) {
  123.     zoo_file = zooopen (zoo_path, Z_RDWR);
  124.     zoo_status = OLD_ZOO;
  125. } else {
  126.     if (!zootime)
  127.         zoo_file = zoocreate (zoo_path);
  128.     else
  129.         zoo_file = NOFILE;      /* don't create if just setting time */
  130.     zoo_status = NEW_ZOO;
  131. }
  132.  
  133. if (zoo_file == NOFILE)
  134.     prterror ('f', could_not_open, zoo_path);
  135. basename(zoo_path, zoo_fname);      /* get basename of archive */
  136. rootname (zoo_path, zoo_bak);       /* name without extension */
  137. strcat (zoo_bak, BACKUP_EXT);       /* name of backup of this archive */
  138.  
  139. /* Now we prepare the archive for adding one or more files.  If the archive
  140. has just been created, we write the archive header */
  141.  
  142. addfname ("",0L,0,0,0,0); /* initialize table of files already in archive */
  143. if (zoo_status == NEW_ZOO) {                 /* newly-created archive */
  144.     if (genson)                               /* if no generations needed */
  145.         zoo_header.vdata = (VFL_ON|GEN_DEFAULT); /* generations on */
  146.     fwr_zooh (&zoo_header, zoo_file);
  147.     zgens = GEN_DEFAULT;
  148.     zooseek (zoo_file, zoo_header.zoo_start, 0); /* seek to where data begins */
  149. } else {
  150.     /* read header and rewrite with updated version numbers, preserving
  151.         header type */
  152.     rwheader (&zoo_header, zoo_file, 1);
  153.     zgens = zoo_header.vdata & VFL_GEN;         /* get archive generations */
  154.     /* initialize latest_name to null string */
  155.     /* NOTE:  latest_name is not currently used for anything, but
  156.         may be used in the future for inserting files into the
  157.         archive in alphabetic order. */
  158.     *latest_name = '\0';
  159.  
  160.     /* Skip existing files but add them to a list.    The variable last_old
  161.     gets the tail of the old chain of directory entries */
  162.     skip_files (zoo_file, &latest_date, &latest_time, &delcount,
  163.                     latest_name, &last_old);
  164. }
  165. /* The file pointer is now positioned correctly to add a file to archive,
  166. unless the null directory entry is too short.  This will be fixed below. */
  167.  
  168. /* If we are just setting time, do it and run. */
  169. if (zootime) {
  170. #ifdef NIXTIME
  171.     zooclose (zoo_file);
  172.     setutime (zoo_path, latest_date, latest_time);
  173. #else
  174.     settime (zoo_file, latest_date, latest_time);
  175.     zooclose (zoo_file);
  176. #endif
  177.     prterror ('m', "Archive time adjusted.\n");
  178.     zooexit (0);
  179. }
  180.  
  181. /* make list of files, excluding archive and its backup */
  182. longest = LONGEST;
  183. flist = (char **) ealloc(MAXADD * sizeof(char *));
  184. if (!inargs) {
  185.     makelist(argc, argv, flist, MAXADD-2, zoo_fname, zoo_bak, ".", &longest);
  186.     /*                                               ^^             ^^         ^^ exclude */
  187. }
  188.  
  189. fptr = 0;    /* ready to get filename (if makelist() was called) or to
  190.                     begin adding filenames (if reading them from stdin) */
  191.  
  192. while (1) {
  193.     unsigned int this_date, this_time;
  194.     int INLIST; /* boolean */
  195.     int RECENT; /* boolean */
  196.     int danger; /* if update requested and disk copy is out of date */
  197.     if (inargs) {
  198.     again: /* loop back if filename was same as archive name or its backup */
  199.         this_path = getstdin();       /* pathname from stdin, in static area */
  200.         if (this_path != NULL) {
  201.             if (samefile (nameptr(zoo_fname),nameptr(this_path)) ||
  202.                         samefile (nameptr(zoo_bak),nameptr(this_path)))
  203.                 goto again;                 /* don't add archive to itself */
  204.             modpath (this_path);
  205.         /* if moving files, add to list for later deletion;  if list overflows,
  206.             terminate addition loop and give warning message */
  207.             if (move) {
  208.                 if (fptr >= MAXADD-2) {
  209.                     prterror ('w', too_many_files, MAXADD-2);
  210.                     this_path = NULL;
  211.                 } else
  212.                     flist[fptr++] = str_dup