| 1 |
/** $MirOS: src/bin/pax/tables.h,v 1.3 2007/10/23 20:07:42 tg Exp $ */ |
| 2 |
/* $OpenBSD: tables.h,v 1.8 2006/08/05 23:05:13 ray Exp $ */ |
| 3 |
/* $NetBSD: tables.h,v 1.3 1995/03/21 09:07:47 cgd Exp $ */ |
| 4 |
|
| 5 |
/*- |
| 6 |
* Copyright (c) 2005 Thorsten Glaser <tg@66h.42h.de> |
| 7 |
* Copyright (c) 1992 Keith Muller. |
| 8 |
* Copyright (c) 1992, 1993 |
| 9 |
* The Regents of the University of California. All rights reserved. |
| 10 |
* |
| 11 |
* This code is derived from software contributed to Berkeley by |
| 12 |
* Keith Muller of the University of California, San Diego. |
| 13 |
* |
| 14 |
* Redistribution and use in source and binary forms, with or without |
| 15 |
* modification, are permitted provided that the following conditions |
| 16 |
* are met: |
| 17 |
* 1. Redistributions of source code must retain the above copyright |
| 18 |
* notice, this list of conditions and the following disclaimer. |
| 19 |
* 2. Redistributions in binary form must reproduce the above copyright |
| 20 |
* notice, this list of conditions and the following disclaimer in the |
| 21 |
* documentation and/or other materials provided with the distribution. |
| 22 |
* 3. Neither the name of the University nor the names of its contributors |
| 23 |
* may be used to endorse or promote products derived from this software |
| 24 |
* without specific prior written permission. |
| 25 |
* |
| 26 |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 27 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 28 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 29 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
| 30 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 31 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 32 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 33 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 34 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 35 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 36 |
* SUCH DAMAGE. |
| 37 |
* |
| 38 |
* @(#)tables.h 8.1 (Berkeley) 5/31/93 |
| 39 |
*/ |
| 40 |
|
| 41 |
/* |
| 42 |
* data structures and constants used by the different databases kept by pax |
| 43 |
*/ |
| 44 |
|
| 45 |
/* |
| 46 |
* Hash Table Sizes MUST BE PRIME, if set too small performance suffers. |
| 47 |
* Probably safe to expect 500000 inodes per tape. Assuming good key |
| 48 |
* distribution (inodes) chains of under 50 long (worst case) is ok. |
| 49 |
*/ |
| 50 |
#define L_TAB_SZ 2503 /* hard link hash table size */ |
| 51 |
#define F_TAB_SZ 50503 /* file time hash table size */ |
| 52 |
#define N_TAB_SZ 541 /* interactive rename hash table */ |
| 53 |
#define D_TAB_SZ 317 /* unique device mapping table */ |
| 54 |
#define A_TAB_SZ 317 /* ftree dir access time reset table */ |
| 55 |
#define MAXKEYLEN 64 /* max number of chars for hash */ |
| 56 |
#define DIRP_SIZE 64 /* initial size of created dir table */ |
| 57 |
|
| 58 |
/* |
| 59 |
* file hard link structure (hashed by dev/ino and chained) used to find the |
| 60 |
* hard links in a file system or with some archive formats (cpio) |
| 61 |
*/ |
| 62 |
typedef struct hrdlnk { |
| 63 |
char *name; /* name of first file seen with this ino/dev */ |
| 64 |
dev_t dev; /* files device number */ |
| 65 |
ino_t ino; /* files inode number */ |
| 66 |
u_long nlink; /* expected link count */ |
| 67 |
struct hrdlnk *fow; |
| 68 |
} HRDLNK; |
| 69 |
|
| 70 |
/* |
| 71 |
* Archive write update file time table (the -u, -C flag), hashed by filename. |
| 72 |
* Filenames are stored in a scratch file at seek offset into the file. The |
| 73 |
* file time (mod time) and the file name length (for a quick check) are |
| 74 |
* stored in a hash table node. We were forced to use a scratch file because |
| 75 |
* with -u, the mtime for every node in the archive must always be available |
| 76 |
* to compare against (and this data can get REALLY large with big archives). |
| 77 |
* By being careful to read only when we have a good chance of a match, the |
| 78 |
* performance loss is not measurable (and the size of the archive we can |
| 79 |
* handle is greatly increased). |
| 80 |
*/ |
| 81 |
typedef struct ftm { |
| 82 |
int namelen; /* file name length */ |
| 83 |
time_t mtime; /* files last modification time */ |
| 84 |
off_t seek; /* location in scratch file */ |
| 85 |
struct ftm *fow; |
| 86 |
} FTM; |
| 87 |
|
| 88 |
/* |
| 89 |
* Interactive rename table (-i flag), hashed by orig filename. |
| 90 |
* We assume this will not be a large table as this mapping data can only be |
| 91 |
* obtained through interactive input by the user. Nobody is going to type in |
| 92 |
* changes for 500000 files? We use chaining to resolve collisions. |
| 93 |
*/ |
| 94 |
|
| 95 |
typedef struct namt { |
| 96 |
char *oname; /* old name */ |
| 97 |
char *nname; /* new name typed in by the user */ |
| 98 |
struct namt *fow; |
| 99 |
} NAMT; |
| 100 |
|
| 101 |
/* |
| 102 |
* Unique device mapping tables. Some protocols (e.g. cpio) require that the |
| 103 |
* <c_dev,c_ino> pair will uniquely identify a file in an archive unless they |
| 104 |
* are links to the same file. Appending to archives can break this. For those |
| 105 |
* protocols that have this requirement we map c_dev to a unique value not seen |
| 106 |
* in the archive when we append. We also try to handle inode truncation with |
| 107 |
* this table. (When the inode field in the archive header are too small, we |
| 108 |
* remap the dev on writes to remove accidental collisions). |
| 109 |
* |
| 110 |
* The list is hashed by device number using chain collision resolution. Off of |
| 111 |
* each DEVT are linked the various remaps for this device based on those bits |
| 112 |
* in the inode which were truncated. For example if we are just remapping to |
| 113 |
* avoid a device number during an update append, off the DEVT we would have |
| 114 |
* only a single DLIST that has a truncation id of 0 (no inode bits were |
| 115 |
* stripped for this device so far). When we spot inode truncation we create |
| 116 |
* a new mapping based on the set of bits in the inode which were stripped off. |
| 117 |
* so if the top four bits of the inode are stripped and they have a pattern of |
| 118 |
* 0110...... (where . are those bits not truncated) we would have a mapping |
| 119 |
* assigned for all inodes that has the same 0110.... pattern (with this dev |
| 120 |
* number of course). This keeps the mapping sparse and should be able to store |
| 121 |
* close to the limit of files which can be represented by the optimal |
| 122 |
* combination of dev and inode bits, and without creating a fouled up archive. |
| 123 |
* Note we also remap truncated devs in the same way (an exercise for the |
| 124 |
* dedicated reader; always wanted to say that...:) |
| 125 |
*/ |
| 126 |
|
| 127 |
typedef struct devt { |
| 128 |
dev_t dev; /* the orig device number we now have to map */ |
| 129 |
struct devt *fow; /* new device map list */ |
| 130 |
struct dlist *list; /* map list based on inode truncation bits */ |
| 131 |
} DEVT; |
| 132 |
|
| 133 |
typedef struct dlist { |
| 134 |
ino_t trunc_bits; /* truncation pattern for a specific map */ |
| 135 |
dev_t dev; /* the new device id we use */ |
| 136 |
struct dlist *fow; |
| 137 |
} DLIST; |
| 138 |
|
| 139 |
/* |
| 140 |
* ftree directory access time reset table. When we are done with a |
| 141 |
* subtree we reset the access and mod time of the directory when the tflag is |
| 142 |
* set. Not really explicitly specified in the pax spec, but easy and fast to |
| 143 |
* do (and this may have even been intended in the spec, it is not clear). |
| 144 |
* table is hashed by inode with chaining. |
| 145 |
*/ |
| 146 |
|
| 147 |
typedef struct atdir { |
| 148 |
char *name; /* name of directory to reset */ |
| 149 |
dev_t dev; /* dev and inode for fast lookup */ |
| 150 |
ino_t ino; |
| 151 |
time_t mtime; /* access and mod time to reset to */ |
| 152 |
time_t atime; |
| 153 |
struct atdir *fow; |
| 154 |
} ATDIR; |
| 155 |
|
| 156 |
/* |
| 157 |
* created directory time and mode storage entry. After pax is finished during |
| 158 |
* extraction or copy, we must reset directory access modes and times that |
| 159 |
* may have been modified after creation (they no longer have the specified |
| 160 |
* times and/or modes). We must reset time in the reverse order of creation, |
| 161 |
* because entries are added from the top of the file tree to the bottom. |
| 162 |
* We MUST reset times from leaf to root (it will not work the other |
| 163 |
* direction). |
| 164 |
*/ |
| 165 |
|
| 166 |
typedef struct dirdata { |
| 167 |
char *name; /* file name */ |
| 168 |
time_t mtime; /* mtime to set */ |
| 169 |
time_t atime; /* atime to set */ |
| 170 |
u_int16_t mode; /* file mode to restore */ |
| 171 |
u_int16_t frc_mode; /* do we force mode settings? */ |
| 172 |
} DIRDATA; |
| 173 |
|
| 174 |
/* |
| 175 |
* file hard link structure (hashed by dev/ino and chained) for anonymisation |
| 176 |
*/ |
| 177 |
typedef struct hrdflnk { |
| 178 |
dev_t dev; /* files device number */ |
| 179 |
ino_t ino; /* files inode number */ |
| 180 |
u_long nlink; /* expected link count */ |
| 181 |
ino_t newi; /* new inode number */ |
| 182 |
struct hrdflnk *fow; |
| 183 |
} HRDFLNK; |