home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 9
/
FreshFishVol9-CD2.bin
/
bbs
/
util
/
zoo-2.1.lha
/
zoo
/
zooadd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-08
|
25KB
|
745 lines
#ifndef LINT
/* derived from: zooadd.c 2.34 88/08/15 10:53:11 */
static char sccsid[]="$Source: /usr/home/dhesi/zoo/RCS/zooadd.c,v $\n\
$Id: zooadd.c,v 1.10 91/07/08 23:48:39 dhesi Exp $";
#endif /* LINT */
/*
Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
(C) Copyright 1988 Rahul Dhesi -- All rights reserved
(C) Copyright 1991 Rahul Dhesi -- All rights reserved
*/
#include "options.h"
/* Adds files specified in parameter-list to archive zoo_path. */
#define LONGEST 20 /* assumed length of longest filename */
#include "zoomem.h" /* to define MAXADD */
#include "zoo.h"
#include "zooio.h"
#include "various.h"
#include "parse.h"
#include "debug.h"
#include "portable.h"
#include "zoofns.h"
#include "errors.i"
extern int break_hit;
extern int quiet;
void show_comment PARMS ((struct direntry *, ZOOFILE, int, char *));
void dosname PARMS ((char *, char *));
void modpath PARMS ((char *));
void opts_add PARMS ((char *, int *, int *, int *, int *, int *, int *,
int *, int *, int *, int *, int *, int *, int *, int *));
int ver_too_high PARMS ((struct zoo_header *));
void get_comment PARMS ((struct direntry *, ZOOFILE, char *));
void copyfields PARMS ((struct direntry *, struct tiny_header *));
void storefname PARMS ((struct direntry *, char *, int));
char *choosefname PARMS ((struct direntry *));
extern struct zoo_header zoo_header;
extern char file_leader[];
extern unsigned int crccode;
void zooadd(zoo_path, argc, argv, option)
char *zoo_path; /* pathname of zoo archive to add to */
int argc; /* how many filespecs supplied */
char **argv; /* array of pointers to filespecs */
char *option; /* option string */
{
char *whichname; /* which name to show user */
char **flist; /* list of ptrs to input fnames */
int fptr; /* will point to within flist */
ZOOFILE this_file; /* file to add */
char zoo_fname[LFNAMESIZE]; /* basename of archive itself */
char zoo_bak[LFNAMESIZE]; /* name of archive's backup */
char this_fname[LFNAMESIZE]; /* just filename of file to add */
char latest_name[LFNAMESIZE]; /* latest name in archive */
long last_old = 0L; /* last direntry in old chain */
ZOOFILE zoo_file; /* stream for open archive */
char *this_path; /* pathname of file to add */
#ifdef NOENUM
#define NEW_ZOO 1
#define OLD_ZOO 2
int zoo_status;
#else
enum {NEW_ZOO, OLD_ZOO} zoo_status; /* newly created or not */
#endif
long this_dir_offset; /* pointers to within archive */
long save_position; /* pointer to within archive */
long prev_pos; /* posn of prev file of same name */
struct direntry direntry; /* directory entry */
struct direntry dir2entry; /* spare */
int status; /* error status */
int success; /* successful addition of file? */
int addcount = 0; /* number added */
int update=0; /* only files already in archive */
int suppress=0; /* suppress compression */
int new=0; /* add only files not in archive */
int zootime = 0; /* just set archive time */
int add_comment = 0; /* add comment */
int add_global_comment = 0; /* archive comment */
int pack = 0; /* pack after adding */
int need_dir = 1; /* store directories too */
int delcount = 0; /* count of deleted entries */
int exit_status = 0; /* exit status to set */
unsigned int latest_date = 0; /* to set time on archive itself */
unsigned int latest_time = 0; /* .. same */
int move = 0; /* delete after adding to archive */
int longest; /* length of longest pathname added */
int firstfile = 1; /* first file being added? */
int z_fmt = 0; /* look for Z format files? */
int inargs = 0; /* read filenames from stdin? */
#ifdef FAST_EXT
struct tiny_header tiny_header; /* for Z format archives */
#endif
unsigned this_version_no; /* version no. of old file */
unsigned high_vflag; /* version flag of old file */
unsigned high_version_no; /* highest version no of this file */
long high_pos; /* offset of file w/highest ver no */
unsigned int fgens; /* gens. to preserve -- file */
unsigned int zgens; /* gens. to preserve -- archive */
long oldcmtpos; /* to save old comment */
unsigned int oldcmtsiz; /* to save old comment */
int genson = 0; /* whether to turn generations on */
int use_lzh = 1; /* whether to use lzh compression OIS*/
/* on entry option points to first letter */
opts_add (option, &zootime, &quiet, &suppress, &move, &new, &pack,
&update, &add_comment, &z_fmt, &need_dir, &inargs, &genson,
&use_lzh, &add_global_comment);
/* POSSIBLE RACE CONDITION BETWEEN TESTING EXISTENCE AND CREATING FILE */
if (exists (zoo_path)) {
zoo_file = zooopen (zoo_path, Z_RDWR);
zoo_status = OLD_ZOO;
} else {
if (!zootime)
zoo_file = zoocreate (zoo_path);
else
zoo_file = NOFILE; /* don't create if just setting time */
zoo_status = NEW_ZOO;
}
if (zoo_file == NOFILE)
prterror ('f', could_not_open, zoo_path);
basename(zoo_path, zoo_fname); /* get basename of archive */
rootname (zoo_path, zoo_bak); /* name without extension */
strcat (zoo_bak, BACKUP_EXT); /* name of backup of this archive */
/* Now we prepare the archive for adding one or more files. If the archive
has just been created, we write the archive header */
addfname ("",0L,0,0,0,0); /* initialize table of files already in archive */
if (zoo_status == NEW_ZOO) { /* newly-created archive */
if (genson) /* if no generations needed */
zoo_header.vdata = (VFL_ON|GEN_DEFAULT); /* generations on */
fwr_zooh (&zoo_header, zoo_file);
zgens = GEN_DEFAULT;
zooseek (zoo_file, zoo_header.zoo_start, 0); /* seek to where data begins */
} else {
/* read header and rewrite with updated version numbers, preserving
header type */
rwheader (&zoo_header, zoo_file, 1);
zgens = zoo_header.vdata & VFL_GEN; /* get archive generations */
/* initialize latest_name to null string */
/* NOTE: latest_name is not currently used for anything, but
may be used in the future for inserting files into the
archive in alphabetic order. */
*latest_name = '\0';
/* Skip existing files but add them to a list. The variable last_old
gets the tail of the old chain of directory entries */
skip_files (zoo_file, &latest_date, &latest_time, &delcount,
latest_name, &last_old);
}
/* The file pointer is now positioned correctly to add a file to archive,
unless the null directory entry is too short. This will be fixed below. */
/* If we are just setting time, do it and run. */
if (zootime) {
#ifdef NIXTIME
zooclose (zoo_file);
setutime (zoo_path, latest_date, latest_time);
#else
settime (zoo_file, latest_date, latest_time);
zooclose (zoo_file);
#endif
prterror ('m', "Archive time adjusted.\n");
zooexit (0);
}
/* make list of files, excluding archive and its backup */
longest = LONGEST;
flist = (char **) ealloc(MAXADD * sizeof(char *));
if (!inargs) {
makelist(argc, argv, flist, MAXADD-2, zoo_fname, zoo_bak, ".", &longest);
/* ^^ ^^ ^^ exclude */
}
fptr = 0; /* ready to get filename (if makelist() was called) or to
begin adding filenames (if reading them from stdin) */
while (1) {
unsigned int this_date, this_time;
int INLIST; /* boolean */
int RECENT; /* boolean */
int danger; /* if update requested and disk copy is out of date */
if (inargs) {
again: /* loop back if filename was same as archive name or its backup */
this_path = getstdin(); /* pathname from stdin, in static area */
if (this_path != NULL) {
if (samefile (nameptr(zoo_fname),nameptr(this_path)) ||
samefile (nameptr(zoo_bak),nameptr(this_path)))
goto again; /* don't add archive to itself */
modpath (this_path);
/* if moving files, add to list for later deletion; if list overflows,
terminate addition loop and give warning message */
if (move) {
if (fptr >= MAXADD-2) {
prterror ('w', too_many_files, MAXADD-2);
this_path = NULL;
} else
flist[fptr++] = str_dup