]> Dogcows Code - chaz/tar/blob - src/create.c
*** empty log message ***
[chaz/tar] / src / create.c
1 /* Create a tar archive.
2 Copyright (C) 1985, 1992, 1993 Free Software Foundation
3
4 This file is part of GNU Tar.
5
6 GNU Tar is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Tar is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Tar; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /*
21 * Create a tar archive.
22 *
23 * Written 25 Aug 1985 by John Gilmore, ihnp4!hoptoad!gnu.
24 */
25
26 #ifdef _AIX
27 #pragma alloca
28 #endif
29 #include <sys/types.h>
30 #include <stdio.h>
31 #include <errno.h>
32 #ifndef STDC_HEADERS
33 extern int errno;
34 #endif
35
36 #ifdef BSD42
37 #include <sys/file.h>
38 #else
39 #ifndef V7
40 #include <fcntl.h>
41 #endif
42 #endif
43
44 #include "tar.h"
45 #include "port.h"
46
47 #ifndef __MSDOS__
48 #include <pwd.h>
49 #include <grp.h>
50 #endif
51
52 #if defined (_POSIX_VERSION)
53 #include <utime.h>
54 #else
55 struct utimbuf
56 {
57 long actime;
58 long modtime;
59 };
60
61 #endif
62
63 extern struct stat hstat; /* Stat struct corresponding */
64
65 #ifndef __MSDOS__
66 extern dev_t ar_dev;
67 extern ino_t ar_ino;
68 #endif
69
70 /* JF */
71 extern struct name *gnu_list_name;
72
73 /*
74 * If there are no symbolic links, there is no lstat(). Use stat().
75 */
76 #ifndef S_ISLNK
77 #define lstat stat
78 #endif
79
80 extern void print_header ();
81
82 union record *start_header ();
83 void blank_name_list ();
84 int check_exclude ();
85 PTR ck_malloc ();
86 PTR ck_realloc ();
87 void clear_buffer ();
88 void close_archive ();
89 void collect_and_sort_names ();
90 int confirm ();
91 int deal_with_sparse ();
92 void find_new_file_size ();
93 void finish_header ();
94 int finish_sparse_file ();
95 void finduname ();
96 void findgname ();
97 int is_dot_or_dotdot ();
98 void open_archive ();
99 char *name_next ();
100 void name_close ();
101 void to_oct ();
102 void dump_file ();
103 void write_dir_file ();
104 void write_eot ();
105 void write_long ();
106 int zero_record ();
107
108 /* This code moved from tar.h since create.c is the only file that cares
109 about 'struct link's. This means that other files might not have to
110 include sys/types.h any more. */
111
112 struct link
113 {
114 struct link *next;
115 dev_t dev;
116 ino_t ino;
117 short linkcount;
118 char name[1];
119 };
120
121 struct link *linklist; /* Points to first link in list */
122
123 static nolinks; /* Gets set if we run out of RAM */
124
125 /*
126 * "Scratch" space to store the information about a sparse file before
127 * writing the info into the header or extended header
128 */
129 /* struct sp_array *sparsearray;*/
130
131 /* number of elts storable in the sparsearray */
132 /*int sparse_array_size = 10;*/
133
134 void
135 create_archive ()
136 {
137 register char *p;
138 char *name_from_list ();
139
140 open_archive (0); /* Open for writing */
141
142 if (f_gnudump)
143 {
144 char *buf = ck_malloc (PATH_MAX);
145 char *q, *bufp;
146
147 collect_and_sort_names ();
148
149 while (p = name_from_list ())
150 dump_file (p, -1, 1);
151 /* if(!f_dironly) { */
152 blank_name_list ();
153 while (p = name_from_list ())
154 {
155 strcpy (buf, p);
156 if (p[strlen (p) - 1] != '/')
157 strcat (buf, "/");
158 bufp = buf + strlen (buf);
159 for (q = gnu_list_name->dir_contents; q && *q; q += strlen (q) + 1)
160 {
161 if (*q == 'Y')
162 {
163 strcpy (bufp, q + 1);
164 dump_file (buf, -1, 1);
165 }
166 }
167 }
168 /* } */
169 free (buf);
170 }
171 else
172 {
173 while (p = name_next (1))
174 dump_file (p, -1, 1);
175 }
176
177 write_eot ();
178 close_archive ();
179 if (f_gnudump)
180 write_dir_file ();
181 name_close ();
182 }
183
184 /*
185 * Dump a single file. If it's a directory, recurse.
186 * Result is 1 for success, 0 for failure.
187 * Sets global "hstat" to stat() output for this file.
188 */
189 void
190 dump_file (p, curdev, toplevel)
191 char *p; /* File name to dump */
192 int curdev; /* Device our parent dir was on */
193 int toplevel; /* Whether we are a toplevel call */
194 {
195 union record *header;
196 char type;
197 extern char *save_name; /* JF for multi-volume support */
198 extern long save_totsize;
199 extern long save_sizeleft;
200 union record *exhdr;
201 char save_linkflag;
202 extern time_t new_time;
203 int critical_error = 0;
204 struct utimbuf restore_times;
205 /* int sparse_ind = 0;*/
206
207
208 if (f_confirm && !confirm ("add", p))
209 return;
210
211 /*
212 * Use stat if following (rather than dumping) 4.2BSD's
213 * symbolic links. Otherwise, use lstat (which, on non-4.2
214 * systems, is #define'd to stat anyway.
215 */
216 #ifdef STX_HIDDEN /* AIX */
217 if (0 != f_follow_links ?
218 statx (p, &hstat, STATSIZE, STX_HIDDEN) :
219 statx (p, &hstat, STATSIZE, STX_HIDDEN | STX_LINK))
220 #else
221 if (0 != f_follow_links ? stat (p, &hstat) : lstat (p, &hstat))
222 #endif
223 {
224 badperror:
225 msg_perror ("can't add file %s", p);
226 badfile:
227 if (!f_ignore_failed_read || critical_error)
228 errors++;
229 return;
230 }
231
232 restore_times.actime = hstat.st_atime;
233 restore_times.modtime = hstat.st_mtime;
234
235 #ifdef S_ISHIDDEN
236 if (S_ISHIDDEN (hstat.st_mode))
237 {
238 char *new = (char *) alloca (strlen (p) + 2);
239 if (new)
240 {
241 strcpy (new, p);
242 strcat (new, "@");
243 p = new;
244 }
245 }
246 #endif
247
248 /* See if we only want new files, and check if this one is too old to
249 put in the archive. */
250 if (f_new_files
251 && !f_gnudump
252 && new_time > hstat.st_mtime
253 && !S_ISDIR (hstat.st_mode)
254 && (f_new_files > 1 || new_time > hstat.st_ctime))
255 {
256 if (curdev < 0)
257 {
258 msg ("%s: is unchanged; not dumped", p);
259 }
260 return;
261 }
262
263 #ifndef __MSDOS__
264 /* See if we are trying to dump the archive */
265 if (ar_dev && hstat.st_dev == ar_dev && hstat.st_ino == ar_ino)
266 {
267 msg ("%s is the archive; not dumped", p);
268 return;
269 }
270 #endif
271 /*
272 * Check for multiple links.
273 *
274 * We maintain a list of all such files that we've written so
275 * far. Any time we see another, we check the list and
276 * avoid dumping the data again if we've done it once already.
277 */
278 if (hstat.st_nlink > 1
279 && (S_ISREG (hstat.st_mode)
280 #ifdef S_ISCTG
281 || S_ISCTG (hstat.st_mode)
282 #endif
283 #ifdef S_ISCHR
284 || S_ISCHR (hstat.st_mode)
285 #endif
286 #ifdef S_ISBLK
287 || S_ISBLK (hstat.st_mode)
288 #endif
289 #ifdef S_ISFIFO
290 || S_ISFIFO (hstat.st_mode)
291 #endif
292 ))
293 {
294 register struct link *lp;
295
296 /* First quick and dirty. Hashing, etc later FIXME */
297 for (lp = linklist; lp; lp = lp->next)
298 {
299 if (lp->ino == hstat.st_ino &&
300 lp->dev == hstat.st_dev)
301 {
302 char *link_name = lp->name;
303
304 /* We found a link. */
305 while (!f_absolute_paths && *link_name == '/')
306 {
307 static int link_warn = 0;
308
309 if (!link_warn)
310 {
311 msg ("Removing leading / from absolute links");
312 link_warn++;
313 }
314 link_name++;
315 }
316 if (link_name - lp->name >= NAMSIZ)
317 write_long (link_name, LF_LONGLINK);
318 current_link_name = link_name;
319
320 hstat.st_size = 0;
321 header = start_header (p, &hstat);
322 if (header == NULL)
323 {
324 critical_error = 1;
325 goto badfile;
326 }
327 strncpy (header->header.arch_linkname,
328 link_name, NAMSIZ);
329
330 /* Force null truncated */
331 header->header.arch_linkname[NAMSIZ - 1] = 0;
332
333 header->header.linkflag = LF_LINK;
334 finish_header (header);
335 /* FIXME: Maybe remove from list after all links found? */
336 if (f_remove_files)
337 {
338 if (unlink (p) == -1)
339 msg_perror ("cannot remove %s", p);
340 }
341 return; /* We dumped it */
342 }
343 }
344
345 /* Not found. Add it to the list of possible links. */
346 lp = (struct link *) ck_malloc ((unsigned) (sizeof (struct link) + strlen (p)));
347 if (!lp)
348 {
349 if (!nolinks)
350 {
351 msg (
352 "no memory for links, they will be dumped as separate files");
353 nolinks++;
354 }
355 }
356 lp->ino = hstat.st_ino;
357 lp->dev = hstat.st_dev;
358 strcpy (lp->name, p);
359 lp->next = linklist;
360 linklist = lp;
361 }
362
363 /*
364 * This is not a link to a previously dumped file, so dump it.
365 */
366 if (S_ISREG (hstat.st_mode)
367 #ifdef S_ISCTG
368 || S_ISCTG (hstat.st_mode)
369 #endif
370 )
371 {
372 int f; /* File descriptor */
373 long bufsize, count;
374 long sizeleft;
375 register union record *start;
376 int header_moved;
377 char isextended = 0;
378 int upperbound;
379 /* int end_nulls = 0; */
380
381 header_moved = 0;
382
383 #ifdef BSD42
384 if (f_sparse_files)
385 {
386 /*
387 * JK - This is the test for sparseness: whether the
388 * "size" of the file matches the number of blocks
389 * allocated for it. If there is a smaller number
390 * of blocks that would be necessary to accommodate
391 * a file of this size, we have a sparse file, i.e.,
392 * at least one of those records in the file is just
393 * a useless hole.
394 */
395 #ifdef hpux /* Nice of HPUX to gratuitiously change it, huh? - mib */
396 if (hstat.st_size - (hstat.st_blocks * 1024) > 1024)
397 #else
398 if (hstat.st_size - (hstat.st_blocks * RECORDSIZE) > RECORDSIZE)
399 #endif
400 {
401 int filesize = hstat.st_size;
402 register int i;
403
404 header = start_header (p, &hstat);
405 if (header == NULL)
406 {
407 critical_error = 1;
408 goto badfile;
409 }
410 header->header.linkflag = LF_SPARSE;
411 header_moved++;
412
413 /*
414 * Call the routine that figures out the
415 * layout of the sparse file in question.
416 * UPPERBOUND is the index of the last
417 * element of the "sparsearray," i.e.,
418 * the number of elements it needed to
419 * describe the file.
420 */
421
422 upperbound = deal_with_sparse (p, header);
423
424 /*
425 * See if we'll need an extended header
426 * later
427 */
428 if (upperbound > SPARSE_IN_HDR - 1)
429 header->header.isextended++;
430 /*
431 * We store the "real" file size so
432 * we can show that in case someone wants
433 * to list the archive, i.e., tar tvf <file>.
434 * It might be kind of disconcerting if the
435 * shrunken file size was the one that showed
436 * up.
437 */
438 to_oct ((long) hstat.st_size, 1 + 12,
439 header->header.realsize);
440
441 /*
442 * This will be the new "size" of the
443 * file, i.e., the size of the file
444 * minus the records of holes that we're
445 * skipping over.
446 */
447
448 find_new_file_size (&filesize, upperbound);
449 hstat.st_size = filesize;
450 to_oct ((long) filesize, 1 + 12,
451 header->header.size);
452 /* to_oct((long) end_nulls, 1+12,
453 header->header.ending_blanks);*/
454
455 for (i = 0; i < SPARSE_IN_HDR; i++)
456 {
457 if (!sparsearray[i].numbytes)
458 break;
459 to_oct (sparsearray[i].offset, 1 + 12,
460 header->header.sp[i].offset);
461 to_oct (sparsearray[i].numbytes, 1 + 12,
462 header->header.sp[i].numbytes);
463 }
464
465 }
466 }
467 #else
468 upperbound = SPARSE_IN_HDR - 1;
469 #endif
470
471 sizeleft = hstat.st_size;
472 /* Don't bother opening empty, world readable files. */
473 if (sizeleft > 0 || 0444 != (0444 & hstat.st_mode))
474 {
475 f = open (p, O_RDONLY | O_BINARY);
476 if (f < 0)
477 goto badperror;
478 }
479 else
480 {
481 f = -1;
482 }
483
484 /* If the file is sparse, we've already taken care of this */
485 if (!header_moved)
486 {
487 header = start_header (p, &hstat);
488 if (header == NULL)
489 {
490 if (f >= 0)
491 (void) close (f);
492 critical_error = 1;
493 goto badfile;
494 }
495 }
496 #ifdef S_ISCTG
497 /* Mark contiguous files, if we support them */
498 if (f_standard && S_ISCTG (hstat.st_mode))
499 {
500 header->header.linkflag = LF_CONTIG;
501 }
502 #endif
503 isextended = header->header.isextended;
504 save_linkflag = header->header.linkflag;
505 finish_header (header);
506 if (isextended)
507 {
508 /* int sum = 0;*/
509 register int i;
510 /* register union record *exhdr;*/
511 /* int arraybound = SPARSE_EXT_HDR;*/
512 /* static */ int index_offset = SPARSE_IN_HDR;
513
514 extend:exhdr = findrec ();
515
516 if (exhdr == NULL)
517 {
518 critical_error = 1;
519 goto badfile;
520 }
521 bzero (exhdr->charptr, RECORDSIZE);
522 for (i = 0; i < SPARSE_EXT_HDR; i++)
523 {
524 if (i + index_offset > upperbound)
525 break;
526 to_oct ((long) sparsearray[i + index_offset].numbytes,
527 1 + 12,
528 exhdr->ext_hdr.sp[i].numbytes);
529 to_oct ((long) sparsearray[i + index_offset].offset,
530 1 + 12,
531 exhdr->ext_hdr.sp[i].offset);
532 }
533 userec (exhdr);
534 /* sum += i;
535 if (sum < upperbound)
536 goto extend;*/
537 if (index_offset + i < upperbound)
538 {
539 index_offset += i;
540 exhdr->ext_hdr.isextended++;
541 goto extend;
542 }
543
544 }
545 if (save_linkflag == LF_SPARSE)
546 {
547 if (finish_sparse_file (f, &sizeleft, hstat.st_size, p))
548 goto padit;
549 }
550 else
551 while (sizeleft > 0)
552 {
553
554 if (f_multivol)
555 {
556 save_name = p;
557 save_sizeleft = sizeleft;
558 save_totsize = hstat.st_size;
559 }
560 start = findrec ();
561
562 bufsize = endofrecs ()->charptr - start->charptr;
563
564 if (sizeleft < bufsize)
565 {
566 /* Last read -- zero out area beyond */
567 bufsize = (int) sizeleft;
568 count = bufsize % RECORDSIZE;
569 if (count)
570 bzero (start->charptr + sizeleft,
571 (int) (RECORDSIZE - count));
572 }
573 count = read (f, start->charptr, bufsize);
574 if (count < 0)
575 {
576 msg_perror ("read error at byte %ld, reading\
577 %d bytes, in file %s", hstat.st_size - sizeleft, bufsize, p);
578 goto padit;
579 }
580 sizeleft -= count;
581
582 /* This is nonportable (the type of userec's arg). */
583 userec (start + (count - 1) / RECORDSIZE);
584
585 if (count == bufsize)
586 continue;
587 msg ("file %s shrunk by %d bytes, padding with zeros.", p, sizeleft);
588 goto padit; /* Short read */
589 }
590
591 if (f_multivol)
592 save_name = 0;
593
594 if (f >= 0)
595 (void) close (f);
596
597 if (f_remove_files)
598 {
599 if (unlink (p) == -1)
600 msg_perror ("cannot remove %s", p);
601 }
602 if (f_atime_preserve)
603 utime (p, &restore_times);
604 return;
605
606 /*
607 * File shrunk or gave error, pad out tape to match
608 * the size we specified in the header.
609 */
610 padit:
611 while (sizeleft > 0)
612 {
613 save_sizeleft = sizeleft;
614 start = findrec ();
615 bzero (start->charptr, RECORDSIZE);
616 userec (start);
617 sizeleft -= RECORDSIZE;
618 }
619 if (f_multivol)
620 save_name = 0;
621 if (f >= 0)
622 (void) close (f);
623 if (f_atime_preserve)
624 utime (p, &restore_times);
625 return;
626 }
627
628 #ifdef S_ISLNK
629 else if (S_ISLNK (hstat.st_mode))
630 {
631 int size;
632 char *buf = alloca (PATH_MAX + 1);
633
634 size = readlink (p, buf, PATH_MAX + 1);
635 if (size < 0)
636 goto badperror;
637 buf[size] = '\0';
638 if (size >= NAMSIZ)
639 write_long (buf, LF_LONGLINK);
640 current_link_name = buf;
641
642 hstat.st_size = 0; /* Force 0 size on symlink */
643 header = start_header (p, &hstat);
644 if (header == NULL)
645 {
646 critical_error = 1;
647 goto badfile;
648 }
649 strncpy (header->header.arch_linkname, buf, NAMSIZ);
650 header->header.arch_linkname[NAMSIZ - 1] = '\0';
651 header->header.linkflag = LF_SYMLINK;
652 finish_header (header); /* Nothing more to do to it */
653 if (f_remove_files)
654 {
655 if (unlink (p) == -1)
656 msg_perror ("cannot remove %s", p);
657 }
658 return;
659 }
660 #endif
661
662 else if (S_ISDIR (hstat.st_mode))
663 {
664 register DIR *dirp;
665 register struct dirent *d;
666 char *namebuf;
667 int buflen;
668 register int len;
669 int our_device = hstat.st_dev;
670
671 /* Build new prototype name */
672 len = strlen (p);
673 buflen = len + NAMSIZ;
674 namebuf = ck_malloc (buflen + 1);
675 strncpy (namebuf, p, buflen);
676 while (len >= 1 && '/' == namebuf[len - 1])
677 len--; /* Delete trailing slashes */
678 namebuf[len++] = '/'; /* Now add exactly one back */
679 namebuf[len] = '\0'; /* Make sure null-terminated */
680
681 /*
682 * Output directory header record with permissions
683 * FIXME, do this AFTER files, to avoid R/O dir problems?
684 * If old archive format, don't write record at all.
685 */
686 if (!f_oldarch)
687 {
688 hstat.st_size = 0; /* Force 0 size on dir */
689 /*
690 * If people could really read standard archives,
691 * this should be: (FIXME)
692 header = start_header(f_standard? p: namebuf, &hstat);
693 * but since they'd interpret LF_DIR records as
694 * regular files, we'd better put the / on the name.
695 */
696 header = start_header (namebuf, &hstat);
697 if (header == NULL)
698 {
699 critical_error = 1;
700 goto badfile; /* eg name too long */
701 }
702
703 if (f_gnudump)
704 header->header.linkflag = LF_DUMPDIR;
705 else if (f_standard)
706 header->header.linkflag = LF_DIR;
707
708 /* If we're gnudumping, we aren't done yet so don't close it. */
709 if (!f_gnudump)
710 finish_header (header); /* Done with directory header */
711 }
712
713 if (f_gnudump)
714 {
715 int sizeleft;
716 int totsize;
717 int bufsize;
718 union record *start;
719 int count;
720 char *buf, *p_buf;
721
722 buf = gnu_list_name->dir_contents; /* FOO */
723 totsize = 0;
724 for (p_buf = buf; p_buf && *p_buf;)
725 {
726 int tmp;
727
728 tmp = strlen (p_buf) + 1;
729 totsize += tmp;
730 p_buf += tmp;
731 }
732 totsize++;
733 to_oct ((long) totsize, 1 + 12, header->header.size);
734 finish_header (header);
735 p_buf = buf;
736 sizeleft = totsize;
737 while (sizeleft > 0)
738 {
739 if (f_multivol)
740 {
741 save_name = p;
742 save_sizeleft = sizeleft;
743 save_totsize = totsize;
744 }
745 start = findrec ();
746 bufsize = endofrecs ()->charptr - start->charptr;
747 if (sizeleft < bufsize)
748 {
749 bufsize = sizeleft;
750 count = bufsize % RECORDSIZE;
751 if (count)
752 bzero (start->charptr + sizeleft, RECORDSIZE - count);
753 }
754 bcopy (p_buf, start->charptr, bufsize);
755 sizeleft -= bufsize;
756 p_buf += bufsize;
757 userec (start + (bufsize - 1) / RECORDSIZE);
758 }
759 if (f_multivol)
760 save_name = 0;
761 if (f_atime_preserve)
762 utime (p, &restore_times);
763 return;
764 }
765
766 /* Now output all the files in the directory */
767 #if 0
768 if (f_dironly)
769 return; /* Unless the cmdline said not to */
770 #endif
771 /*
772 * See if we are crossing from one file system to another,
773 * and avoid doing so if the user only wants to dump one file system.
774 */
775 if (f_local_filesys && !toplevel && curdev != hstat.st_dev)
776 {
777 if (f_verbose)
778 msg ("%s: is on a different filesystem; not dumped", p);
779 return;
780 }
781
782
783 errno = 0;
784 dirp = opendir (p);
785 if (!dirp)
786 {
787 if (errno)
788 {
789 msg_perror ("can't open directory %s", p);
790 }
791 else
792 {
793 msg ("error opening directory %s",
794 p);
795 }
796 return;
797 }
798
799 /* Hack to remove "./" from the front of all the file names */
800 if (len == 2 && namebuf[0] == '.' && namebuf[1] == '/')
801 len = 0;
802
803 /* Should speed this up by cd-ing into the dir, FIXME */
804 while (NULL != (d = readdir (dirp)))
805 {
806 /* Skip . and .. */
807 if (is_dot_or_dotdot (d->d_name))
808 continue;
809
810 if (NLENGTH (d) + len >= buflen)
811 {
812 buflen = len + NLENGTH (d);
813 namebuf = ck_realloc (namebuf, buflen + 1);
814 /* namebuf[len]='\0';
815 msg("file name %s%s too long",
816 namebuf, d->d_name);
817 continue; */
818 }
819 strcpy (namebuf + len, d->d_name);
820 if (f_exclude && check_exclude (namebuf))
821 continue;
822 dump_file (namebuf, our_device, 0);
823 }
824
825 closedir (dirp);
826 free (namebuf);
827 if (f_atime_preserve)
828 utime (p, &restore_times);
829 return;
830 }
831
832 #ifdef S_ISCHR
833 else if (S_ISCHR (hstat.st_mode))
834 {
835 type = LF_CHR;
836 }
837 #endif
838
839 #ifdef S_ISBLK
840 else if (S_ISBLK (hstat.st_mode))
841 {
842 type = LF_BLK;
843 }
844 #endif
845
846 /* Avoid screwy apollo lossage where S_IFIFO == S_IFSOCK */
847 #if (_ISP__M68K == 0) && (_ISP__A88K == 0) && defined(S_ISFIFO)
848 else if (S_ISFIFO (hstat.st_mode))
849 {
850 type = LF_FIFO;
851 }
852 #endif
853
854 #ifdef S_ISSOCK
855 else if (S_ISSOCK (hstat.st_mode))
856 {
857 type = LF_FIFO;
858 }
859 #endif
860 else
861 goto unknown;
862
863 if (!f_standard)
864 goto unknown;
865
866 hstat.st_size = 0; /* Force 0 size */
867 header = start_header (p, &hstat);
868 if (header == NULL)
869 {
870 critical_error = 1;
871 goto badfile; /* eg name too long */
872 }
873
874 header->header.linkflag = type;
875 #if defined(S_IFBLK) || defined(S_IFCHR)
876 if (type != LF_FIFO)
877 {
878 to_oct ((long) major (hstat.st_rdev), 8,
879 header->header.devmajor);
880 to_oct ((long) minor (hstat.st_rdev), 8,
881 header->header.devminor);
882 }
883 #endif
884
885 finish_header (header);
886 if (f_remove_files)
887 {
888 if (unlink (p) == -1)
889 msg_perror ("cannot remove %s", p);
890 }
891 return;
892
893 unknown:
894 msg ("%s: Unknown file type; file ignored.", p);
895 }
896
897 int
898 finish_sparse_file (fd, sizeleft, fullsize, name)
899 int fd;
900 long *sizeleft, fullsize;
901 char *name;
902 {
903 union record *start;
904 char tempbuf[RECORDSIZE];
905 int bufsize, sparse_ind = 0, count;
906 long pos;
907 long nwritten = 0;
908
909
910 while (*sizeleft > 0)
911 {
912 start = findrec ();
913 bzero (start->charptr, RECORDSIZE);
914 bufsize = sparsearray[sparse_ind].numbytes;
915 if (!bufsize)
916 { /* we blew it, maybe */
917 msg ("Wrote %ld of %ld bytes to file %s",
918 fullsize - *sizeleft, fullsize, name);
919 break;
920 }
921 pos = lseek (fd, sparsearray[sparse_ind++].offset, 0);
922 /*
923 * If the number of bytes to be written here exceeds
924 * the size of the temporary buffer, do it in steps.
925 */
926 while (bufsize > RECORDSIZE)
927 {
928 /* if (amt_read) {
929 count = read(fd, start->charptr+amt_read, RECORDSIZE-amt_read);
930 bufsize -= RECORDSIZE - amt_read;
931 amt_read = 0;
932 userec(start);
933 start = findrec();
934 bzero(start->charptr, RECORDSIZE);
935 }*/
936 /* store the data */
937 count = read (fd, start->charptr, RECORDSIZE);
938 if (count < 0)
939 {
940 msg_perror ("read error at byte %ld, reading %d bytes, in file %s",
941 fullsize - *sizeleft, bufsize, name);
942 return 1;
943 }
944 bufsize -= count;
945 *sizeleft -= count;
946 userec (start);
947 nwritten += RECORDSIZE; /* XXX */
948 start = findrec ();
949 bzero (start->charptr, RECORDSIZE);
950 }
951
952
953 clear_buffer (tempbuf);
954 count = read (fd, tempbuf, bufsize);
955 bcopy (tempbuf, start->charptr, RECORDSIZE);
956 if (count < 0)
957 {
958 msg_perror ("read error at byte %ld, reading %d bytes, in file %s",
959 fullsize - *sizeleft, bufsize, name);
960 return 1;
961 }
962 /* if (amt_read >= RECORDSIZE) {
963 amt_read = 0;
964 userec(start+(count-1)/RECORDSIZE);
965 if (count != bufsize) {
966 msg("file %s shrunk by %d bytes, padding with zeros.", name, sizeleft);
967 return 1;
968 }
969 start = findrec();
970 } else
971 amt_read += bufsize;*/
972 nwritten += count; /* XXX */
973 *sizeleft -= count;
974 userec (start);
975
976 }
977 free (sparsearray);
978 /* printf ("Amount actually written is (I hope) %d.\n", nwritten); */
979 /* userec(start+(count-1)/RECORDSIZE);*/
980 return 0;
981
982 }
983
984 void
985 init_sparsearray ()
986 {
987 register int i;
988
989 sp_array_size = 10;
990 /*
991 * Make room for our scratch space -- initially is 10 elts long
992 */
993 sparsearray = (struct sp_array *) ck_malloc (sp_array_size * sizeof (struct sp_array));
994 for (i = 0; i < sp_array_size; i++)
995 {
996 sparsearray[i].offset = 0;
997 sparsearray[i].numbytes = 0;
998 }
999 }
1000
1001
1002
1003 /*
1004 * Okay, we've got a sparse file on our hands -- now, what we need to do is
1005 * make a pass through the file and carefully note where any data is, i.e.,
1006 * we want to find how far into the file each instance of data is, and how
1007 * many bytes are there. We store this information in the sparsearray,
1008 * which will later be translated into header information. For now, we use
1009 * the sparsearray as convenient storage.
1010 *
1011 * As a side note, this routine is a mess. If I could have found a cleaner
1012 * way to do it, I would have. If anyone wants to find a nicer way to do
1013 * this, feel free.
1014 */
1015
1016 /* There is little point in trimming small amounts of null data at the */
1017 /* head and tail of blocks -- it's ok if we only avoid dumping blocks */
1018 /* of complete null data */
1019 int
1020 deal_with_sparse (name, header, nulls_at_end)
1021 char *name;
1022 union record *header;
1023 int nulls_at_end;
1024 {
1025 long numbytes = 0;
1026 long offset = 0;
1027 /* long save_offset;*/
1028 int fd;
1029 /* int current_size = hstat.st_size;*/
1030 int sparse_ind = 0, cc;
1031 char buf[RECORDSIZE];
1032 #if 0
1033 int read_last_data = 0; /* did we just read the last record? */
1034 #endif
1035 int amidst_data = 0;
1036
1037 header->header.isextended = 0;
1038 /*
1039 * Can't open the file -- this problem will be caught later on,
1040 * so just return.
1041 */
1042 if ((fd = open (name, O_RDONLY)) < 0)
1043 return 0;
1044
1045 init_sparsearray ();
1046 clear_buffer (buf);
1047
1048 while ((cc = read (fd, buf, sizeof buf)) != 0)
1049 {
1050
1051 if (sparse_ind > sp_array_size - 1)
1052 {
1053
1054 /*
1055 * realloc the scratch area, since we've run out of room --
1056 */
1057 sparsearray = (struct sp_array *)
1058 realloc (sparsearray,
1059 2 * sp_array_size * (sizeof (struct sp_array)));
1060 sp_array_size *= 2;
1061 }
1062 if (cc == sizeof buf)
1063 {
1064 if (zero_record (buf))
1065 {
1066 if (amidst_data)
1067 {
1068 sparsearray[sparse_ind++].numbytes
1069 = numbytes;
1070 amidst_data = 0;
1071 }
1072 }
1073 else
1074 { /* !zero_record(buf) */
1075 if (amidst_data)
1076 numbytes += cc;
1077 else
1078 {
1079 amidst_data = 1;
1080 numbytes = cc;
1081 sparsearray[sparse_ind].offset
1082 = offset;
1083 }
1084 }
1085 }
1086 else if (cc < sizeof buf)
1087 {
1088 /* This has to be the last bit of the file, so this */
1089 /* is somewhat shorter than the above. */
1090 if (!zero_record (buf))
1091 {
1092 if (!amidst_data)
1093 {
1094 amidst_data = 1;
1095 numbytes = cc;
1096 sparsearray[sparse_ind].offset
1097 = offset;
1098 }
1099 else
1100 numbytes += cc;
1101 }
1102 }
1103 offset += cc;
1104 clear_buffer (buf);
1105 }
1106 if (amidst_data)
1107 sparsearray[sparse_ind++].numbytes = numbytes;
1108 close (fd);
1109
1110 return sparse_ind - 1;
1111 }
1112
1113 /*
1114 * Just zeroes out the buffer so we don't confuse ourselves with leftover
1115 * data.
1116 */
1117 void
1118 clear_buffer (buf)
1119 char *buf;
1120 {
1121 register int i;
1122
1123 for (i = 0; i < RECORDSIZE; i++)
1124 buf[i] = '\0';
1125 }
1126
1127 #if 0 /* I'm leaving this as a monument to Joy Kendall, who wrote it -mib */
1128 /*
1129 * JK -
1130 * This routine takes a character array, and tells where within that array
1131 * the data can be found. It skips over any zeros, and sets the first
1132 * non-zero point in the array to be the "start", and continues until it
1133 * finds non-data again, which is marked as the "end." This routine is
1134 * mainly for 1) seeing how far into a file we must lseek to data, given
1135 * that we have a sparse file, and 2) determining the "real size" of the
1136 * file, i.e., the number of bytes in the sparse file that are data, as
1137 * opposed to the zeros we are trying to skip.
1138 */
1139 where_is_data (from, to, buffer)
1140 int *from, *to;
1141 char *buffer;
1142 {
1143 register int i = 0;
1144 register int save_to = *to;
1145 int amidst_data = 0;
1146
1147
1148 while (!buffer[i])
1149 i++;
1150 *from = i;
1151
1152 if (*from < 16) /* don't bother */
1153 *from = 0;
1154 /* keep going to make sure there isn't more real
1155 data in this record */
1156 while (i < RECORDSIZE)
1157 {
1158 if (!buffer[i])
1159 {
1160 if (amidst_data)
1161 {
1162 save_to = i;
1163 amidst_data = 0;
1164 }
1165 i++;
1166 }
1167 else if (buffer[i])
1168 {
1169 if (!amidst_data)
1170 amidst_data = 1;
1171 i++;
1172 }
1173 }
1174 if (i == RECORDSIZE)
1175 *to = i;
1176 else
1177 *to = save_to;
1178
1179 }
1180
1181 #endif
1182
1183 /* Note that this routine is only called if zero_record returned true */
1184 #if 0 /* But we actually don't need it at all. */
1185 where_is_data (from, to, buffer)
1186 int *from, *to;
1187 char *buffer;
1188 {
1189 char *fp, *tp;
1190
1191 for (fp = buffer; !*fp; fp++)
1192 ;
1193 for (tp = buffer + RECORDSIZE - 1; !*tp; tp--)
1194 ;
1195 *from = fp - buffer;
1196 *to = tp - buffer + 1;
1197 }
1198
1199 #endif
1200
1201
1202
1203 /*
1204 * Takes a recordful of data and basically cruises through it to see if
1205 * it's made *entirely* of zeros, returning a 0 the instant it finds
1206 * something that is a non-zero, i.e., useful data.
1207 */
1208 int
1209 zero_record (buffer)
1210 char *buffer;
1211 {
1212 register int i;
1213
1214 for (i = 0; i < RECORDSIZE; i++)
1215 if (buffer[i] != '\000')
1216 return 0;
1217 return 1;
1218 }
1219
1220 void
1221 find_new_file_size (filesize, highest_index)
1222 int *filesize;
1223 int highest_index;
1224 {
1225 register int i;
1226
1227 *filesize = 0;
1228 for (i = 0; sparsearray[i].numbytes && i <= highest_index; i++)
1229 *filesize += sparsearray[i].numbytes;
1230 }
1231
1232 /*
1233 * Make a header block for the file name whose stat info is st .
1234 * Return header pointer for success, NULL if the name is too long.
1235 */
1236 union record *
1237 start_header (name, st)
1238 char *name;
1239 register struct stat *st;
1240 {
1241 register union record *header;
1242
1243 if (strlen (name) >= NAMSIZ)
1244 write_long (name, LF_LONGNAME);
1245
1246 header = (union record *) findrec ();
1247 bzero (header->charptr, sizeof (*header)); /* XXX speed up */
1248
1249 /*
1250 * Check the file name and put it in the record.
1251 */
1252 if (!f_absolute_paths)
1253 {
1254 static int warned_once = 0;
1255 #ifdef __MSDOS__
1256 if (name[1] == ':')
1257 {
1258 name += 2;
1259 if (!warned_once++)
1260 msg ("Removing drive spec from names in the archive");
1261 }
1262 #endif
1263 while ('/' == *name)
1264 {
1265 name++; /* Force relative path */
1266 if (!warned_once++)
1267 msg ("Removing leading / from absolute path names in the archive.");
1268 }
1269 }
1270 current_file_name = name;
1271 strncpy (header->header.arch_name, name, NAMSIZ);
1272 header->header.arch_name[NAMSIZ - 1] = '\0';
1273
1274 to_oct ((long) (st->st_mode & 07777),
1275 8, header->header.mode);
1276 to_oct ((long) st->st_uid, 8, header->header.uid);
1277 to_oct ((long) st->st_gid, 8, header->header.gid);
1278 to_oct ((long) st->st_size, 1 + 12, header->header.size);
1279 to_oct ((long) st->st_mtime, 1 + 12, header->header.mtime);
1280 /* header->header.linkflag is left as null */
1281 if (f_gnudump)
1282 {
1283 to_oct ((long) st->st_atime, 1 + 12, header->header.atime);
1284 to_oct ((long) st->st_ctime, 1 + 12, header->header.ctime);
1285 }
1286
1287 #ifndef NONAMES
1288 /* Fill in new Unix Standard fields if desired. */
1289 if (f_standard)
1290 {
1291 header->header.linkflag = LF_NORMAL; /* New default */
1292 strcpy (header->header.magic, TMAGIC); /* Mark as Unix Std */
1293 finduname (header->header.uname, st->st_uid);
1294 findgname (header->header.gname, st->st_gid);
1295 }
1296 #endif
1297 return header;
1298 }
1299
1300 /*
1301 * Finish off a filled-in header block and write it out.
1302 * We also print the file name and/or full info if verbose is on.
1303 */
1304 void
1305 finish_header (header)
1306 register union record *header;
1307 {
1308 register int i, sum;
1309 register char *p;
1310
1311 bcopy (CHKBLANKS, header->header.chksum, sizeof (header->header.chksum));
1312
1313 sum = 0;
1314 p = header->charptr;
1315 for (i = sizeof (*header); --i >= 0;)
1316 {
1317 /*
1318 * We can't use unsigned char here because of old compilers,
1319 * e.g. V7.
1320 */
1321 sum += 0xFF & *p++;
1322 }
1323
1324 /*
1325 * Fill in the checksum field. It's formatted differently
1326 * from the other fields: it has [6] digits, a null, then a
1327 * space -- rather than digits, a space, then a null.
1328 * We use to_oct then write the null in over to_oct's space.
1329 * The final space is already there, from checksumming, and
1330 * to_oct doesn't modify it.
1331 *
1332 * This is a fast way to do:
1333 * (void) sprintf(header->header.chksum, "%6o", sum);
1334 */
1335 to_oct ((long) sum, 8, header->header.chksum);
1336 header->header.chksum[6] = '\0'; /* Zap the space */
1337
1338 userec (header);
1339
1340 if (f_verbose)
1341 {
1342 extern union record *head;/* Points to current tape header */
1343 extern int head_standard; /* Tape header is in ANSI format */
1344
1345 /* These globals are parameters to print_header, sigh */
1346 head = header;
1347 /* hstat is already set up */
1348 head_standard = f_standard;
1349 print_header ();
1350 }
1351
1352 return;
1353 }
1354
1355
1356 /*
1357 * Quick and dirty octal conversion.
1358 * Converts long "value" into a "digs"-digit field at "where",
1359 * including a trailing space and room for a null. "digs"==3 means
1360 * 1 digit, a space, and room for a null.
1361 *
1362 * We assume the trailing null is already there and don't fill it in.
1363 * This fact is used by start_header and finish_header, so don't change it!
1364 *
1365 * This should be equivalent to:
1366 * (void) sprintf(where, "%*lo ", digs-2, value);
1367 * except that sprintf fills in the trailing null and we don't.
1368 */
1369 void
1370 to_oct (value, digs, where)
1371 register long value;
1372 register int digs;
1373 register char *where;
1374 {
1375
1376 --digs; /* Trailing null slot is left alone */
1377 where[--digs] = ' '; /* Put in the space, though */
1378
1379 /* Produce the digits -- at least one */
1380 do
1381 {
1382 where[--digs] = '0' + (char) (value & 7); /* one octal digit */
1383 value >>= 3;
1384 }
1385 while (digs > 0 && value != 0);
1386
1387 /* Leading spaces, if necessary */
1388 while (digs > 0)
1389 where[--digs] = ' ';
1390
1391 }
1392
1393
1394 /*
1395 * Write the EOT record(s).
1396 * We actually zero at least one record, through the end of the block.
1397 * Old tar writes garbage after two zeroed records -- and PDtar used to.
1398 */
1399 void
1400 write_eot ()
1401 {
1402 union record *p;
1403 int bufsize;
1404
1405 p = findrec ();
1406 if (p)
1407 {
1408 bufsize = endofrecs ()->charptr - p->charptr;
1409 bzero (p->charptr, bufsize);
1410 userec (p);
1411 }
1412 }
1413
1414 /* Write a LF_LONGLINK or LF_LONGNAME record. */
1415 void
1416 write_long (p, type)
1417 char *p;
1418 char type;
1419 {
1420 int size = strlen (p) + 1;
1421 int bufsize;
1422 union record *header;
1423 struct stat foo;
1424
1425
1426 bzero (&foo, sizeof foo);
1427 foo.st_size = size;
1428
1429 header = start_header ("././@LongLink", &foo);
1430 header->header.linkflag = type;
1431 finish_header (header);
1432
1433 header = findrec ();
1434
1435 bufsize = endofrecs ()->charptr - header->charptr;
1436
1437 while (bufsize < size)
1438 {
1439 bcopy (p, header->charptr, bufsize);
1440 p += bufsize;
1441 size -= bufsize;
1442 userec (header + (bufsize - 1) / RECORDSIZE);
1443 header = findrec ();
1444 bufsize = endofrecs ()->charptr - header->charptr;
1445 }
1446 bcopy (p, header->charptr, size);
1447 bzero (header->charptr + size, bufsize - size);
1448 userec (header + (size - 1) / RECORDSIZE);
1449 }
This page took 0.091834 seconds and 5 git commands to generate.