Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/bin/pax/tables.c
39475 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (c) 1992 Keith Muller.
5
* Copyright (c) 1992, 1993
6
* The Regents of the University of California. All rights reserved.
7
*
8
* This code is derived from software contributed to Berkeley by
9
* Keith Muller of the University of California, San Diego.
10
*
11
* Redistribution and use in source and binary forms, with or without
12
* modification, are permitted provided that the following conditions
13
* are met:
14
* 1. Redistributions of source code must retain the above copyright
15
* notice, this list of conditions and the following disclaimer.
16
* 2. Redistributions in binary form must reproduce the above copyright
17
* notice, this list of conditions and the following disclaimer in the
18
* documentation and/or other materials provided with the distribution.
19
* 3. Neither the name of the University nor the names of its contributors
20
* may be used to endorse or promote products derived from this software
21
* without specific prior written permission.
22
*
23
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
* SUCH DAMAGE.
34
*/
35
36
#include <sys/types.h>
37
#include <sys/time.h>
38
#include <sys/stat.h>
39
#include <sys/fcntl.h>
40
#include <errno.h>
41
#include <stdio.h>
42
#include <stdlib.h>
43
#include <string.h>
44
#include <unistd.h>
45
#include "pax.h"
46
#include "tables.h"
47
#include "extern.h"
48
49
/*
50
* Routines for controlling the contents of all the different databases pax
51
* keeps. Tables are dynamically created only when they are needed. The
52
* goal was speed and the ability to work with HUGE archives. The databases
53
* were kept simple, but do have complex rules for when the contents change.
54
* As of this writing, the POSIX library functions were more complex than
55
* needed for this application (pax databases have very short lifetimes and
56
* do not survive after pax is finished). Pax is required to handle very
57
* large archives. These database routines carefully combine memory usage and
58
* temporary file storage in ways which will not significantly impact runtime
59
* performance while allowing the largest possible archives to be handled.
60
* Trying to force the fit to the POSIX database routines was not considered
61
* time well spent.
62
*/
63
64
static HRDLNK **ltab = NULL; /* hard link table for detecting hard links */
65
static FTM **ftab = NULL; /* file time table for updating arch */
66
static NAMT **ntab = NULL; /* interactive rename storage table */
67
static DEVT **dtab = NULL; /* device/inode mapping tables */
68
static ATDIR **atab = NULL; /* file tree directory time reset table */
69
static int dirfd = -1; /* storage for setting created dir time/mode */
70
static u_long dircnt; /* entries in dir time/mode storage */
71
static int ffd = -1; /* tmp file for file time table name storage */
72
73
static DEVT *chk_dev(dev_t, int);
74
75
/*
76
* hard link table routines
77
*
78
* The hard link table tries to detect hard links to files using the device and
79
* inode values. We do this when writing an archive, so we can tell the format
80
* write routine that this file is a hard link to another file. The format
81
* write routine then can store this file in whatever way it wants (as a hard
82
* link if the format supports that like tar, or ignore this info like cpio).
83
* (Actually a field in the format driver table tells us if the format wants
84
* hard link info. if not, we do not waste time looking for them). We also use
85
* the same table when reading an archive. In that situation, this table is
86
* used by the format read routine to detect hard links from stored dev and
87
* inode numbers (like cpio). This will allow pax to create a link when one
88
* can be detected by the archive format.
89
*/
90
91
/*
92
* lnk_start
93
* Creates the hard link table.
94
* Return:
95
* 0 if created, -1 if failure
96
*/
97
98
int
99
lnk_start(void)
100
{
101
if (ltab != NULL)
102
return(0);
103
if ((ltab = (HRDLNK **)calloc(L_TAB_SZ, sizeof(HRDLNK *))) == NULL) {
104
paxwarn(1, "Cannot allocate memory for hard link table");
105
return(-1);
106
}
107
return(0);
108
}
109
110
/*
111
* chk_lnk()
112
* Looks up entry in hard link hash table. If found, it copies the name
113
* of the file it is linked to (we already saw that file) into ln_name.
114
* lnkcnt is decremented and if goes to 1 the node is deleted from the
115
* database. (We have seen all the links to this file). If not found,
116
* we add the file to the database if it has the potential for having
117
* hard links to other files we may process (it has a link count > 1)
118
* Return:
119
* if found returns 1; if not found returns 0; -1 on error
120
*/
121
122
int
123
chk_lnk(ARCHD *arcn)
124
{
125
HRDLNK *pt;
126
HRDLNK **ppt;
127
u_int indx;
128
129
if (ltab == NULL)
130
return(-1);
131
/*
132
* ignore those nodes that cannot have hard links
133
*/
134
if ((arcn->type == PAX_DIR) || (arcn->sb.st_nlink <= 1))
135
return(0);
136
137
/*
138
* hash inode number and look for this file
139
*/
140
indx = ((unsigned)arcn->sb.st_ino) % L_TAB_SZ;
141
if ((pt = ltab[indx]) != NULL) {
142
/*
143
* it's hash chain in not empty, walk down looking for it
144
*/
145
ppt = &(ltab[indx]);
146
while (pt != NULL) {
147
if ((pt->ino == arcn->sb.st_ino) &&
148
(pt->dev == arcn->sb.st_dev))
149
break;
150
ppt = &(pt->fow);
151
pt = pt->fow;
152
}
153
154
if (pt != NULL) {
155
/*
156
* found a link. set the node type and copy in the
157
* name of the file it is to link to. we need to
158
* handle hardlinks to regular files differently than
159
* other links.
160
*/
161
arcn->ln_nlen = l_strncpy(arcn->ln_name, pt->name,
162
sizeof(arcn->ln_name) - 1);
163
arcn->ln_name[arcn->ln_nlen] = '\0';
164
if (arcn->type == PAX_REG)
165
arcn->type = PAX_HRG;
166
else
167
arcn->type = PAX_HLK;
168
169
/*
170
* if we have found all the links to this file, remove
171
* it from the database
172
*/
173
if (--pt->nlink <= 1) {
174
*ppt = pt->fow;
175
free(pt->name);
176
free(pt);
177
}
178
return(1);
179
}
180
}
181
182
/*
183
* we never saw this file before. It has links so we add it to the
184
* front of this hash chain
185
*/
186
if ((pt = (HRDLNK *)malloc(sizeof(HRDLNK))) != NULL) {
187
if ((pt->name = strdup(arcn->name)) != NULL) {
188
pt->dev = arcn->sb.st_dev;
189
pt->ino = arcn->sb.st_ino;
190
pt->nlink = arcn->sb.st_nlink;
191
pt->fow = ltab[indx];
192
ltab[indx] = pt;
193
return(0);
194
}
195
free(pt);
196
}
197
198
paxwarn(1, "Hard link table out of memory");
199
return(-1);
200
}
201
202
/*
203
* purg_lnk
204
* remove reference for a file that we may have added to the data base as
205
* a potential source for hard links. We ended up not using the file, so
206
* we do not want to accidentally point another file at it later on.
207
*/
208
209
void
210
purg_lnk(ARCHD *arcn)
211
{
212
HRDLNK *pt;
213
HRDLNK **ppt;
214
u_int indx;
215
216
if (ltab == NULL)
217
return;
218
/*
219
* do not bother to look if it could not be in the database
220
*/
221
if ((arcn->sb.st_nlink <= 1) || (arcn->type == PAX_DIR) ||
222
(arcn->type == PAX_HLK) || (arcn->type == PAX_HRG))
223
return;
224
225
/*
226
* find the hash chain for this inode value, if empty return
227
*/
228
indx = ((unsigned)arcn->sb.st_ino) % L_TAB_SZ;
229
if ((pt = ltab[indx]) == NULL)
230
return;
231
232
/*
233
* walk down the list looking for the inode/dev pair, unlink and
234
* free if found
235
*/
236
ppt = &(ltab[indx]);
237
while (pt != NULL) {
238
if ((pt->ino == arcn->sb.st_ino) &&
239
(pt->dev == arcn->sb.st_dev))
240
break;
241
ppt = &(pt->fow);
242
pt = pt->fow;
243
}
244
if (pt == NULL)
245
return;
246
247
/*
248
* remove and free it
249
*/
250
*ppt = pt->fow;
251
free(pt->name);
252
free(pt);
253
}
254
255
/*
256
* lnk_end()
257
* Pull apart an existing link table so we can reuse it. We do this between
258
* read and write phases of append with update. (The format may have
259
* used the link table, and we need to start with a fresh table for the
260
* write phase).
261
*/
262
263
void
264
lnk_end(void)
265
{
266
int i;
267
HRDLNK *pt;
268
HRDLNK *ppt;
269
270
if (ltab == NULL)
271
return;
272
273
for (i = 0; i < L_TAB_SZ; ++i) {
274
if (ltab[i] == NULL)
275
continue;
276
pt = ltab[i];
277
ltab[i] = NULL;
278
279
/*
280
* free up each entry on this chain
281
*/
282
while (pt != NULL) {
283
ppt = pt;
284
pt = ppt->fow;
285
free(ppt->name);
286
free(ppt);
287
}
288
}
289
return;
290
}
291
292
/*
293
* modification time table routines
294
*
295
* The modification time table keeps track of last modification times for all
296
* files stored in an archive during a write phase when -u is set. We only
297
* add a file to the archive if it is newer than a file with the same name
298
* already stored on the archive (if there is no other file with the same
299
* name on the archive it is added). This applies to writes and appends.
300
* An append with an -u must read the archive and store the modification time
301
* for every file on that archive before starting the write phase. It is clear
302
* that this is one HUGE database. To save memory space, the actual file names
303
* are stored in a scratch file and indexed by an in memory hash table. The
304
* hash table is indexed by hashing the file path. The nodes in the table store
305
* the length of the filename and the lseek offset within the scratch file
306
* where the actual name is stored. Since there are never any deletions from
307
* this table, fragmentation of the scratch file is never an issue. Lookups
308
* seem to not exhibit any locality at all (files in the database are rarely
309
* looked up more than once...). So caching is just a waste of memory. The
310
* only limitation is the amount of scratch file space available to store the
311
* path names.
312
*/
313
314
/*
315
* ftime_start()
316
* create the file time hash table and open for read/write the scratch
317
* file. (after created it is unlinked, so when we exit we leave
318
* no witnesses).
319
* Return:
320
* 0 if the table and file was created ok, -1 otherwise
321
*/
322
323
int
324
ftime_start(void)
325
{
326
327
if (ftab != NULL)
328
return(0);
329
if ((ftab = (FTM **)calloc(F_TAB_SZ, sizeof(FTM *))) == NULL) {
330
paxwarn(1, "Cannot allocate memory for file time table");
331
return(-1);
332
}
333
334
/*
335
* get random name and create temporary scratch file, unlink name
336
* so it will get removed on exit
337
*/
338
memcpy(tempbase, _TFILE_BASE, sizeof(_TFILE_BASE));
339
if ((ffd = mkstemp(tempfile)) < 0) {
340
syswarn(1, errno, "Unable to create temporary file: %s",
341
tempfile);
342
return(-1);
343
}
344
(void)unlink(tempfile);
345
346
return(0);
347
}
348
349
/*
350
* chk_ftime()
351
* looks up entry in file time hash table. If not found, the file is
352
* added to the hash table and the file named stored in the scratch file.
353
* If a file with the same name is found, the file times are compared and
354
* the most recent file time is retained. If the new file was younger (or
355
* was not in the database) the new file is selected for storage.
356
* Return:
357
* 0 if file should be added to the archive, 1 if it should be skipped,
358
* -1 on error
359
*/
360
361
int
362
chk_ftime(ARCHD *arcn)
363
{
364
FTM *pt;
365
int namelen;
366
u_int indx;
367
char ckname[PAXPATHLEN+1];
368
369
/*
370
* no info, go ahead and add to archive
371
*/
372
if (ftab == NULL)
373
return(0);
374
375
/*
376
* hash the pathname and look up in table
377
*/
378
namelen = arcn->nlen;
379
indx = st_hash(arcn->name, namelen, F_TAB_SZ);
380
if ((pt = ftab[indx]) != NULL) {
381
/*
382
* the hash chain is not empty, walk down looking for match
383
* only read up the path names if the lengths match, speeds
384
* up the search a lot
385
*/
386
while (pt != NULL) {
387
if (pt->namelen == namelen) {
388
/*
389
* potential match, have to read the name
390
* from the scratch file.
391
*/
392
if (lseek(ffd,pt->seek,SEEK_SET) != pt->seek) {
393
syswarn(1, errno,
394
"Failed ftime table seek");
395
return(-1);
396
}
397
if (read(ffd, ckname, namelen) != namelen) {
398
syswarn(1, errno,
399
"Failed ftime table read");
400
return(-1);
401
}
402
403
/*
404
* if the names match, we are done
405
*/
406
if (!strncmp(ckname, arcn->name, namelen))
407
break;
408
}
409
410
/*
411
* try the next entry on the chain
412
*/
413
pt = pt->fow;
414
}
415
416
if (pt != NULL) {
417
/*
418
* found the file, compare the times, save the newer
419
*/
420
if (arcn->sb.st_mtime > pt->mtime) {
421
/*
422
* file is newer
423
*/
424
pt->mtime = arcn->sb.st_mtime;
425
return(0);
426
}
427
/*
428
* file is older
429
*/
430
return(1);
431
}
432
}
433
434
/*
435
* not in table, add it
436
*/
437
if ((pt = (FTM *)malloc(sizeof(FTM))) != NULL) {
438
/*
439
* add the name at the end of the scratch file, saving the
440
* offset. add the file to the head of the hash chain
441
*/
442
if ((pt->seek = lseek(ffd, (off_t)0, SEEK_END)) >= 0) {
443
if (write(ffd, arcn->name, namelen) == namelen) {
444
pt->mtime = arcn->sb.st_mtime;
445
pt->namelen = namelen;
446
pt->fow = ftab[indx];
447
ftab[indx] = pt;
448
return(0);
449
}
450
syswarn(1, errno, "Failed write to file time table");
451
} else
452
syswarn(1, errno, "Failed seek on file time table");
453
} else
454
paxwarn(1, "File time table ran out of memory");
455
456
if (pt != NULL)
457
free(pt);
458
return(-1);
459
}
460
461
/*
462
* Interactive rename table routines
463
*
464
* The interactive rename table keeps track of the new names that the user
465
* assigns to files from tty input. Since this map is unique for each file
466
* we must store it in case there is a reference to the file later in archive
467
* (a link). Otherwise we will be unable to find the file we know was
468
* extracted. The remapping of these files is stored in a memory based hash
469
* table (it is assumed since input must come from /dev/tty, it is unlikely to
470
* be a very large table).
471
*/
472
473
/*
474
* name_start()
475
* create the interactive rename table
476
* Return:
477
* 0 if successful, -1 otherwise
478
*/
479
480
int
481
name_start(void)
482
{
483
if (ntab != NULL)
484
return(0);
485
if ((ntab = (NAMT **)calloc(N_TAB_SZ, sizeof(NAMT *))) == NULL) {
486
paxwarn(1, "Cannot allocate memory for interactive rename table");
487
return(-1);
488
}
489
return(0);
490
}
491
492
/*
493
* add_name()
494
* add the new name to old name mapping just created by the user.
495
* If an old name mapping is found (there may be duplicate names on an
496
* archive) only the most recent is kept.
497
* Return:
498
* 0 if added, -1 otherwise
499
*/
500
501
int
502
add_name(char *oname, int onamelen, char *nname)
503
{
504
NAMT *pt;
505
u_int indx;
506
507
if (ntab == NULL) {
508
/*
509
* should never happen
510
*/
511
paxwarn(0, "No interactive rename table, links may fail\n");
512
return(0);
513
}
514
515
/*
516
* look to see if we have already mapped this file, if so we
517
* will update it
518
*/
519
indx = st_hash(oname, onamelen, N_TAB_SZ);
520
if ((pt = ntab[indx]) != NULL) {
521
/*
522
* look down the has chain for the file
523
*/
524
while ((pt != NULL) && (strcmp(oname, pt->oname) != 0))
525
pt = pt->fow;
526
527
if (pt != NULL) {
528
/*
529
* found an old mapping, replace it with the new one
530
* the user just input (if it is different)
531
*/
532
if (strcmp(nname, pt->nname) == 0)
533
return(0);
534
535
free(pt->nname);
536
if ((pt->nname = strdup(nname)) == NULL) {
537
paxwarn(1, "Cannot update rename table");
538
return(-1);
539
}
540
return(0);
541
}
542
}
543
544
/*
545
* this is a new mapping, add it to the table
546
*/
547
if ((pt = (NAMT *)malloc(sizeof(NAMT))) != NULL) {
548
if ((pt->oname = strdup(oname)) != NULL) {
549
if ((pt->nname = strdup(nname)) != NULL) {
550
pt->fow = ntab[indx];
551
ntab[indx] = pt;
552
return(0);
553
}
554
free(pt->oname);
555
}
556
free(pt);
557
}
558
paxwarn(1, "Interactive rename table out of memory");
559
return(-1);
560
}
561
562
/*
563
* sub_name()
564
* look up a link name to see if it points at a file that has been
565
* remapped by the user. If found, the link is adjusted to contain the
566
* new name (oname is the link to name)
567
*/
568
569
void
570
sub_name(char *oname, int *onamelen, size_t onamesize)
571
{
572
NAMT *pt;
573
u_int indx;
574
575
if (ntab == NULL)
576
return;
577
/*
578
* look the name up in the hash table
579
*/
580
indx = st_hash(oname, *onamelen, N_TAB_SZ);
581
if ((pt = ntab[indx]) == NULL)
582
return;
583
584
while (pt != NULL) {
585
/*
586
* walk down the hash chain looking for a match
587
*/
588
if (strcmp(oname, pt->oname) == 0) {
589
/*
590
* found it, replace it with the new name
591
* and return (we know that oname has enough space)
592
*/
593
*onamelen = l_strncpy(oname, pt->nname, onamesize - 1);
594
oname[*onamelen] = '\0';
595
return;
596
}
597
pt = pt->fow;
598
}
599
600
/*
601
* no match, just return
602
*/
603
return;
604
}
605
606
/*
607
* device/inode mapping table routines
608
* (used with formats that store device and inodes fields)
609
*
610
* device/inode mapping tables remap the device field in an archive header. The
611
* device/inode fields are used to determine when files are hard links to each
612
* other. However these values have very little meaning outside of that. This
613
* database is used to solve one of two different problems.
614
*
615
* 1) when files are appended to an archive, while the new files may have hard
616
* links to each other, you cannot determine if they have hard links to any
617
* file already stored on the archive from a prior run of pax. We must assume
618
* that these inode/device pairs are unique only within a SINGLE run of pax
619
* (which adds a set of files to an archive). So we have to make sure the
620
* inode/dev pairs we add each time are always unique. We do this by observing
621
* while the inode field is very dense, the use of the dev field is fairly
622
* sparse. Within each run of pax, we remap any device number of a new archive
623
* member that has a device number used in a prior run and already stored in a
624
* file on the archive. During the read phase of the append, we store the
625
* device numbers used and mark them to not be used by any file during the
626
* write phase. If during write we go to use one of those old device numbers,
627
* we remap it to a new value.
628
*
629
* 2) Often the fields in the archive header used to store these values are
630
* too small to store the entire value. The result is an inode or device value
631
* which can be truncated. This really can foul up an archive. With truncation
632
* we end up creating links between files that are really not links (after
633
* truncation the inodes are the same value). We address that by detecting
634
* truncation and forcing a remap of the device field to split truncated
635
* inodes away from each other. Each truncation creates a pattern of bits that
636
* are removed. We use this pattern of truncated bits to partition the inodes
637
* on a single device to many different devices (each one represented by the
638
* truncated bit pattern). All inodes on the same device that have the same
639
* truncation pattern are mapped to the same new device. Two inodes that
640
* truncate to the same value clearly will always have different truncation
641
* bit patterns, so they will be split from away each other. When we spot
642
* device truncation we remap the device number to a non truncated value.
643
* (for more info see table.h for the data structures involved).
644
*/
645
646
/*
647
* dev_start()
648
* create the device mapping table
649
* Return:
650
* 0 if successful, -1 otherwise
651
*/
652
653
int
654
dev_start(void)
655
{
656
if (dtab != NULL)
657
return(0);
658
if ((dtab = (DEVT **)calloc(D_TAB_SZ, sizeof(DEVT *))) == NULL) {
659
paxwarn(1, "Cannot allocate memory for device mapping table");
660
return(-1);
661
}
662
return(0);
663
}
664
665
/*
666
* add_dev()
667
* add a device number to the table. this will force the device to be
668
* remapped to a new value if it be used during a write phase. This
669
* function is called during the read phase of an append to prohibit the
670
* use of any device number already in the archive.
671
* Return:
672
* 0 if added ok, -1 otherwise
673
*/
674
675
int
676
add_dev(ARCHD *arcn)
677
{
678
if (chk_dev(arcn->sb.st_dev, 1) == NULL)
679
return(-1);
680
return(0);
681
}
682
683
/*
684
* chk_dev()
685
* check for a device value in the device table. If not found and the add
686
* flag is set, it is added. This does NOT assign any mapping values, just
687
* adds the device number as one that need to be remapped. If this device
688
* is already mapped, just return with a pointer to that entry.
689
* Return:
690
* pointer to the entry for this device in the device map table. Null
691
* if the add flag is not set and the device is not in the table (it is
692
* not been seen yet). If add is set and the device cannot be added, null
693
* is returned (indicates an error).
694
*/
695
696
static DEVT *
697
chk_dev(dev_t dev, int add)
698
{
699
DEVT *pt;
700
u_int indx;
701
702
if (dtab == NULL)
703
return(NULL);
704
/*
705
* look to see if this device is already in the table
706
*/
707
indx = ((unsigned)dev) % D_TAB_SZ;
708
if ((pt = dtab[indx]) != NULL) {
709
while ((pt != NULL) && (pt->dev != dev))
710
pt = pt->fow;
711
712
/*
713
* found it, return a pointer to it
714
*/
715
if (pt != NULL)
716
return(pt);
717
}
718
719
/*
720
* not in table, we add it only if told to as this may just be a check
721
* to see if a device number is being used.
722
*/
723
if (add == 0)
724
return(NULL);
725
726
/*
727
* allocate a node for this device and add it to the front of the hash
728
* chain. Note we do not assign remaps values here, so the pt->list
729
* list must be NULL.
730
*/
731
if ((pt = (DEVT *)malloc(sizeof(DEVT))) == NULL) {
732
paxwarn(1, "Device map table out of memory");
733
return(NULL);
734
}
735
pt->dev = dev;
736
pt->list = NULL;
737
pt->fow = dtab[indx];
738
dtab[indx] = pt;
739
return(pt);
740
}
741
/*
742
* map_dev()
743
* given an inode and device storage mask (the mask has a 1 for each bit
744
* the archive format is able to store in a header), we check for inode
745
* and device truncation and remap the device as required. Device mapping
746
* can also occur when during the read phase of append a device number was
747
* seen (and was marked as do not use during the write phase). WE ASSUME
748
* that unsigned longs are the same size or bigger than the fields used
749
* for ino_t and dev_t. If not the types will have to be changed.
750
* Return:
751
* 0 if all ok, -1 otherwise.
752
*/
753
754
int
755
map_dev(ARCHD *arcn, u_long dev_mask, u_long ino_mask)
756
{
757
DEVT *pt;
758
DLIST *dpt;
759
static dev_t lastdev = 0; /* next device number to try */
760
int trc_ino = 0;
761
int trc_dev = 0;
762
ino_t trunc_bits = 0;
763
ino_t nino;
764
765
if (dtab == NULL)
766
return(0);
767
/*
768
* check for device and inode truncation, and extract the truncated
769
* bit pattern.
770
*/
771
if ((arcn->sb.st_dev & (dev_t)dev_mask) != arcn->sb.st_dev)
772
++trc_dev;
773
if ((nino = arcn->sb.st_ino & (ino_t)ino_mask) != arcn->sb.st_ino) {
774
++trc_ino;
775
trunc_bits = arcn->sb.st_ino & (ino_t)(~ino_mask);
776
}
777
778
/*
779
* see if this device is already being mapped, look up the device
780
* then find the truncation bit pattern which applies
781
*/
782
if ((pt = chk_dev(arcn->sb.st_dev, 0)) != NULL) {
783
/*
784
* this device is already marked to be remapped
785
*/
786
for (dpt = pt->list; dpt != NULL; dpt = dpt->fow)
787
if (dpt->trunc_bits == trunc_bits)
788
break;
789
790
if (dpt != NULL) {
791
/*
792
* we are being remapped for this device and pattern
793
* change the device number to be stored and return
794
*/
795
arcn->sb.st_dev = dpt->dev;
796
arcn->sb.st_ino = nino;
797
return(0);
798
}
799
} else {
800
/*
801
* this device is not being remapped YET. if we do not have any
802
* form of truncation, we do not need a remap
803
*/
804
if (!trc_ino && !trc_dev)
805
return(0);
806
807
/*
808
* we have truncation, have to add this as a device to remap
809
*/
810
if ((pt = chk_dev(arcn->sb.st_dev, 1)) == NULL)
811
goto bad;
812
813
/*
814
* if we just have a truncated inode, we have to make sure that
815
* all future inodes that do not truncate (they have the
816
* truncation pattern of all 0's) continue to map to the same
817
* device number. We probably have already written inodes with
818
* this device number to the archive with the truncation
819
* pattern of all 0's. So we add the mapping for all 0's to the
820
* same device number.
821
*/
822
if (!trc_dev && (trunc_bits != 0)) {
823
if ((dpt = (DLIST *)malloc(sizeof(DLIST))) == NULL)
824
goto bad;
825
dpt->trunc_bits = 0;
826
dpt->dev = arcn->sb.st_dev;
827
dpt->fow = pt->list;
828
pt->list = dpt;
829
}
830
}
831
832
/*
833
* look for a device number not being used. We must watch for wrap
834
* around on lastdev (so we do not get stuck looking forever!)
835
*/
836
while (++lastdev > 0) {
837
if (chk_dev(lastdev, 0) != NULL)
838
continue;
839
/*
840
* found an unused value. If we have reached truncation point
841
* for this format we are hosed, so we give up. Otherwise we
842
* mark it as being used.
843
*/
844
if (((lastdev & ((dev_t)dev_mask)) != lastdev) ||
845
(chk_dev(lastdev, 1) == NULL))
846
goto bad;
847
break;
848
}
849
850
if ((lastdev <= 0) || ((dpt = (DLIST *)malloc(sizeof(DLIST))) == NULL))
851
goto bad;
852
853
/*
854
* got a new device number, store it under this truncation pattern.
855
* change the device number this file is being stored with.
856
*/
857
dpt->trunc_bits = trunc_bits;
858
dpt->dev = lastdev;
859
dpt->fow = pt->list;
860
pt->list = dpt;
861
arcn->sb.st_dev = lastdev;
862
arcn->sb.st_ino = nino;
863
return(0);
864
865
bad:
866
paxwarn(1, "Unable to fix truncated inode/device field when storing %s",
867
arcn->name);
868
paxwarn(0, "Archive may create improper hard links when extracted");
869
return(0);
870
}
871
872
/*
873
* directory access/mod time reset table routines (for directories READ by pax)
874
*
875
* The pax -t flag requires that access times of archive files be the same
876
* before being read by pax. For regular files, access time is restored after
877
* the file has been copied. This database provides the same functionality for
878
* directories read during file tree traversal. Restoring directory access time
879
* is more complex than files since directories may be read several times until
880
* all the descendants in their subtree are visited by fts. Directory access
881
* and modification times are stored during the fts pre-order visit (done
882
* before any descendants in the subtree are visited) and restored after the
883
* fts post-order visit (after all the descendants have been visited). In the
884
* case of premature exit from a subtree (like from the effects of -n), any
885
* directory entries left in this database are reset during final cleanup
886
* operations of pax. Entries are hashed by inode number for fast lookup.
887
*/
888
889
/*
890
* atdir_start()
891
* create the directory access time database for directories READ by pax.
892
* Return:
893
* 0 is created ok, -1 otherwise.
894
*/
895
896
int
897
atdir_start(void)
898
{
899
if (atab != NULL)
900
return(0);
901
if ((atab = (ATDIR **)calloc(A_TAB_SZ, sizeof(ATDIR *))) == NULL) {
902
paxwarn(1,"Cannot allocate space for directory access time table");
903
return(-1);
904
}
905
return(0);
906
}
907
908
909
/*
910
* atdir_end()
911
* walk through the directory access time table and reset the access time
912
* of any directory who still has an entry left in the database. These
913
* entries are for directories READ by pax
914
*/
915
916
void
917
atdir_end(void)
918
{
919
ATDIR *pt;
920
int i;
921
922
if (atab == NULL)
923
return;
924
/*
925
* for each non-empty hash table entry reset all the directories
926
* chained there.
927
*/
928
for (i = 0; i < A_TAB_SZ; ++i) {
929
if ((pt = atab[i]) == NULL)
930
continue;
931
/*
932
* remember to force the times, set_ftime() looks at pmtime
933
* and patime, which only applies to things CREATED by pax,
934
* not read by pax. Read time reset is controlled by -t.
935
*/
936
for (; pt != NULL; pt = pt->fow)
937
set_ftime(pt->name, pt->mtime, pt->atime, 1);
938
}
939
}
940
941
/*
942
* add_atdir()
943
* add a directory to the directory access time table. Table is hashed
944
* and chained by inode number. This is for directories READ by pax
945
*/
946
947
void
948
add_atdir(char *fname, dev_t dev, ino_t ino, time_t mtime, time_t atime)
949
{
950
ATDIR *pt;
951
u_int indx;
952
953
if (atab == NULL)
954
return;
955
956
/*
957
* make sure this directory is not already in the table, if so just
958
* return (the older entry always has the correct time). The only
959
* way this will happen is when the same subtree can be traversed by
960
* different args to pax and the -n option is aborting fts out of a
961
* subtree before all the post-order visits have been made.
962
*/
963
indx = ((unsigned)ino) % A_TAB_SZ;
964
if ((pt = atab[indx]) != NULL) {
965
while (pt != NULL) {
966
if ((pt->ino == ino) && (pt->dev == dev))
967
break;
968
pt = pt->fow;
969
}
970
971
/*
972
* oops, already there. Leave it alone.
973
*/
974
if (pt != NULL)
975
return;
976
}
977
978
/*
979
* add it to the front of the hash chain
980
*/
981
if ((pt = (ATDIR *)malloc(sizeof(ATDIR))) != NULL) {
982
if ((pt->name = strdup(fname)) != NULL) {
983
pt->dev = dev;
984
pt->ino = ino;
985
pt->mtime = mtime;
986
pt->atime = atime;
987
pt->fow = atab[indx];
988
atab[indx] = pt;
989
return;
990
}
991
free(pt);
992
}
993
994
paxwarn(1, "Directory access time reset table ran out of memory");
995
return;
996
}
997
998
/*
999
* get_atdir()
1000
* look up a directory by inode and device number to obtain the access
1001
* and modification time you want to set to. If found, the modification
1002
* and access time parameters are set and the entry is removed from the
1003
* table (as it is no longer needed). These are for directories READ by
1004
* pax
1005
* Return:
1006
* 0 if found, -1 if not found.
1007
*/
1008
1009
int
1010
get_atdir(dev_t dev, ino_t ino, time_t *mtime, time_t *atime)
1011
{
1012
ATDIR *pt;
1013
ATDIR **ppt;
1014
u_int indx;
1015
1016
if (atab == NULL)
1017
return(-1);
1018
/*
1019
* hash by inode and search the chain for an inode and device match
1020
*/
1021
indx = ((unsigned)ino) % A_TAB_SZ;
1022
if ((pt = atab[indx]) == NULL)
1023
return(-1);
1024
1025
ppt = &(atab[indx]);
1026
while (pt != NULL) {
1027
if ((pt->ino == ino) && (pt->dev == dev))
1028
break;
1029
/*
1030
* no match, go to next one
1031
*/
1032
ppt = &(pt->fow);
1033
pt = pt->fow;
1034
}
1035
1036
/*
1037
* return if we did not find it.
1038
*/
1039
if (pt == NULL)
1040
return(-1);
1041
1042
/*
1043
* found it. return the times and remove the entry from the table.
1044
*/
1045
*ppt = pt->fow;
1046
*mtime = pt->mtime;
1047
*atime = pt->atime;
1048
free(pt->name);
1049
free(pt);
1050
return(0);
1051
}
1052
1053
/*
1054
* directory access mode and time storage routines (for directories CREATED
1055
* by pax).
1056
*
1057
* Pax requires that extracted directories, by default, have their access/mod
1058
* times and permissions set to the values specified in the archive. During the
1059
* actions of extracting (and creating the destination subtree during -rw copy)
1060
* directories extracted may be modified after being created. Even worse is
1061
* that these directories may have been created with file permissions which
1062
* prohibits any descendants of these directories from being extracted. When
1063
* directories are created by pax, access rights may be added to permit the
1064
* creation of files in their subtree. Every time pax creates a directory, the
1065
* times and file permissions specified by the archive are stored. After all
1066
* files have been extracted (or copied), these directories have their times
1067
* and file modes reset to the stored values. The directory info is restored in
1068
* reverse order as entries were added to the data file from root to leaf. To
1069
* restore atime properly, we must go backwards. The data file consists of
1070
* records with two parts, the file name followed by a DIRDATA trailer. The
1071
* fixed sized trailer contains the size of the name plus the off_t location in
1072
* the file. To restore we work backwards through the file reading the trailer
1073
* then the file name.
1074
*/
1075
1076
/*
1077
* dir_start()
1078
* set up the directory time and file mode storage for directories CREATED
1079
* by pax.
1080
* Return:
1081
* 0 if ok, -1 otherwise
1082
*/
1083
1084
int
1085
dir_start(void)
1086
{
1087
1088
if (dirfd != -1)
1089
return(0);
1090
1091
/*
1092
* unlink the file so it goes away at termination by itself
1093
*/
1094
memcpy(tempbase, _TFILE_BASE, sizeof(_TFILE_BASE));
1095
if ((dirfd = mkstemp(tempfile)) >= 0) {
1096
(void)unlink(tempfile);
1097
return(0);
1098
}
1099
paxwarn(1, "Unable to create temporary file for directory times: %s",
1100
tempfile);
1101
return(-1);
1102
}
1103
1104
/*
1105
* add_dir()
1106
* add the mode and times for a newly CREATED directory
1107
* name is name of the directory, psb the stat buffer with the data in it,
1108
* frc_mode is a flag that says whether to force the setting of the mode
1109
* (ignoring the user set values for preserving file mode). Frc_mode is
1110
* for the case where we created a file and found that the resulting
1111
* directory was not writeable and the user asked for file modes to NOT
1112
* be preserved. (we have to preserve what was created by default, so we
1113
* have to force the setting at the end. this is stated explicitly in the
1114
* pax spec)
1115
*/
1116
1117
void
1118
add_dir(char *name, int nlen, struct stat *psb, int frc_mode)
1119
{
1120
DIRDATA dblk;
1121
1122
if (dirfd < 0)
1123
return;
1124
1125
/*
1126
* get current position (where file name will start) so we can store it
1127
* in the trailer
1128
*/
1129
if ((dblk.npos = lseek(dirfd, 0L, SEEK_CUR)) < 0) {
1130
paxwarn(1,"Unable to store mode and times for directory: %s",name);
1131
return;
1132
}
1133
1134
/*
1135
* write the file name followed by the trailer
1136
*/
1137
dblk.nlen = nlen + 1;
1138
dblk.mode = psb->st_mode & 0xffff;
1139
dblk.mtime = psb->st_mtime;
1140
dblk.atime = psb->st_atime;
1141
dblk.frc_mode = frc_mode;
1142
if ((write(dirfd, name, dblk.nlen) == dblk.nlen) &&
1143
(write(dirfd, (char *)&dblk, sizeof(dblk)) == sizeof(dblk))) {
1144
++dircnt;
1145
return;
1146
}
1147
1148
paxwarn(1,"Unable to store mode and times for created directory: %s",name);
1149
return;
1150
}
1151
1152
/*
1153
* proc_dir()
1154
* process all file modes and times stored for directories CREATED
1155
* by pax
1156
*/
1157
1158
void
1159
proc_dir(void)
1160
{
1161
char name[PAXPATHLEN+1];
1162
DIRDATA dblk;
1163
u_long cnt;
1164
1165
if (dirfd < 0)
1166
return;
1167
/*
1168
* read backwards through the file and process each directory
1169
*/
1170
for (cnt = 0; cnt < dircnt; ++cnt) {
1171
/*
1172
* read the trailer, then the file name, if this fails
1173
* just give up.
1174
*/
1175
if (lseek(dirfd, -((off_t)sizeof(dblk)), SEEK_CUR) < 0)
1176
break;
1177
if (read(dirfd,(char *)&dblk, sizeof(dblk)) != sizeof(dblk))
1178
break;
1179
if (lseek(dirfd, dblk.npos, SEEK_SET) < 0)
1180
break;
1181
if (read(dirfd, name, dblk.nlen) != dblk.nlen)
1182
break;
1183
if (lseek(dirfd, dblk.npos, SEEK_SET) < 0)
1184
break;
1185
1186
/*
1187
* frc_mode set, make sure we set the file modes even if
1188
* the user didn't ask for it (see file_subs.c for more info)
1189
*/
1190
if (pmode || dblk.frc_mode)
1191
set_pmode(name, dblk.mode);
1192
if (patime || pmtime)
1193
set_ftime(name, dblk.mtime, dblk.atime, 0);
1194
}
1195
1196
(void)close(dirfd);
1197
dirfd = -1;
1198
if (cnt != dircnt)
1199
paxwarn(1,"Unable to set mode and times for created directories");
1200
return;
1201
}
1202
1203
/*
1204
* database independent routines
1205
*/
1206
1207
/*
1208
* st_hash()
1209
* hashes filenames to a u_int for hashing into a table. Looks at the tail
1210
* end of file, as this provides far better distribution than any other
1211
* part of the name. For performance reasons we only care about the last
1212
* MAXKEYLEN chars (should be at LEAST large enough to pick off the file
1213
* name). Was tested on 500,000 name file tree traversal from the root
1214
* and gave almost a perfectly uniform distribution of keys when used with
1215
* prime sized tables (MAXKEYLEN was 128 in test). Hashes (sizeof int)
1216
* chars at a time and pads with 0 for last addition.
1217
* Return:
1218
* the hash value of the string MOD (%) the table size.
1219
*/
1220
1221
u_int
1222
st_hash(char *name, int len, int tabsz)
1223
{
1224
char *pt;
1225
char *dest;
1226
char *end;
1227
int i;
1228
u_int key = 0;
1229
int steps;
1230
int res;
1231
u_int val;
1232
1233
/*
1234
* only look at the tail up to MAXKEYLEN, we do not need to waste
1235
* time here (remember these are pathnames, the tail is what will
1236
* spread out the keys)
1237
*/
1238
if (len > MAXKEYLEN) {
1239
pt = &(name[len - MAXKEYLEN]);
1240
len = MAXKEYLEN;
1241
} else
1242
pt = name;
1243
1244
/*
1245
* calculate the number of u_int size steps in the string and if
1246
* there is a runt to deal with
1247
*/
1248
steps = len/sizeof(u_int);
1249
res = len % sizeof(u_int);
1250
1251
/*
1252
* add up the value of the string in unsigned integer sized pieces
1253
* too bad we cannot have unsigned int aligned strings, then we
1254
* could avoid the expensive copy.
1255
*/
1256
for (i = 0; i < steps; ++i) {
1257
end = pt + sizeof(u_int);
1258
dest = (char *)&val;
1259
while (pt < end)
1260
*dest++ = *pt++;
1261
key += val;
1262
}
1263
1264
/*
1265
* add in the runt padded with zero to the right
1266
*/
1267
if (res) {
1268
val = 0;
1269
end = pt + res;
1270
dest = (char *)&val;
1271
while (pt < end)
1272
*dest++ = *pt++;
1273
key += val;
1274
}
1275
1276
/*
1277
* return the result mod the table size
1278
*/
1279
return(key % tabsz);
1280
}
1281
1282