1 /* @(#)create.c 1.162 20/07/08 Copyright 1985, 1995, 2001-2020 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)create.c 1.162 20/07/08 Copyright 1985, 1995, 2001-2020 J. Schilling";
6 #endif
7 /*
8 * Copyright (c) 1985, 1995, 2001-2020 J. Schilling
9 */
10 /*
11 * The contents of this file are subject to the terms of the
12 * Common Development and Distribution License, Version 1.0 only
13 * (the "License"). You may not use this file except in compliance
14 * with the License.
15 *
16 * See the file CDDL.Schily.txt in this distribution for details.
17 * A copy of the CDDL is also available via the Internet at
18 * http://www.opensource.org/licenses/cddl1.txt
19 *
20 * When distributing Covered Code, include this CDDL HEADER in each
21 * file and include the License file CDDL.Schily.txt from this distribution.
22 */
23
24 #include <schily/stdio.h>
25 #include "star.h"
26 #include "props.h"
27 #include "table.h"
28 #include <schily/errno.h> /* XXX seterrno() is better JS */
29 #include <schily/standard.h>
30 #include <schily/stdlib.h>
31 #include <schily/unistd.h>
32 #include <schily/dirent.h>
33 #include <schily/string.h>
34 #include <schily/jmpdefs.h> /* For __fjmalloc() */
35 #define GT_COMERR /* #define comerr gtcomerr */
36 #define GT_ERROR /* #define error gterror */
37 #include <schily/schily.h>
38 #include <schily/idcache.h>
39 #include "restore.h"
40 #ifdef USE_FIND
41 #include <schily/fcntl.h> /* For AT_FDCWD */
42 #include <schily/stat.h> /* Fuer stat_to_info() in starsubs.h */
43 #include <schily/walk.h>
44 #include <schily/find.h>
45 #endif
46 #include "starsubs.h"
47 #include "checkerr.h"
48 #include "fifo.h"
49 #include <schily/fetchdir.h>
50
51 #ifdef USE_ACL
52
53 #ifdef OWN_ACLTEXT
54 #if defined(UNIXWARE) && defined(HAVE_ACL)
55 #define HAVE_SUN_ACL
56 #define HAVE_ANY_ACL
57 #endif
58 #endif
59 /*
60 * HAVE_ANY_ACL currently includes HAVE_POSIX_ACL and HAVE_SUN_ACL.
61 * This definition must be in sync with the definition in acl_unix.c
62 * As USE_ACL is used in star.h, we are not allowed to change the
63 * value of USE_ACL before we did include star.h or we may not include
64 * star.h at all.
65 * HAVE_HP_ACL is currently not included in HAVE_ANY_ACL.
66 */
67 #ifndef HAVE_ANY_ACL
68 #undef USE_ACL /* Do not try to get or set ACLs */
69 #endif
70 #endif
71
72 struct pdirs {
73 struct pdirs *p_last;
74 dev_t p_dev;
75 ino_t p_ino;
76 };
77
78 typedef struct lname {
79 struct lname *l_lnext; /* Next in list */
80 char l_lname[1]; /* actually longer */
81 } LNAME;
82
83 typedef struct links {
84 struct links *l_next; /* Next in list */
85 struct lname *l_lnames; /* Link names for SVr4 cpio */
86 ino_t l_ino; /* Inode number (st_ino) */
87 dev_t l_dev; /* Filesys number (st_dev) */
88 Ulong l_linkno; /* Link serial number in compl. list */
89 long l_nlink; /* Link count for file */
90 short l_namlen; /* strlen(l_name) */
91 Uchar l_flags; /* Flags (see below) */
92 char l_name[1]; /* actually longer */
93 } LINKS;
94
95 #define L_ISDIR 1 /* This entry refers to a directory */
96 #define L_ISLDIR 2 /* A dir, hard linked to another dir */
97 #define L_DATA 4 /* SVr4 cpio file data encountered */
98
99 #define L_HSIZE 256 /* must be a power of two */
100
101 #define l_hash(info) (((info)->f_ino + (info)->f_dev) & (L_HSIZE-1))
102
103 LOCAL LINKS *links[L_HSIZE];
104
105 extern FILE *vpr;
106 extern FILE *listf;
107
108 extern BOOL pkglist;
109 extern BOOL multivol;
110 extern long hdrtype;
111 extern BOOL tape_isreg;
112 extern dev_t tape_dev;
113 extern ino_t tape_ino;
114 #define is_tape(info) ((info)->f_dev == tape_dev && (info)->f_ino == tape_ino)
115
116 extern long bufsize;
117 extern char *bigptr;
118
119 extern BOOL havepat;
120 extern dev_t curfs;
121 extern Ullong maxsize;
122 extern struct timespec Newer;
123 extern Ullong tsize;
124 extern BOOL prblockno;
125 extern BOOL debug;
126 extern int dumplevel;
127 extern int verbose;
128 extern BOOL silent;
129 extern BOOL readnull;
130 extern BOOL cflag;
131 extern BOOL uflag;
132 extern BOOL nodir;
133 extern BOOL acctime;
134 extern BOOL dirmode;
135 extern BOOL paxfollow;
136 extern BOOL doacl;
137 extern BOOL doxattr;
138 extern BOOL dolxattr;
139 extern BOOL nodesc;
140 extern BOOL nomount;
141 extern BOOL interactive;
142 extern BOOL nospec;
143 extern int Fflag;
144 extern BOOL abs_path;
145 extern BOOL nowarn;
146 extern BOOL match_tree;
147 extern BOOL force_hole;
148 extern BOOL sparse;
149 extern BOOL Ctime;
150 extern BOOL nodump;
151 extern BOOL nullout;
152 extern BOOL linkdata;
153 extern BOOL link_dirs;
154 extern BOOL dodump;
155 extern BOOL dometa;
156 extern BOOL dumpmeta;
157 extern BOOL lowmem;
158 extern BOOL do_subst;
159
160 #ifdef USE_FIND
161 extern BOOL dofind;
162 #endif
163
164 extern int intr;
165
166 /*
167 * Variables that control overwriting the stat() struct members
168 * controlled by the pkglist= option.
169 */
170 LOCAL BOOL statmod = FALSE;
171 LOCAL uid_t statuid = _BAD_UID;
172 LOCAL gid_t statgid = _BAD_GID;
173 LOCAL mode_t statmode = _BAD_MODE;
174
175 EXPORT void checklinks __PR((void));
176 LOCAL int take_file __PR((char *name, FINFO *info));
177 EXPORT ssize_t _fileread __PR((int *fp, void *buf, size_t len));
178 EXPORT void create __PR((char *name, BOOL Hflag, BOOL forceadd));
179 LOCAL void createi __PR((char *sname, char *name, int namlen,
180 FINFO *info, pathstore_t *pathp,
181 struct pdirs *last));
182 EXPORT void createlist __PR((struct WALK *state));
183 LOCAL BOOL get_metainfo __PR((char *line));
184 EXPORT BOOL read_symlink __PR((char *sname, char *name, FINFO *info, TCB *ptb));
185 LOCAL LINKS *find_link __PR((FINFO *info));
186 EXPORT BOOL last_cpio_link __PR((FINFO *info));
187 EXPORT BOOL xcpio_link __PR((FINFO *info));
188 LOCAL BOOL acpio_link __PR((FINFO *info));
189 EXPORT void flushlinks __PR((void));
190 LOCAL void flush_link __PR((LINKS *lp));
191 EXPORT BOOL read_link __PR((char *name, int namlen, FINFO *info,
192 TCB *ptb));
193 LOCAL ssize_t nullread __PR((void *vp, char *cp, size_t amt));
194 EXPORT void put_file __PR((int *fp, FINFO *info));
195 EXPORT void cr_file __PR((FINFO *info,
196 ssize_t (*)(void *, char *, size_t),
197 void *arg, long amt, char *text));
198 LOCAL void put_dir __PR((char *sname, char *dname, int namlen,
199 FINFO *info, TCB *ptb,
200 pathstore_t *pathp, struct pdirs *last));
201 LOCAL void toolong __PR((char *dname, char *name, size_t len));
202 LOCAL BOOL checkdirexclude __PR((char *sname, char *name, int namlen, FINFO *info));
203 LOCAL BOOL checkexclude __PR((char *sname, char *name, int namlen, FINFO *info));
204
205 #ifdef USE_FIND
206 EXPORT int walkfunc __PR((char *nm, struct stat *fs, int type, struct WALK *state));
207 LOCAL void findcreate __PR((char *name, struct WALK *state));
208 #endif
209
210 EXPORT void
checklinks()211 checklinks()
212 {
213 register LINKS *lp;
214 register int i;
215 register int used = 0;
216 register int curlen;
217 register int maxlen = 0;
218 register int nlinks = 0;
219 register int ndirs = 0;
220 register int nldirs = 0;
221
222 for (i = 0; i < L_HSIZE; i++) {
223 if (links[i] == (LINKS *)NULL)
224 continue;
225
226 curlen = 0;
227 used++;
228
229 for (lp = links[i]; lp != (LINKS *)NULL; lp = lp->l_next) {
230 curlen++;
231 nlinks++;
232 if ((lp->l_flags & L_ISDIR) != 0) {
233 ndirs++;
234 if ((lp->l_flags & L_ISLDIR) != 0)
235 nldirs++;
236 } else if (lp->l_nlink != 0) {
237 /*
238 * The fact that UNIX uses '.' and '..' as hard
239 * links to directories on all known file
240 * systems is a design bug. It makes it hard to
241 * find hard links to directories. Note that
242 * POSIX neither requires '.' and '..' to be
243 * implemented as hard links nor that these
244 * directories are physical present in the
245 * directory content.
246 * As it is hard to find all links (we would
247 * need to stat all directories as well as all
248 * '.' and '..' entries, we only warn for non
249 * directories.
250 */
251 if (cflag &&
252 !errhidden(E_MISSLINK, lp->l_name)) {
253 if (!errwarnonly(E_MISSLINK, lp->l_name))
254 xstats.s_misslinks++;
255 errmsgno(EX_BAD,
256 "Missing links to '%s'.\n",
257 lp->l_name);
258 (void) errabort(E_MISSLINK, lp->l_name,
259 TRUE);
260 }
261 }
262 }
263 if (maxlen < curlen)
264 maxlen = curlen;
265 }
266 if (debug) {
267 if (link_dirs) {
268 errmsgno(EX_BAD, "entries: %d hashents: %d/%d maxlen: %d\n",
269 nlinks, used, L_HSIZE, maxlen);
270 errmsgno(EX_BAD, "hardlinks total: %d linked dirs: %d/%d linked files: %d \n",
271 nlinks+nldirs-ndirs, nldirs, ndirs, nlinks-ndirs);
272 } else {
273 errmsgno(EX_BAD, "hardlinks: %d hashents: %d/%d maxlen: %d\n",
274 nlinks, used, L_HSIZE, maxlen);
275 }
276 }
277 }
278
279 /*
280 * Returns:
281 * TRUE take file
282 * FALSE do not take file
283 * -1 pattern did not match
284 */
285 LOCAL int
take_file(name,info)286 take_file(name, info)
287 register char *name;
288 register FINFO *info;
289 {
290 if ((info->f_flags & F_FORCE_ADD) != 0)
291 return (TRUE);
292 if (nodump && (info->f_flags & F_NODUMP) != 0)
293 return (FALSE);
294
295 if (havepat && !match(name)) {
296 return (-1);
297 /* Bei Directories ist f_size == 0 */
298 } else if (maxsize && info->f_size > maxsize) {
299 return (FALSE);
300 } else if (dumplevel > 0) {
301 /*
302 * For now, we cannot reliably deal with sub-second granularity
303 * on all platforms. For this reason, we let some files be on
304 * two incrementals to make sure not to miss them completely.
305 */
306 if (info->f_mtime >= Newer.tv_sec) {
307 /* EMPTY */
308 ;
309 } else if (info->f_ctime >= Newer.tv_sec) {
310 if (dumpmeta)
311 info->f_xftype = XT_META;
312 } else {
313 return (FALSE);
314 }
315
316 } else if (Newer.tv_sec && (Ctime ? info->f_ctime:info->f_mtime) <=
317 Newer.tv_sec) {
318 /*
319 * First the easy case: Don't take file if seconds are
320 * less than in the reference file.
321 */
322 if ((Ctime ? info->f_ctime:info->f_mtime) < Newer.tv_sec)
323 return (FALSE);
324 /*
325 * If we do not have nanoseconds, we are done.
326 */
327 if ((info->f_flags & F_NSECS) == 0)
328 return (FALSE);
329 /*
330 * Here we know that we have nanoseconds and that seconds
331 * are equal, so finally check nanoseconds.
332 */
333 if ((Ctime ? info->f_cnsec:info->f_mnsec) <= Newer.tv_nsec)
334 return (FALSE);
335 } else if (uflag && !update_newer(info)) {
336 return (FALSE);
337 } else if (!multivol &&
338 tsize > 0 && tsize < (tarblocks(info->f_size)+1+2)) {
339 if (!errhidden(E_FILETOOBIG, name)) {
340 if (!errwarnonly(E_FILETOOBIG, name))
341 xstats.s_toobig++;
342 errmsgno(EX_BAD,
343 "'%s' does not fit on tape. Not dumped.\n",
344 name);
345 (void) errabort(E_FILETOOBIG, name, TRUE);
346 }
347 return (FALSE);
348 } else if (props.pr_maxsize > 0 && info->f_size > props.pr_maxsize) {
349 if (!errhidden(E_FILETOOBIG, name)) {
350 if (!errwarnonly(E_FILETOOBIG, name))
351 xstats.s_toobig++;
352 errmsgno(EX_BAD,
353 "'%s' file too big for current mode. Not dumped.\n",
354 name);
355 (void) errabort(E_FILETOOBIG, name, TRUE);
356 }
357 return (FALSE);
358 } else if (pr_unsuptype(info)) {
359 if (!errhidden(E_SPECIALFILE, name)) {
360 if (!errwarnonly(E_SPECIALFILE, name))
361 xstats.s_isspecial++;
362 errmsgno(EX_BAD,
363 "'%s' unsupported file type '%s'. Not dumped.\n",
364 name, XTTONAME(info->f_xftype));
365 (void) errabort(E_SPECIALFILE, name, TRUE);
366 }
367 return (FALSE);
368 } else if (is_special(info) && nospec) {
369 if (!errhidden(E_SPECIALFILE, name)) {
370 if (!errwarnonly(E_SPECIALFILE, name))
371 xstats.s_isspecial++;
372 errmsgno(EX_BAD,
373 "'%s' is not a file. Not dumped.\n", name);
374 (void) errabort(E_SPECIALFILE, name, TRUE);
375 }
376 return (FALSE);
377 } else if (tape_isreg && is_tape(info)) {
378 errmsgno(EX_BAD, "'%s' is the archive. Not dumped.\n", name);
379 return (FALSE);
380 }
381 if (is_file(info) && dometa) {
382 /*
383 * This is the right place for this code although it does not
384 * look correct. Later in star-1.5 we decide here, based on
385 * mtime and ctime of the file, whether we archive a file at
386 * all and whether we only add the file's metadata.
387 */
388 info->f_xftype = XT_META;
389 if (pr_unsuptype(info)) {
390 if (!errhidden(E_SPECIALFILE, name)) {
391 if (!errwarnonly(E_SPECIALFILE, name))
392 xstats.s_isspecial++;
393 errmsgno(EX_BAD,
394 "'%s' unsupported file type '%s'. Not dumped.\n",
395 name, XTTONAME(info->f_xftype));
396 (void) errabort(E_SPECIALFILE, name, TRUE);
397 }
398 return (FALSE);
399 }
400 }
401 #ifdef USE_ACL
402 /*
403 * If we return (FALSE) here, the file would not be archived at all.
404 * This is not what we want, so ignore return code from get_acls().
405 */
406 if (doacl)
407 (void) get_acls(info);
408 #endif /* USE_ACL */
409 #ifdef USE_XATTR
410 if (dolxattr)
411 (void) get_xattr(info);
412 #endif
413 return (TRUE);
414 }
415
416 ssize_t
_fileread(fp,buf,len)417 _fileread(fp, buf, len)
418 register int *fp;
419 void *buf;
420 size_t len;
421 {
422 register int fd = *fp;
423 register ssize_t ret;
424 int errcnt = 0;
425
426 retry:
427 while ((ret = read(fd, buf, len)) < 0 && geterrno() == EINTR)
428 /* LINTED */
429 ;
430 if (ret < 0 && geterrno() == EINVAL && ++errcnt < 100) {
431 off_t oo;
432 off_t si;
433
434 /*
435 * Work around the problem that we cannot read()
436 * if the buffer crosses 2 GB in non large file mode.
437 */
438 oo = lseek(fd, (off_t)0, SEEK_CUR);
439 if (oo == (off_t)-1)
440 return (ret);
441 si = lseek(fd, (off_t)0, SEEK_END);
442 if (si == (off_t)-1)
443 return (ret);
444 if (lseek(fd, oo, SEEK_SET) == (off_t)-1)
445 return (ret);
446 if (oo >= si) { /* EOF */
447 ret = 0;
448 } else if ((si - oo) <= len) {
449 len = si - oo;
450 goto retry;
451 }
452 }
453 return (ret);
454 }
455
456 EXPORT void
create(name,Hflag,forceadd)457 create(name, Hflag, forceadd)
458 register char *name;
459 BOOL Hflag;
460 BOOL forceadd;
461 {
462 FINFO finfo;
463 register FINFO *info = &finfo;
464 BOOL opaxfollow = paxfollow; /* paxfollow supersedes follow */
465
466 if (name[0] == '.' && name[1] == '/') {
467 for (name++; name[0] == '/'; name++)
468 /* LINTED */
469 ;
470 }
471 if (name[0] == '\0')
472 name = ".";
473 if (Hflag)
474 paxfollow = Hflag;
475 if (!getinfo(name, info)) {
476 paxfollow = opaxfollow;
477 if (!errhidden(E_STAT, name)) {
478 if (!errwarnonly(E_STAT, name))
479 xstats.s_staterrs++;
480 errmsg("Cannot stat '%s'.\n", name);
481 (void) errabort(E_STAT, name, TRUE);
482 }
483 return;
484 }
485 if (forceadd)
486 info->f_flags |= F_FORCE_ADD;
487 paxfollow = opaxfollow;
488 createi(name, name, strlen(name), info,
489 (pathstore_t *)0, (struct pdirs *)0);
490 }
491
492 LOCAL void
createi(sname,name,namlen,info,pathp,last)493 createi(sname, name, namlen, info, pathp, last)
494 char *sname;
495 register char *name;
496 int namlen;
497 register FINFO *info;
498 pathstore_t *pathp;
499 struct pdirs *last;
500 {
501 char lname[PATH_MAX+1]; /* This limit cannot be overruled */
502 TCB tb;
503 register TCB *ptb = &tb;
504 int fd = -1;
505 BOOL was_link = FALSE;
506 BOOL do_sparse = FALSE;
507
508 if (hash_xlookup(name))
509 return;
510
511 info->f_sname = sname;
512 info->f_name = name; /* XXX Das ist auch in getinfo !!!?!!! */
513 info->f_namelen = namlen;
514 if (Fflag > 0 && !checkexclude(sname, name, namlen, info))
515 return;
516
517 #ifdef nonono_NICHT_BEI_CREATE /* XXX */
518 if (!abs_path && /* XXX VVV siehe skip_slash() */
519 (info->f_name[0] == '/' /* || info->f_lname[0] == '/' */)) {
520 skip_slash(info);
521 info->f_namelen -= info->f_name - name;
522 if (info->f_namelen == 0) {
523 info->f_name = "./";
524 info->f_namelen = 2;
525 }
526 /* XXX das gleiche mit f_lname !!!!! */
527 }
528 #endif /* nonono_NICHT_BEI_CREATE XXX */
529 info->f_lname = lname; /* XXX nur �bergangsweise!!!!! */
530 info->f_lnamelen = 0;
531
532 if (prblockno)
533 (void) tblocks(); /* set curblockno */
534
535 if (do_subst && subst(info)) {
536 if (info->f_name[0] == '\0') {
537 if (verbose)
538 fgtprintf(vpr,
539 "'%s' substitutes to null string, skipping ...\n",
540 name);
541 return;
542 }
543 }
544
545 if (statmod) {
546 if (statmode != _BAD_MODE)
547 info->f_mode = statmode;
548 if (statuid != _BAD_UID)
549 info->f_uid = statuid;
550 if (statgid != _BAD_GID)
551 info->f_gid = statgid;
552 }
553
554 if (verbose <= 1 &&
555 !(dirmode && is_dir(info)) &&
556 (info->f_namelen <= props.pr_maxsname)) {
557 /*
558 * Allocate TCB from the buffer to avoid copying TCB
559 * in the most frequent case.
560 * If we are writing directories after the files they
561 * contain, we cannot allocate the space for tcb
562 * from the buffer.
563 * With very long names we will have to write out
564 * other data before we can write the TCB, so we cannot
565 * alloc tcb from buffer too.
566 * If we are creating a long listing while archiving, the
567 * TCB will be overwritten by info_to_xhdr() and this would
568 * overwrite username/groupname that is later needed for
569 * vprint(), so we cannot allocate TCB from the buffer here.
570 */
571 if ((ptb = (TCB *)get_block(props.pr_hdrsize)) == NULL)
572 ptb = &tb;
573 else
574 info->f_flags |= F_TCB_BUF;
575 }
576 info->f_tcb = ptb;
577 if ((props.pr_flags & PR_CPIO) == 0)
578 filltcb(ptb);
579 if (!name_to_tcb(info, ptb)) /* Name too long */
580 return;
581
582 #ifndef __PRE_CPIO__
583 if (is_symlink(info) && !read_symlink(sname, name, info, ptb)) {
584 return;
585 }
586 #endif
587 info_to_tcb(info, ptb);
588 if (is_dir(info)) {
589 /*
590 * If we have been requested to check for hard linked
591 * directories, first look for possible hard links.
592 */
593 if (link_dirs && /* info->f_nlink > 1 && */ read_link(name, namlen, info, ptb))
594 was_link = TRUE;
595
596 if (was_link && !is_link(info)) /* link name too long */
597 return;
598
599 if (was_link && take_file(name, info) > 0) {
600 put_tcb(ptb, info);
601 vprint(info);
602 } else {
603 put_dir(sname, name, namlen, info, ptb, pathp, last);
604 }
605 } else if (take_file(name, info) <= 0) { /* < TRUE */
606 return;
607 } else if (interactive && !ia_change(ptb, info)) {
608 fgtprintf(vpr, "Skipping ...\n");
609 #ifdef __PRE_CPIO__
610 } else if (is_symlink(info) && !read_symlink(sname, name, info, ptb)) {
611 /* EMPTY */
612 ;
613 #endif
614 } else if (is_meta(info)) {
615 /*
616 * XXX Currently only TAR supports meta files.
617 * XXX If we ever change this, we may need to remove the
618 * XXX ptb->dbuf references here.
619 */
620 if (info->f_nlink > 1 && read_link(name, namlen, info, ptb))
621 was_link = TRUE;
622
623 if (was_link && !is_link(info)) /* link name too long */
624 return;
625
626 if (!was_link) {
627 /*
628 * XXX We definitely do not want that other tar
629 * XXX implementations are able to read tar archives
630 * XXX that contain meta files.
631 * XXX If a tar implementation that does not understand
632 * XXX meta files extracts archives with meta files,
633 * XXX it will most likely destroy old files on disk.
634 */
635 ptb->dbuf.t_linkflag = LF_META;
636 info->f_flags &= ~F_SPLIT_NAME;
637 if (ptb->dbuf.t_prefix[0] != '\0')
638 fillbytes(ptb->dbuf.t_prefix, props.pr_maxprefix, '\0');
639 if (props.pr_flags & PR_XHDR)
640 info->f_xflags |= XF_PATH;
641 else
642 info->f_flags |= F_LONGNAME;
643 ptb->dbuf.t_name[0] = 0; /* Hide P-1988 name */
644 info_to_tcb(info, ptb);
645 }
646 put_tcb(ptb, info);
647 vprint(info);
648 return;
649
650 } else if (is_file(info) && info->f_size != 0 && !nullout &&
651 (fd = _lfileopen(sname, "rb")) < 0) {
652 if (!errhidden(E_OPEN, name)) {
653 if (!errwarnonly(E_OPEN, name))
654 xstats.s_openerrs++;
655 errmsg("Cannot open '%s'.\n", name);
656 (void) errabort(E_OPEN, name, TRUE);
657 }
658 } else {
659 if (info->f_nlink > 1 && read_link(name, namlen, info, ptb) &&
660 !linkdata) {
661 was_link = TRUE;
662 }
663 if (was_link && !is_link(info)) { /* link name too long */
664 if (fd >= 0)
665 close(fd);
666 return;
667 }
668 /*
669 * Special treatment for the idiosyncratic way of dealing with
670 * hard links in the SVr4 CRC cpio archive format.
671 * The link count is handled by calling read_link() in
672 * cpiotcb_to_info() before.
673 */
674 if ((props.pr_flags & PR_SV_CPIO_LINKS) != 0 &&
675 info->f_nlink > 1) {
676 if (!last_cpio_link(info)) { /* Ign. all but last */
677 if (fd >= 0)
678 close(fd);
679 return;
680 }
681 if (acpio_link(info)) { /* Now extract all */
682 put_file(&fd, info);
683 goto out;
684 }
685 /*
686 * If the link count is increasing, do it the same way
687 * as SVr4 cpio and archive the rest as plain files.
688 */
689 if (is_file(info))
690 info->f_rsize = info->f_size;
691 info->f_xftype = info->f_rxftype;
692 }
693
694 if (!is_file(info) || was_link || info->f_rsize == 0) {
695 /*
696 * Don't dump the content of hardlinks and empty files.
697 * Hardlinks currently have f_rsize == 0 !
698 */
699 put_tcb(ptb, info);
700 vprint(info);
701 if (fd >= 0)
702 close(fd);
703 return;
704 }
705
706 /*
707 * In case we like to do sparse file handling via SEEK_HOLE we need
708 * an open fd in order to check for a sparse file.
709 */
710 do_sparse = sparse && (props.pr_flags & PR_SPARSE);
711 if (do_sparse && nullout &&
712 (fd = _lfileopen(sname, "rb")) < 0) {
713 if (!errhidden(E_OPEN, name)) {
714 if (!errwarnonly(E_OPEN, name))
715 xstats.s_openerrs++;
716 errmsg("Cannot open '%s'.\n", name);
717 (void) errabort(E_OPEN, name, TRUE);
718 }
719 return;
720 }
721
722 if (do_sparse && sparse_file(&fd, info)) {
723 if (!silent)
724 error("'%s' is sparse\n", info->f_name);
725 put_sparse(&fd, info);
726 } else if (do_sparse && force_hole) {
727 /*
728 * Treat all files as sparse when -force-hole
729 * option is given. Files that do not contain
730 * any zeroed region will however still be
731 * archived as plain files by put_sparse().
732 */
733 put_sparse(&fd, info);
734 } else {
735 put_tcb(ptb, info);
736 vprint(info);
737 put_file(&fd, info);
738 }
739 /*
740 * Reset access time of file.
741 * This is important when using star for dumps.
742 * N.B. this has been done after fclose()
743 * before _FIOSATIME has been used.
744 *
745 * If f == NULL, the file has not been accessed for read
746 * and access time need not be reset.
747 */
748 out:
749 if (acctime && fd >= 0)
750 rs_acctime(fd, info);
751 if (fd >= 0)
752 close(fd);
753 }
754 }
755
756 EXPORT void
createlist(state)757 createlist(state)
758 struct WALK *state;
759 {
760 register int nlen;
761 char *name;
762 size_t nsize = PATH_MAX;
763
764 /*
765 * We need at least PATH_MAX+1 and add 512 to get better messages below
766 */
767 name = ___malloc(nsize, "name buffer");
768
769 for (nlen = 1; nlen >= 0; ) {
770 if ((nlen = getdelim(&name, &nsize,
771 readnull ? '\0' : '\n', listf)) < 0)
772 break;
773
774 if (nlen == 0)
775 continue;
776 if (!readnull) {
777 if (name[nlen-1] == '\n')
778 name[--nlen] = '\0';
779 if (nlen == 0)
780 continue;
781 }
782 if (pkglist) {
783 if (!get_metainfo(name))
784 continue;
785 nlen = strlen(name);
786 }
787 if (intr)
788 break;
789 curfs = NODEV;
790 #ifdef USE_FIND
791 if (dofind) {
792 findcreate(name, state);
793 } else
794 #endif
795 create(name, FALSE, FALSE); /* XXX Liste doch wie Kommandozeile? */
796 }
797 free(name);
798 }
799
800 LOCAL BOOL
get_metainfo(line)801 get_metainfo(line)
802 char *line;
803 {
804 char *p;
805 char *p2;
806 uid_t uid;
807 gid_t gid;
808 long lid;
809
810 p = strchr(line, ' ');
811 if (p == NULL) {
812 statmod = FALSE;
813 return (TRUE);
814 }
815
816 *p++ = '\0';
817 statmod = TRUE;
818 statmode = _BAD_MODE;
819 statuid = _BAD_UID;
820 statgid = _BAD_GID;
821 if (*p == '?') {
822 p2 = ++p;
823 } else {
824 p2 = astolb(p, &lid, 8);
825 if (*p2 == ' ')
826 statmode = lid;
827 }
828 if (*p2 == ' ') {
829 p = ++p2;
830 } else {
831 errmsgno(EX_BAD, "%s: illegal mode\n", line);
832 return (FALSE);
833 }
834 p2 = strchr(p, ' ');
835 if (p2 != NULL) {
836 *p2++ = '\0';
837 } else {
838 errmsgno(EX_BAD, "%s: illegal uid\n", line);
839 return (FALSE);
840 }
841 if (!streql(p, "?") && ic_uidname(p, strlen(p), &uid))
842 statuid = uid;
843 p = p2;
844 if (!streql(p, "?") && ic_gidname(p, strlen(p), &gid))
845 statgid = gid;
846
847 return (TRUE);
848 }
849
850 EXPORT BOOL
read_symlink(sname,name,info,ptb)851 read_symlink(sname, name, info, ptb)
852 char *sname;
853 char *name;
854 register FINFO *info;
855 TCB *ptb;
856 {
857 int len;
858
859 info->f_lname[0] = '\0';
860
861 #ifdef HAVE_READLINK
862 if ((len = lreadlink(sname, info->f_lname, PATH_MAX)) < 0) {
863 if (!errhidden(E_READLINK, name)) {
864 if (!errwarnonly(E_READLINK, name))
865 xstats.s_rwerrs++;
866 errmsg("Cannot read link '%s'.\n", name);
867 (void) errabort(E_READLINK, name, TRUE);
868 }
869 return (FALSE);
870 }
871 info->f_lnamelen = len;
872 /*
873 * string from readlink is not null terminated
874 */
875 info->f_lname[len] = '\0';
876
877 if (len > props.pr_maxlnamelen) {
878 if (!errhidden(E_NAMETOOLONG, name)) {
879 if (!errwarnonly(E_NAMETOOLONG, name))
880 xstats.s_toolong++;
881 errmsgno(EX_BAD,
882 "%s: Symbolic link too long.\n", name);
883 (void) errabort(E_NAMETOOLONG, name, TRUE);
884 }
885 return (FALSE);
886 }
887 if ((props.pr_flags & PR_CPIO) != 0)
888 return (TRUE);
889
890 if (len > props.pr_maxslname) {
891 if (props.pr_flags & PR_XHDR)
892 info->f_xflags |= XF_LINKPATH;
893 else
894 info->f_flags |= F_LONGLINK;
895 }
896 /*
897 * if linkname is not longer than props.pr_maxslname
898 * that's all to do with linkname
899 */
900 strncpy(ptb->dbuf.t_linkname, info->f_lname, props.pr_maxslname);
901 return (TRUE);
902 #else
903 if (!errhidden(E_SPECIALFILE, name)) {
904 if (!errwarnonly(E_SPECIALFILE, name))
905 xstats.s_isspecial++;
906 errmsgno(EX_BAD,
907 "'%s' unsupported file type '%s'. Not dumped.\n",
908 name, XTTONAME(info->f_xftype));
909 (void) errabort(E_SPECIALFILE, name, TRUE);
910 }
911 return (FALSE);
912 #endif
913 }
914
915 LOCAL LINKS *
find_link(info)916 find_link(info)
917 register FINFO *info;
918 {
919 register LINKS *lp;
920
921 lp = links[l_hash(info)];
922
923 for (; lp != (LINKS *)NULL; lp = lp->l_next) {
924 if (lp->l_ino == info->f_ino && lp->l_dev == info->f_dev)
925 return (lp);
926 }
927 return ((LINKS *)NULL);
928 }
929
930 /*
931 * Return TRUE in case we found the last entry (the one that may have data)
932 * for a specific file.
933 */
934 EXPORT BOOL
last_cpio_link(info)935 last_cpio_link(info)
936 register FINFO *info;
937 {
938 register LINKS *lp;
939
940 if ((lp = find_link(info)) != NULL) {
941 if ((!cflag && info->f_size > 0) ||
942 lp->l_nlink <= 0 ||
943 (lp->l_flags & L_DATA) != 0)
944 return (TRUE);
945 return (FALSE);
946 }
947 return (TRUE);
948 }
949
950 /*
951 * Extract all cpio CRC links.
952 * XXX This should be in extract.c
953 */
954 EXPORT BOOL
xcpio_link(info)955 xcpio_link(info)
956 register FINFO *info;
957 {
958 register LINKS *lp;
959 char *name = info->f_name;
960 char *lname = info->f_lname;
961 off_t rsize = info->f_rsize;
962 int xftype = info->f_xftype;
963
964 if ((lp = find_link(info)) != NULL) {
965 /*
966 * We come here if the link count increases and we need to
967 * archive more "files" as expected.
968 */
969 if ((lp->l_flags & L_DATA) != 0)
970 return (FALSE);
971 }
972 info->f_xftype = info->f_rxftype;
973 extracti(info, NULL); /* Extract as real node */
974 info->f_xftype = xftype;
975 info->f_rsize = 0;
976
977 if (lp != NULL) {
978 register LNAME *ln;
979
980 lp->l_flags |= L_DATA;
981 info->f_lname = name;
982 info->f_name = lp->l_name;
983 extracti(info, NULL); /* Extract link info->f_lname */
984
985 for (ln = lp->l_lnames; ln; ln = ln->l_lnext) {
986 if (streql(name, ln->l_lname))
987 continue;
988 info->f_name = ln->l_lname;
989 extracti(info, NULL); /* Extract all other links */
990 }
991 }
992 info->f_name = name;
993 info->f_lname = lname;
994 info->f_rsize = rsize;
995 return (TRUE);
996 }
997
998 /*
999 * Archive all cpio CRC links.
1000 *
1001 * We are called if our caller believes that the last link for a specific file
1002 * has been encountered.
1003 */
1004 LOCAL BOOL
acpio_link(info)1005 acpio_link(info)
1006 register FINFO *info;
1007 {
1008 TCB tb;
1009 register TCB *ptb = info->f_tcb;
1010 register LINKS *lp;
1011 int namelen = info->f_namelen;
1012 char *name = info->f_name;
1013 char *lname = info->f_lname;
1014 off_t size = info->f_size; /* real size of file */
1015 #ifdef __wrong_but_what_people_would_expect__
1016 off_t rsize = info->f_rsize; /* size as archived on tape */
1017 #endif
1018
1019 if ((lp = find_link(info)) != NULL) {
1020 /*
1021 * We come here if the link count increases and we need to
1022 * archive more "files" than expected.
1023 */
1024 if ((lp->l_flags & L_DATA) != 0)
1025 return (FALSE);
1026 }
1027
1028 info->f_size = 0;
1029 info->f_rsize = 0;
1030
1031 if (lp != NULL) {
1032 register LNAME *ln;
1033
1034 lp->l_flags |= L_DATA;
1035 info->f_lname = name;
1036 info->f_namelen = strlen(lp->l_name);
1037 info->f_name = lp->l_name;
1038 info_to_tcb(info, ptb);
1039 put_tcb(ptb, info);
1040 vprint(info);
1041
1042 for (ln = lp->l_lnames; ln; ln = ln->l_lnext) {
1043 if (streql(name, ln->l_lname))
1044 continue;
1045 info->f_namelen = strlen(ln->l_lname);
1046 info->f_name = ln->l_lname;
1047 info->f_flags &= ~F_TCB_BUF;
1048 if ((ptb = (TCB *)get_block(props.pr_hdrsize)) == NULL)
1049 ptb = &tb;
1050 else
1051 info->f_flags |= F_TCB_BUF;
1052 info->f_tcb = ptb;
1053 info_to_tcb(info, ptb);
1054 put_tcb(ptb, info);
1055 vprint(info);
1056 }
1057 }
1058 info->f_namelen = namelen;
1059 info->f_name = name;
1060 info->f_lname = lname;
1061 info->f_size = size;
1062 #ifdef __wrong_but_what_people_would_expect__
1063 info->f_rsize = rsize;
1064 #else
1065 info->f_rsize = size; /* Achieve that the last link archives data */
1066 #endif
1067 info->f_xftype = info->f_rxftype;
1068
1069 info->f_flags &= ~F_TCB_BUF;
1070 if ((ptb = (TCB *)get_block(props.pr_hdrsize)) == NULL)
1071 ptb = &tb;
1072 else
1073 info->f_flags |= F_TCB_BUF;
1074 info->f_tcb = ptb;
1075 info_to_tcb(info, ptb);
1076 put_tcb(ptb, info);
1077 vprint(info);
1078 return (TRUE);
1079 }
1080
1081 /*
1082 * Flush all SVr4 cpio -Hcrc links that have not yet been archived.
1083 */
1084 EXPORT void
flushlinks()1085 flushlinks()
1086 {
1087 register LINKS *lp;
1088 register int i;
1089
1090 if ((props.pr_flags & PR_SV_CPIO_LINKS) == 0)
1091 return;
1092
1093 for (i = 0; i < L_HSIZE; i++) {
1094 if (links[i] == (LINKS *)NULL)
1095 continue;
1096
1097 for (lp = links[i]; lp != (LINKS *)NULL; lp = lp->l_next) {
1098 if ((lp->l_flags & (L_ISDIR|L_DATA)) == 0 &&
1099 (lp->l_nlink > 0))
1100 flush_link(lp);
1101 }
1102 }
1103 }
1104
1105 /*
1106 * Flush a single cpio -Hcrc link.
1107 */
1108 LOCAL void
flush_link(lp)1109 flush_link(lp)
1110 register LINKS *lp;
1111 {
1112 TCB tb;
1113 TCB *ptb;
1114 FINFO finfo;
1115 register LNAME *ln;
1116 int fd = 1;
1117 BOOL did_stat;
1118 char *name;
1119
1120 finfo.f_flags = 0;
1121 finfo.f_flags &= ~F_TCB_BUF;
1122 if ((ptb = (TCB *)get_block(props.pr_hdrsize)) == NULL)
1123 ptb = &tb;
1124 else
1125 finfo.f_flags |= F_TCB_BUF;
1126 did_stat = getinfo(lp->l_name, &finfo);
1127 name = lp->l_name;
1128 for (ln = lp->l_lnames; ln; ln = ln->l_lnext) {
1129 if (!did_stat) {
1130 did_stat = getinfo(ln->l_lname, &finfo);
1131 if (did_stat)
1132 name = ln->l_lname;
1133 }
1134 fd++;
1135 }
1136 if (!did_stat) {
1137 if (!errhidden(E_STAT, lp->l_name)) {
1138 if (!errwarnonly(E_STAT, lp->l_name))
1139 xstats.s_staterrs++;
1140 errmsg("Cannot stat '%s'.\n", lp->l_name);
1141 (void) errabort(E_STAT, lp->l_name, TRUE);
1142 }
1143 return;
1144 }
1145 finfo.f_name = lp->l_name;
1146 finfo.f_namelen = strlen(lp->l_name);
1147 finfo.f_lname = ""; /* XXX nur �bergangsweise!!!!! */
1148 finfo.f_lnamelen = 0;
1149
1150 finfo.f_nlink = fd;
1151 finfo.f_xftype = XT_LINK;
1152 finfo.f_tcb = ptb;
1153 fd = -1;
1154 if (is_file(&finfo) && finfo.f_size != 0 && !nullout &&
1155 (fd = _lfileopen(name, "rb")) < 0) {
1156 if (!errhidden(E_OPEN, name)) {
1157 if (!errwarnonly(E_OPEN, name))
1158 xstats.s_openerrs++;
1159 errmsg("Cannot open '%s'.\n", name);
1160 (void) errabort(E_OPEN, name, TRUE);
1161 }
1162 return;
1163 }
1164 if (acpio_link(&finfo))
1165 put_file(&fd, &finfo);
1166
1167 if (acctime && fd >= 0)
1168 rs_acctime(fd, &finfo);
1169 if (fd >= 0)
1170 close(fd);
1171 }
1172
1173 /*
1174 * Cheating with st_dev & st_ino for CPIO:
1175 * Do not use inode number 0 and start st_dev from an
1176 * obscure value...
1177 */
1178 #define dev_from_linkno(n) (0x5555 + ((n) / 0xFFFF))
1179 #define ino_from_linkno(n) (1 + ((n) % 0xFFFF))
1180
1181 EXPORT BOOL
read_link(name,namlen,info,ptb)1182 read_link(name, namlen, info, ptb)
1183 char *name;
1184 int namlen;
1185 register FINFO *info;
1186 TCB *ptb;
1187 {
1188 register LINKS *lp;
1189 static Ulong linkno = 0;
1190
1191 if ((lp = find_link(info)) != NULL) {
1192 if (lp->l_namlen > props.pr_maxlnamelen) {
1193 if (!errhidden(E_NAMETOOLONG, lp->l_name)) {
1194 if (!errwarnonly(E_NAMETOOLONG, lp->l_name))
1195 xstats.s_toolong++;
1196 errmsgno(EX_BAD,
1197 "%s: Link name too long.\n",
1198 lp->l_name);
1199 (void) errabort(E_NAMETOOLONG, lp->l_name,
1200 TRUE);
1201 }
1202 return (TRUE);
1203 }
1204 if (lp->l_namlen > props.pr_maxslname) {
1205 if (props.pr_flags & PR_XHDR)
1206 info->f_xflags |= XF_LINKPATH;
1207 else
1208 info->f_flags |= F_LONGLINK;
1209 }
1210 if (--lp->l_nlink < 0) {
1211 if (!nowarn && (info->f_flags & F_EXTRACT) == 0)
1212 errmsgno(EX_BAD,
1213 "%s: Linkcount below zero (%ld)\n",
1214 lp->l_name, lp->l_nlink);
1215 }
1216 /*
1217 * We found a hard link to a directory that is already
1218 * known in the link cache. Mark it for later
1219 * statistical analysis.
1220 */
1221 if (lp->l_flags & L_ISDIR)
1222 lp->l_flags |= L_ISLDIR;
1223 /*
1224 * if linkname is not longer than props.pr_maxslname
1225 * that's all to do with linkname
1226 */
1227 if ((props.pr_flags & PR_CPIO) == 0) {
1228 strncpy(ptb->dbuf.t_linkname, lp->l_name,
1229 props.pr_maxslname);
1230 }
1231 info->f_lname = lp->l_name;
1232 info->f_lnamelen = lp->l_namlen;
1233 info->f_xftype = XT_LINK;
1234
1235 /*
1236 * With POSIX-1988, f_rsize is 0 for hardlinks
1237 *
1238 * XXX Should we add a property for old tar
1239 * XXX compatibility to keep the size field as before?
1240 */
1241 if (!linkdata)
1242 info->f_rsize = (off_t)0;
1243 /*
1244 * XXX This is the wrong place but the TCB has already
1245 * XXX been set up (including size field) before.
1246 * XXX We only call info_to_tcb() to change size to 0.
1247 * XXX There should be a better way to deal with TCB.
1248 */
1249 if ((info->f_flags & F_EXTRACT) == 0) {
1250 /*
1251 * XXX Nicht bei extrakt
1252 */
1253 info->f_dev = dev_from_linkno(lp->l_linkno);
1254 info->f_ino = ino_from_linkno(lp->l_linkno);
1255 info_to_tcb(info, ptb);
1256 info->f_dev = lp->l_dev;
1257 info->f_ino = lp->l_ino;
1258 }
1259 /*
1260 * XXX Dies ist eine ungewollte Referenz auf den
1261 * XXX TAR Control Block, aber hier ist der TCB
1262 * XXX schon fertig und wir wollen nur den Typ
1263 * XXX Modifizieren.
1264 */
1265 if ((props.pr_flags & PR_CPIO) == 0)
1266 ptb->dbuf.t_linkflag = LNKTYPE;
1267 if ((props.pr_flags & PR_SV_CPIO_LINKS) != 0) {
1268 register LNAME *ln;
1269
1270 ln = (LNAME *)malloc(sizeof (*ln)+namlen);
1271 if (ln == NULL) {
1272 errmsg(
1273 "Cannot alloc new link name for '%s'.\n",
1274 name);
1275 } else {
1276 strlcpy(ln->l_lname, name, namlen+1);
1277 ln->l_lnext = lp->l_lnames;
1278 lp->l_lnames = ln;
1279 }
1280 }
1281 return (TRUE);
1282 }
1283 if ((lp = (LINKS *)malloc(sizeof (*lp)+namlen)) == (LINKS *)NULL) {
1284 errmsg("Cannot alloc new link for '%s'.\n", name);
1285 } else {
1286 register LINKS **lpp = &links[l_hash(info)];
1287
1288 lp->l_next = *lpp;
1289 *lpp = lp;
1290 lp->l_lnames = NULL;
1291 lp->l_linkno = linkno++;
1292 lp->l_ino = info->f_ino;
1293 lp->l_dev = info->f_dev;
1294 lp->l_nlink = info->f_nlink - 1;
1295 lp->l_namlen = namlen;
1296 if (is_dir(info))
1297 lp->l_flags = L_ISDIR;
1298 else
1299 lp->l_flags = 0;
1300 strlcpy(lp->l_name, name, namlen+1);
1301
1302 if ((info->f_flags & F_EXTRACT) == 0) {
1303 /*
1304 * XXX Nicht bei extrakt
1305 */
1306 info->f_dev = dev_from_linkno(lp->l_linkno);
1307 info->f_ino = ino_from_linkno(lp->l_linkno);
1308 info_to_tcb(info, ptb);
1309 info->f_dev = lp->l_dev;
1310 info->f_ino = lp->l_ino;
1311 }
1312 }
1313 return (FALSE);
1314 }
1315
1316 /* ARGSUSED */
1317 LOCAL ssize_t
nullread(vp,cp,amt)1318 nullread(vp, cp, amt)
1319 void *vp;
1320 char *cp;
1321 size_t amt;
1322 {
1323 return (amt);
1324 }
1325
1326 EXPORT void
put_file(fp,info)1327 put_file(fp, info)
1328 register int *fp;
1329 register FINFO *info;
1330 {
1331 if (nullout) {
1332 cr_file(info, (ssize_t(*)__PR((void *, char *, size_t)))nullread,
1333 fp, 0, "reading");
1334 } else {
1335 cr_file(info, (ssize_t(*)__PR((void *, char *, size_t)))_fileread,
1336 fp, 0, "reading");
1337 }
1338 }
1339
1340 EXPORT void
cr_file(info,func,arg,amt,text)1341 cr_file(info, func, arg, amt, text)
1342 FINFO *info;
1343 ssize_t (*func) __PR((void *, char *, size_t));
1344 register void *arg;
1345 long amt;
1346 char *text;
1347 {
1348 register long amount;
1349 register off_t blocks;
1350 register off_t size;
1351 register int i = 0;
1352 register off_t n;
1353 extern m_stats *stats;
1354
1355 size = info->f_rsize;
1356
1357 fifo_enter_critical();
1358 stats->cur_size = size;
1359 stats->cur_off = 0;
1360 fifo_leave_critical();
1361
1362 if ((blocks = tarblocks(info->f_rsize)) == 0)
1363 return;
1364 if (amt == 0)
1365 amt = bufsize;
1366 do {
1367 amount = buf_wait(TBLOCK);
1368 amount = min(amount, amt);
1369
1370 if ((props.pr_flags & PR_CPIO) == 0) {
1371 if ((i = (*func)(arg, bigptr, max(amount, TBLOCK))) <= 0)
1372 break;
1373 } else {
1374 if ((i = (*func)(arg, bigptr, amount)) <= 0)
1375 break;
1376 }
1377
1378 size -= i;
1379 fifo_enter_critical();
1380 stats->cur_off += i;
1381 fifo_leave_critical();
1382
1383 if (size < 0) { /* File increased in size */
1384 n = tarblocks(size+i); /* use expected size only */
1385 } else {
1386 n = tarblocks(i);
1387 }
1388 if ((props.pr_flags & PR_CPIO) == 0) {
1389
1390 if (i % TBLOCK) { /* Clear (better compression) */
1391 fillbytes(bigptr+i, TBLOCK - (i%TBLOCK), '\0');
1392 }
1393 buf_wake(n*TBLOCK);
1394 } else {
1395 if (size < 0) /* File increased in size */
1396 buf_wake(size+i); /* use expected size only */
1397 else
1398 buf_wake(i);
1399 n = blocks;
1400 }
1401 } while ((blocks -= n) >= 0 && i > 0 && size >= 0);
1402 if (i < 0) {
1403 if (!errhidden(E_READ, info->f_name)) {
1404 if (!errwarnonly(E_READ, info->f_name))
1405 xstats.s_rwerrs++;
1406 errmsg("Error %s '%s'.\n", text, info->f_name);
1407 (void) errabort(E_READ, info->f_name, TRUE);
1408 }
1409 } else if ((blocks != 0 || size != 0) && func != nullread) {
1410 if (!errhidden(size < 0 ? E_GROW:E_SHRINK, info->f_name)) {
1411 if (!errwarnonly(size < 0 ? E_GROW:E_SHRINK, info->f_name))
1412 xstats.s_sizeerrs++;
1413 errmsgno(EX_BAD,
1414 "'%s': file changed size (%s).\n",
1415 info->f_name, size < 0 ? "increased":"shrunk");
1416 (void) errabort(size < 0 ? E_GROW:E_SHRINK,
1417 info->f_name, TRUE);
1418 }
1419 }
1420 /*
1421 * If the file did shrink, fill up to expected size...
1422 */
1423 if ((props.pr_flags & PR_CPIO) == 0) {
1424 while (--blocks >= 0)
1425 writeempty();
1426 } else {
1427 while (size > 0) {
1428 amount = buf_wait(1);
1429 amount = min(amount, size);
1430 fillbytes(bigptr, amount, '\0');
1431 buf_wake(amount);
1432 size -= amount;
1433 }
1434 }
1435 /*
1436 * Honour CPIO padding
1437 */
1438 if ((amount = props.pr_pad) != 0) {
1439 size = info->f_rsize;
1440 if (info->f_flags & F_LONGNAME)
1441 size += props.pr_hdrsize;
1442 amount = (amount + 1 - (size & amount)) & amount;
1443 while (amount-- > 0) {
1444 buf_wait(1);
1445 *bigptr = '\0';
1446 buf_wake(1);
1447 }
1448 }
1449 }
1450
1451 #define newfs(i) ((i)->f_dev != curfs)
1452
1453 LOCAL void
put_dir(sname,dname,namlen,info,ptb,pathp,last)1454 put_dir(sname, dname, namlen, info, ptb, pathp, last)
1455 char *sname;
1456 register char *dname;
1457 register int namlen;
1458 FINFO *info;
1459 TCB *ptb;
1460 pathstore_t *pathp;
1461 struct pdirs *last;
1462 {
1463 static int depth = -10;
1464 static int dinit = 0;
1465 FINFO nfinfo;
1466 register FINFO *ninfo = &nfinfo;
1467 DIR *d = NULL;
1468 struct dirent *dir;
1469 #ifdef HAVE_SEEKDIR
1470 long offset = 0L;
1471 #endif
1472 pathstore_t path;
1473 register char *name;
1474 size_t xlen;
1475 BOOL putdir = FALSE;
1476 BOOL direrr = FALSE;
1477 size_t dlen;
1478 char *dp = NULL;
1479 struct pdirs thisd;
1480 struct pdirs *pd = last;
1481 BOOL didslash = FALSE;
1482
1483 if (!dinit) {
1484 #ifdef _SC_OPEN_MAX
1485 depth += sysconf(_SC_OPEN_MAX);
1486 #else
1487 depth += getdtablesize();
1488 #endif
1489 dinit = 1;
1490 }
1491
1492 if (nodump && (info->f_flags & F_NODUMP) != 0)
1493 return;
1494
1495 info->f_dir = NULL;
1496 info->f_dirinos = NULL;
1497 info->f_dirlen = 0;
1498 info->f_dirents = 0;
1499
1500 switch (take_file(dname, info)) {
1501
1502 case -1:
1503 if (match_tree)
1504 return;
1505 break;
1506
1507 case TRUE:
1508 putdir = TRUE;
1509 }
1510
1511 if ((!nodesc || dodump > 0) && (!nomount || !newfs(info))) {
1512 /*
1513 * If this is a mounted directory and we have been called
1514 * with -M, it makes no sense to include the directorie's file
1515 * name list with -dump.
1516 * By not including this list, we also avoid error messages
1517 * like:
1518 * star: Permission denied. Cannot open 'opt/SUNWddk'.
1519 *
1520 * which is a result of an automounted directory.
1521 *
1522 * Conclusion: try to use a filesystem snapshot whenever
1523 * possible.
1524 */
1525 if (!lowmem) {
1526 ino_t *ino = NULL;
1527 size_t nents;
1528
1529 d = lopendir(sname);
1530 if (d) {
1531 dp = dfetchdir(d, sname,
1532 &nents, &dlen, dodump?&ino:NULL);
1533 #if defined(HAVE_FSTATAT) && defined(HAVE_DIRFD)
1534 if (depth <= 0) {
1535 closedir(d);
1536 d = NULL;
1537 }
1538 #else
1539 closedir(d);
1540 d = NULL;
1541 #endif
1542 } else {
1543 dp = NULL;
1544 }
1545 if (dp == NULL) {
1546 if (!errhidden(E_OPEN, dname)) {
1547 if (!errwarnonly(E_OPEN, dname))
1548 xstats.s_openerrs++;
1549 errmsg("Cannot open '%s'.\n", dname);
1550 (void) errabort(E_OPEN, dname, TRUE);
1551 }
1552 direrr = TRUE;
1553 } else {
1554 info->f_dir = dp;
1555 info->f_dirinos = ino;
1556 info->f_dirlen = dlen;
1557 info->f_dirents = nents;
1558 /*
1559 * Don't count list terminator null Byte
1560 */
1561 dlen--;
1562 }
1563 } else if (!(d = lopendir(sname))) {
1564 if (!errhidden(E_OPEN, dname)) {
1565 if (!errwarnonly(E_OPEN, dname))
1566 xstats.s_openerrs++;
1567 errmsg("Cannot open '%s'.\n", dname);
1568 (void) errabort(E_OPEN, dname, TRUE);
1569 }
1570 direrr = TRUE;
1571 }
1572 }
1573 depth--;
1574 if (!nodir) {
1575 if (interactive && !ia_change(ptb, info)) {
1576 fgtprintf(vpr, "Skipping ...\n");
1577 if (d)
1578 closedir(d);
1579 if (dp)
1580 free(info->f_dir);
1581 if (info->f_dirinos)
1582 free(info->f_dirinos);
1583 depth++;
1584 return;
1585 }
1586 if (putdir) {
1587 if (!dirmode)
1588 put_tcb(ptb, info);
1589 vprint(info);
1590 }
1591 }
1592 if (direrr) {
1593 depth++;
1594 return;
1595 }
1596
1597 /*
1598 * Search parent dir structure for possible loops.
1599 */
1600 thisd.p_last = last;
1601 thisd.p_dev = info->f_dev;
1602 thisd.p_ino = info->f_ino;
1603
1604 while (pd) {
1605 if (pd->p_dev == info->f_dev &&
1606 pd->p_ino == info->f_ino) {
1607 goto out;
1608 }
1609 pd = pd->p_last;
1610 }
1611
1612 if (!nodesc && (!nomount || !newfs(info))) {
1613 if (sname != dname)
1614 comerrno(EX_BAD, "Panic: put_dir(): sname != dname\n");
1615
1616 name = dname;
1617 if (pathp == NULL) {
1618 if (name[0] == '.' && name[1] == '/') {
1619 for (name++; name[0] == '/'; name++)
1620 /* LINTED */
1621 ;
1622 namlen -= name - dname;
1623 }
1624 if (name[0] == '.' && name[1] == '\0') {
1625 name++;
1626 namlen--;
1627 }
1628 pathp = &path;
1629 if (init_pspace(PS_STDERR, pathp) < 0 ||
1630 strlcpy_pspace(PS_STDERR, pathp, name, namlen) < 0) {
1631 toolong("", name, namlen);
1632 goto out;
1633 }
1634 }
1635 if (namlen && pathp->ps_path[pathp->ps_tail - 1] != '/') {
1636 char *p;
1637
1638 if ((pathp->ps_tail+2) > pathp->ps_size) {
1639 if (incr_pspace(PS_STDERR, pathp, 2) < 0) {
1640 toolong("", name, namlen);
1641 goto out;
1642 }
1643 }
1644 p = &pathp->ps_path[pathp->ps_tail++];
1645 *p++ = '/';
1646 *p++ = '\0';
1647 namlen++;
1648 didslash = TRUE;
1649 }
1650
1651 while (!intr) {
1652 char *snm;
1653
1654 if (lowmem) {
1655 if ((dir = readdir(d)) == NULL)
1656 break;
1657 if (streql(dir->d_name, ".") ||
1658 streql(dir->d_name, ".."))
1659 continue;
1660 snm = dir->d_name;
1661 xlen = strlen(snm);
1662 } else {
1663 if (dlen == 0)
1664 break;
1665
1666 snm = &dp[1];
1667 xlen = strlen(snm);
1668 dp += xlen + 2;
1669 /*
1670 * Subtract total element size but make sure
1671 * that "dlen" never wraps "below" zero, as it
1672 * is unsigned.
1673 */
1674 if ((xlen + 2) > dlen)
1675 dlen = 0;
1676 else
1677 dlen -= xlen + 2;
1678 }
1679
1680 if ((namlen+xlen+1) >= pathp->ps_size) {
1681 if (grow_pspace(PS_STDERR, pathp, namlen+xlen+1) < 0) {
1682 toolong(pathp->ps_path, snm, namlen+xlen);
1683 goto out;
1684 }
1685 }
1686 strcpy(&pathp->ps_path[pathp->ps_tail], snm);
1687 name = pathp->ps_path;
1688
1689 #if defined(HAVE_FSTATAT) && defined(HAVE_DIRFD)
1690 /*
1691 * We get the performance win only with the native
1692 * fstatat() and not from the emulation.
1693 */
1694 if (d ? !getinfoat(dirfd(d), snm, ninfo) :
1695 !getinfo(name, ninfo)) {
1696 #else
1697 if (!getinfo(name, ninfo)) {
1698 #endif
1699 if (!errhidden(E_STAT, name)) {
1700 if (!errwarnonly(E_STAT, name))
1701 xstats.s_staterrs++;
1702 errmsg("Cannot stat '%s'.\n", name);
1703 (void) errabort(E_STAT, name, TRUE);
1704 }
1705 continue;
1706 }
1707 #ifdef HAVE_SEEKDIR
1708 if (d && is_dir(ninfo) && depth <= 0) {
1709 seterrno(0);
1710 offset = telldir(d);
1711 if (geterrno()) {
1712 char *p;
1713
1714 if (pathp->ps_tail == 0) {
1715 dname = ".";
1716 p = NULL;
1717 } else {
1718 /*
1719 * pathstore_t relocates ps_path
1720 */
1721 dname = pathp->ps_path;
1722 p = &pathp->ps_path[pathp->ps_tail-1];
1723 *p = '\0';
1724 }
1725 if (!errhidden(E_OPEN, dname)) {
1726 if (!errwarnonly(E_OPEN, dname))
1727 xstats.s_openerrs++;
1728 errmsg(
1729 "WARNING: telldir does not work on '%s'.\n",
1730 dname);
1731 (void) errabort(E_OPEN, dname,
1732 TRUE);
1733 }
1734 if (p)
1735 *p = '/';
1736 /*
1737 * XXX xstats.s_openerrs is wrong here.
1738 * Avoid an endless loop on unseekable
1739 * directories.
1740 */
1741 /* closedir() is past end of loop */
1742 break;
1743 }
1744 closedir(d);
1745 }
1746 #endif
1747 pathp->ps_tail += xlen;
1748 createi(name, name, xlen+namlen, ninfo, pathp, &thisd);
1749 pathp->ps_tail -= xlen;
1750 pathp->ps_path[pathp->ps_tail] = '\0';
1751 #ifdef HAVE_SEEKDIR
1752 if (d && is_dir(ninfo) && depth <= 0) {
1753 char *p;
1754
1755 if (pathp->ps_tail == 0) {
1756 sname = dname = ".";
1757 p = NULL;
1758 } else {
1759 /*
1760 * pathstore_t relocates ps_path
1761 */
1762 sname = dname = pathp->ps_path;
1763 p = &pathp->ps_path[pathp->ps_tail-1];
1764 *p = '\0';
1765 }
1766 if (!(d = lopendir(sname))) {
1767 if (!errhidden(E_OPEN, dname)) {
1768 if (!errwarnonly(E_OPEN, dname))
1769 xstats.s_openerrs++;
1770 errmsg("Cannot open '%s'.\n",
1771 dname);
1772 (void) errabort(E_OPEN, dname,
1773 TRUE);
1774 }
1775 if (p)
1776 *p = '/';
1777 break;
1778 }
1779 seterrno(0);
1780 seekdir(d, offset);
1781 if (geterrno()) {
1782 if (!errhidden(E_OPEN, dname)) {
1783 if (!errwarnonly(E_OPEN, dname))
1784 xstats.s_openerrs++;
1785 errmsg(
1786 "WARNING: seekdir does not work on '%s'.\n",
1787 dname);
1788 (void) errabort(E_OPEN, dname,
1789 TRUE);
1790 }
1791 /*
1792 * XXX xstats.s_openerrs is wrong here.
1793 * Avoid an endless loop on unseekable
1794 * directories.
1795 */
1796 if (p)
1797 *p = '/';
1798 break;
1799 }
1800 if (p)
1801 *p = '/';
1802 }
1803 #endif
1804 }
1805 }
1806 out:
1807 if (didslash)
1808 pathp->ps_path[--pathp->ps_tail] = '\0';
1809 if (d)
1810 closedir(d);
1811 if (dp)
1812 free(info->f_dir);
1813 if (info->f_dirinos)
1814 free(info->f_dirinos);
1815 if (pathp == &path)
1816 free_pspace(pathp);
1817 depth++;
1818 if (!nodir && dirmode && putdir)
1819 put_tcb(ptb, info);
1820 }
1821
1822 /*
1823 * This is currently only called in case we did run out of memory.
1824 */
1825 LOCAL void
toolong(dname,name,len)1826 toolong(dname, name, len)
1827 char *dname;
1828 char *name;
1829 size_t len;
1830 {
1831 if (!errhidden(E_NAMETOOLONG, name)) {
1832 if (!errwarnonly(E_NAMETOOLONG, name))
1833 xstats.s_toolong++;
1834 errmsgno(EX_BAD, "%s%s: Name too long (%lu), out of memory.\n",
1835 dname, name,
1836 (unsigned long)len);
1837 (void) errabort(E_NAMETOOLONG, name, TRUE);
1838 }
1839 }
1840
1841 LOCAL BOOL
checkdirexclude(sname,name,namlen,info)1842 checkdirexclude(sname, name, namlen, info)
1843 char *sname;
1844 char *name;
1845 int namlen;
1846 FINFO *info;
1847 {
1848 FINFO finfo;
1849 char pname[PATH_MAX+1];
1850 char *pnamep = pname;
1851 size_t pnamelen = sizeof (pname);
1852 size_t pnlen;
1853 int OFflag = Fflag;
1854 char *p;
1855 BOOL ret = TRUE;
1856
1857 Fflag = 0;
1858 pnlen = namlen;
1859 pnlen += 2 + 8; /* Null Byte + '/' + strlen(".exclude") */
1860 if (pnlen > pnamelen) {
1861 pnamep = __fjmalloc(stderr, pnlen, "name buffer", JM_RETURN);
1862 if (pnamep == NULL) {
1863 errmsg("Cannot check '%s' for exclude\n", name);
1864 goto notfound;
1865 }
1866 }
1867 strcpy(pnamep, name);
1868 p = &pnamep[namlen];
1869 if (p[-1] != '/') {
1870 *p++ = '/';
1871 }
1872 strcpy(p, ".mirror");
1873 if (!_getinfo(pnamep, &finfo)) {
1874 strcpy(p, ".exclude");
1875 if (!_getinfo(pnamep, &finfo))
1876 goto notfound;
1877 }
1878 if (is_file(&finfo)) {
1879 if (OFflag == 3) {
1880 nodesc++;
1881 if (!dirmode) {
1882 createi(sname, name, namlen, info,
1883 (pathstore_t *)0,
1884 (struct pdirs *)0);
1885 }
1886 create(pnamep, FALSE, FALSE); /* Needed to strip off "./" */
1887 if (dirmode) {
1888 createi(sname, name, namlen, info,
1889 (pathstore_t *)0,
1890 (struct pdirs *)0);
1891 }
1892 nodesc--;
1893 }
1894 ret = FALSE;
1895 }
1896 notfound:
1897 if (pnamep != pname)
1898 free(pnamep);
1899 Fflag = OFflag;
1900 return (ret);
1901 }
1902
1903 LOCAL BOOL
checkexclude(sname,name,namlen,info)1904 checkexclude(sname, name, namlen, info)
1905 char *sname;
1906 char *name;
1907 int namlen;
1908 FINFO *info;
1909 {
1910 int len;
1911 const char *fn;
1912
1913 if (Fflag <= 0)
1914 return (TRUE);
1915
1916 fn = filename(name);
1917
1918 if (is_dir(info)) {
1919 /*
1920 * Exclude with -F -FF -FFFFF 1, 2, 5+
1921 */
1922 if (Fflag < 3 || Fflag > 4) {
1923 if (streql(fn, "SCCS") || /* SCCS directory */
1924 streql(fn, "RCS")) /* RCS directory */
1925 return (FALSE);
1926 }
1927 if (Fflag > 1 && streql(fn, "OBJ")) /* OBJ directory */
1928 return (FALSE);
1929 if (Fflag > 2 && !checkdirexclude(sname, name, namlen, info))
1930 return (FALSE);
1931 return (TRUE);
1932 }
1933 if ((len = strlen(fn)) < 3) /* Will never match later */
1934 return (TRUE);
1935
1936 if (Fflag > 1 && fn[len-2] == '.' && fn[len-1] == 'o') /* obj files */
1937 return (FALSE);
1938
1939 if (Fflag > 1 && is_file(info)) {
1940 if (streql(fn, "core") ||
1941 streql(fn, "errs") ||
1942 streql(fn, "a.out"))
1943 return (FALSE);
1944 }
1945
1946 return (TRUE);
1947 }
1948
1949 #ifdef USE_FIND
1950 /*
1951 * The callback function for treewalk()
1952 *
1953 * XXX errhidden() support not yet implemented.
1954 */
1955 EXPORT int
walkfunc(nm,fs,type,state)1956 walkfunc(nm, fs, type, state)
1957 char *nm;
1958 struct stat *fs;
1959 int type;
1960 struct WALK *state;
1961 {
1962 if (intr) {
1963 state->flags |= WALK_WF_QUIT;
1964 return (0);
1965 }
1966 if (type == WALK_NS) {
1967 errmsg("Cannot stat '%s'.\n", nm);
1968 state->err = 1;
1969 return (0);
1970 } else if (type == WALK_SLN && (state->walkflags & WALK_PHYS) == 0) {
1971 errmsg("Cannot follow symlink '%s'.\n", nm);
1972 state->err = 1;
1973 return (0);
1974 } else if (type == WALK_DNR) {
1975 if (state->flags & WALK_WF_NOCHDIR)
1976 errmsg("Cannot chdir to '%s'.\n", nm);
1977 else
1978 errmsg("Cannot read '%s'.\n", nm);
1979 state->err = 1;
1980 return (0);
1981 }
1982 if (state->maxdepth >= 0 && state->level >= state->maxdepth)
1983 state->flags |= WALK_WF_PRUNE;
1984 if (state->mindepth >= 0 && state->level < state->mindepth)
1985 return (0);
1986
1987 if (state->tree == NULL ||
1988 find_expr(nm, nm + state->base, fs, state, state->tree)) {
1989 FINFO finfo;
1990 extern char *listfile;
1991
1992 finfo.f_sname = nm + state->base;
1993 finfo.f_name = nm;
1994 stat_to_info(AT_FDCWD, fs, &finfo);
1995 if (nomount && newfs(&finfo))
1996 return (0);
1997 if (listfile) /* We did not do a chdir() */
1998 state->base = 0;
1999 createi(nm + state->base, nm, strlen(nm), &finfo,
2000 (pathstore_t *)0, (struct pdirs *)0);
2001 }
2002 return (0);
2003 }
2004
2005 LOCAL void
findcreate(name,state)2006 findcreate(name, state)
2007 register char *name;
2008 struct WALK *state;
2009 {
2010 struct stat statbuf;
2011 int type = WALK_NONE;
2012
2013 if (!getstat(name, &statbuf)) {
2014 if (!errhidden(E_STAT, name)) {
2015 if (!errwarnonly(E_STAT, name))
2016 xstats.s_staterrs++;
2017 errmsg("Cannot stat '%s'.\n", name);
2018 (void) errabort(E_STAT, name, TRUE);
2019 }
2020 return;
2021 }
2022
2023 walksname(name, state);
2024 (void) walkfunc(name, &statbuf, type, state);
2025 }
2026 #endif
2027