Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/archival/libunarchive/data_extract_all.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 13  void FAST_FUNC data_extract_all(archive_ Line 13  void FAST_FUNC data_extract_all(archive_
13   int res;   int res;
14    
15   if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) {   if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) {
16   char *name = xstrdup(file_header->name);   char *slash = strrchr(file_header->name, '/');
17   bb_make_directory(dirname(name), -1, FILEUTILS_RECUR);   if (slash) {
18   free(name);   *slash = '\0';
19     bb_make_directory(file_header->name, -1, FILEUTILS_RECUR);
20     *slash = '/';
21     }
22   }   }
23    
24   /* Check if the file already exists */   if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) {
  if (archive_handle->ah_flags & ARCHIVE_EXTRACT_UNCONDITIONAL) {  
25   /* Remove the entry if it exists */   /* Remove the entry if it exists */
26   if (((file_header->mode & S_IFMT) != S_IFDIR)   if ((!S_ISDIR(file_header->mode))
27   && (unlink(file_header->name) == -1)   && (unlink(file_header->name) == -1)
28   && (errno != ENOENT)   && (errno != ENOENT)
29   ) {   ) {
30   bb_perror_msg_and_die("cannot remove old file %s",   bb_perror_msg_and_die("can't remove old file %s",
31   file_header->name);   file_header->name);
32   }   }
33   }   }
34   else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) {   else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) {
35   /* Remove the existing entry if its older than the extracted entry */   /* Remove the existing entry if its older than the extracted entry */
36   struct stat statbuf;   struct stat existing_sb;
37   if (lstat(file_header->name, &statbuf) == -1) {   if (lstat(file_header->name, &existing_sb) == -1) {
38   if (errno != ENOENT) {   if (errno != ENOENT) {
39   bb_perror_msg_and_die("cannot stat old file");   bb_perror_msg_and_die("can't stat old file");
40   }   }
41   }   }
42   else if (statbuf.st_mtime <= file_header->mtime) {   else if (existing_sb.st_mtime >= file_header->mtime) {
43   if (!(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {   if (!(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
44   bb_error_msg("%s not created: newer or "   bb_error_msg("%s not created: newer or "
45   "same age file exists", file_header->name);   "same age file exists", file_header->name);
# Line 46  void FAST_FUNC data_extract_all(archive_ Line 48  void FAST_FUNC data_extract_all(archive_
48   return;   return;
49   }   }
50   else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) {   else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) {
51   bb_perror_msg_and_die("cannot remove old file %s",   bb_perror_msg_and_die("can't remove old file %s",
52   file_header->name);   file_header->name);
53   }   }
54   }   }
55    
56   /* Handle hard links separately   /* Handle hard links separately
57   * We identified hard links as regular files of size 0 with a symlink */   * We identified hard links as regular files of size 0 with a symlink */
58   if (S_ISREG(file_header->mode) && (file_header->link_target)   if (S_ISREG(file_header->mode)
59   && (file_header->size == 0)   && file_header->link_target
60     && file_header->size == 0
61   ) {   ) {
62   /* hard link */   /* hard link */
63   res = link(file_header->link_target, file_header->name);   res = link(file_header->link_target, file_header->name);
64   if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {   if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
65   bb_perror_msg("cannot create %slink "   bb_perror_msg("can't create %slink "
66   "from %s to %s", "hard",   "from %s to %s", "hard",
67   file_header->name,   file_header->name,
68   file_header->link_target);   file_header->link_target);
# Line 69  void FAST_FUNC data_extract_all(archive_ Line 72  void FAST_FUNC data_extract_all(archive_
72   switch (file_header->mode & S_IFMT) {   switch (file_header->mode & S_IFMT) {
73   case S_IFREG: {   case S_IFREG: {
74   /* Regular file */   /* Regular file */
75   dst_fd = xopen3(file_header->name, O_WRONLY | O_CREAT | O_EXCL,   int flags = O_WRONLY | O_CREAT | O_EXCL;
76   file_header->mode);   if (archive_handle->ah_flags & ARCHIVE_O_TRUNC)
77     flags = O_WRONLY | O_CREAT | O_TRUNC;
78     dst_fd = xopen3(file_header->name,
79     flags,
80     file_header->mode
81     );
82   bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size);   bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size);
83   close(dst_fd);   close(dst_fd);
84   break;   break;
# Line 82  void FAST_FUNC data_extract_all(archive_ Line 90  void FAST_FUNC data_extract_all(archive_
90   && (errno != EEXIST)   && (errno != EEXIST)
91   && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)   && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
92   ) {   ) {
93   bb_perror_msg("cannot make dir %s", file_header->name);   bb_perror_msg("can't make dir %s", file_header->name);
94   }   }
95   break;   break;
96   case S_IFLNK:   case S_IFLNK:
# Line 91  void FAST_FUNC data_extract_all(archive_ Line 99  void FAST_FUNC data_extract_all(archive_
99   if ((res == -1)   if ((res == -1)
100   && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)   && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
101   ) {   ) {
102   bb_perror_msg("cannot create %slink "   bb_perror_msg("can't create %slink "
103   "from %s to %s", "sym",   "from %s to %s", "sym",
104   file_header->name,   file_header->name,
105   file_header->link_target);   file_header->link_target);
# Line 105  void FAST_FUNC data_extract_all(archive_ Line 113  void FAST_FUNC data_extract_all(archive_
113   if ((res == -1)   if ((res == -1)
114   && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)   && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
115   ) {   ) {
116   bb_perror_msg("cannot create node %s", file_header->name);   bb_perror_msg("can't create node %s", file_header->name);
117   }   }
118   break;   break;
119   default:   default:
# Line 113  void FAST_FUNC data_extract_all(archive_ Line 121  void FAST_FUNC data_extract_all(archive_
121   }   }
122   }   }
123    
124   if (!(archive_handle->ah_flags & ARCHIVE_NOPRESERVE_OWN)) {   if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_OWNER)) {
125  #if ENABLE_FEATURE_TAR_UNAME_GNAME  #if ENABLE_FEATURE_TAR_UNAME_GNAME
126   uid_t uid = file_header->uid;   if (!(archive_handle->ah_flags & ARCHIVE_NUMERIC_OWNER)) {
127   gid_t gid = file_header->gid;   uid_t uid = file_header->uid;
128     gid_t gid = file_header->gid;
129    
130   if (file_header->uname) {   if (file_header->tar__uname) {
131   struct passwd *pwd = getpwnam(file_header->uname);  //TODO: cache last name/id pair?
132   if (pwd) uid = pwd->pw_uid;   struct passwd *pwd = getpwnam(file_header->tar__uname);
133   }   if (pwd) uid = pwd->pw_uid;
134   if (file_header->gname) {   }
135   struct group *grp = getgrnam(file_header->gname);   if (file_header->tar__gname) {
136   if (grp) gid = grp->gr_gid;   struct group *grp = getgrnam(file_header->tar__gname);
137   }   if (grp) gid = grp->gr_gid;
138   lchown(file_header->name, uid, gid);   }
139  #else   /* GNU tar 1.15.1 uses chown, not lchown */
140   lchown(file_header->name, file_header->uid, file_header->gid);   chown(file_header->name, uid, gid);
141     } else
142  #endif  #endif
143     chown(file_header->name, file_header->uid, file_header->gid);
144   }   }
145   if ((file_header->mode & S_IFMT) != S_IFLNK) {   if (!S_ISLNK(file_header->mode)) {
146   /* uclibc has no lchmod, glibc is even stranger -   /* uclibc has no lchmod, glibc is even stranger -
147   * it has lchmod which seems to do nothing!   * it has lchmod which seems to do nothing!
148   * so we use chmod... */   * so we use chmod... */
149   if (!(archive_handle->ah_flags & ARCHIVE_NOPRESERVE_PERM)) {   if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) {
150   chmod(file_header->name, file_header->mode);   chmod(file_header->name, file_header->mode);
151   }   }
152   /* same for utime */   /* same for utime */
153   if (archive_handle->ah_flags & ARCHIVE_PRESERVE_DATE) {   if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) {
154   struct utimbuf t;   struct timeval t[2];
155   t.actime = t.modtime = file_header->mtime;  
156   utime(file_header->name, &t);   t[1].tv_sec = t[0].tv_sec = file_header->mtime;
157     t[1].tv_usec = t[0].tv_usec = 0;
158     utimes(file_header->name, t);
159   }   }
160   }   }
161  }  }

Legend:
Removed from v.983  
changed lines
  Added in v.984