1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
|
/* @(#)append.c 1.21 05/08/21 Copyright 1992, 2001-2003 J. Schilling */
#ifndef lint
static char sccsid[] =
"@(#)append.c 1.21 05/08/21 Copyright 1992, 2001-2003 J. Schilling";
#endif
/*
* Routines used to append files to an existing
* tape archive
*
* Copyright (c) 1992, 2001-2003 J. Schilling
*/
/*
* Copyright Jrg Schilling. All rights reserved.
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only.
* See the file CDDL.Schily.txt in this distribution or
* http://opensource.org/licenses/cddl1.php for details.
*/
#include <mconfig.h>
#include <stdio.h>
#include <unixstd.h>
#include <standard.h>
#include "star.h"
#include <schily.h>
#include "starsubs.h"
extern FILE *vpr;
extern BOOL debug;
extern BOOL cflag;
extern BOOL uflag;
extern BOOL rflag;
/*
* XXX We should try to share the hash code with lhash.c
*/
static struct h_elem {
struct h_elem *h_next;
time_t h_time;
long h_nsec;
short h_len;
char h_flags;
char h_data[1]; /* Variable size. */
} **h_tab;
#define HF_NSEC 0x01 /* have nsecs */
static unsigned h_size;
LOCAL int cachesize;
EXPORT void skipall __PR((void));
LOCAL void hash_new __PR((size_t size));
LOCAL struct h_elem * uhash_lookup __PR((FINFO *info));
LOCAL void hash_add __PR((FINFO *info));
EXPORT BOOL update_newer __PR((FINFO *info));
LOCAL int hashval __PR((Uchar *str, Uint maxsize));
EXPORT void
skipall()
{
FINFO finfo;
TCB tb;
char name[PATH_MAX+1];
char lname[PATH_MAX+1];
register TCB *ptb = &tb;
if (uflag)
hash_new(100);
fillbytes((char *)&finfo, sizeof (finfo), '\0');
finfo.f_tcb = ptb;
for (;;) {
if (get_tcb(ptb) == EOF)
break;
finfo.f_name = name;
finfo.f_lname = lname;
if (tcb_to_info(ptb, &finfo) == EOF)
break;
if (debug)
fprintf(vpr, "R %s\n", finfo.f_name);
if (uflag)
hash_add(&finfo);
void_file(&finfo);
}
if (debug)
error("used %d bytes for update cache.\n", cachesize);
}
#include <strdefs.h>
LOCAL void
hash_new(size)
size_t size;
{
register int i;
h_size = size;
h_tab = (struct h_elem **)__malloc(size * sizeof (struct h_elem *), "new hash");
for (i = 0; i < size; i++) h_tab[i] = 0;
cachesize += size * sizeof (struct h_elem *);
}
LOCAL struct h_elem *
uhash_lookup(info)
FINFO *info;
{
register char *name = info->f_name;
register struct h_elem *hp;
register int hv;
hv = hashval((unsigned char *)name, h_size);
for (hp = h_tab[hv]; hp; hp = hp->h_next) {
if (streql(name, hp->h_data))
return (hp);
}
return (0);
}
LOCAL void
hash_add(info)
FINFO *info;
{
register int len;
register struct h_elem *hp;
register int hv;
/*
* XXX nsec korrekt implementiert?
*/
if ((hp = uhash_lookup(info)) != 0) {
if (hp->h_time < info->f_mtime) {
hp->h_time = info->f_mtime;
hp->h_nsec = info->f_mnsec;
} else if (hp->h_time == info->f_mtime) {
/*
* If the current archive entry holds extended
* time imformation, honor it.
*/
if (info->f_xflags & XF_MTIME)
hp->h_flags |= HF_NSEC;
else
hp->h_flags &= ~HF_NSEC;
if ((hp->h_flags & HF_NSEC) &&
(hp->h_nsec < info->f_mnsec))
hp->h_nsec = info->f_mnsec;
}
return;
}
len = strlen(info->f_name);
hp = __malloc((size_t)len + sizeof (struct h_elem), "add hash");
cachesize += len + sizeof (struct h_elem);
strcpy(hp->h_data, info->f_name);
hp->h_time = info->f_mtime;
hp->h_nsec = info->f_mnsec;
hp->h_flags = 0;
if (info->f_xflags & XF_MTIME)
hp->h_flags |= HF_NSEC;
hv = hashval((unsigned char *)info->f_name, h_size);
hp->h_next = h_tab[hv];
h_tab[hv] = hp;
}
EXPORT BOOL
update_newer(info)
FINFO *info;
{
register struct h_elem *hp;
/*
* XXX nsec korrekt implementiert?
*/
if ((hp = uhash_lookup(info)) != 0) {
if (info->f_mtime > hp->h_time)
return (TRUE);
if ((hp->h_flags & HF_NSEC) && (info->f_flags & F_NSECS) &&
info->f_mtime == hp->h_time && info->f_mnsec > hp->h_nsec)
return (TRUE);
return (FALSE);
}
return (TRUE);
}
LOCAL int
hashval(str, maxsize)
register Uchar *str;
Uint maxsize;
{
register int sum = 0;
register int i;
register int c;
for (i = 0; (c = *str++) != '\0'; i++)
sum ^= (c << (i&7));
return (sum % maxsize);
}
|