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 815 by niro, Sat Sep 1 22:45:15 2007 UTC revision 816 by niro, Fri Apr 24 18:33:46 2009 UTC
# Line 6  Line 6 
6  #include "libbb.h"  #include "libbb.h"
7  #include "unarchive.h"  #include "unarchive.h"
8    
9  void data_extract_all(archive_handle_t *archive_handle)  void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
10  {  {
11   file_header_t *file_header = archive_handle->file_header;   file_header_t *file_header = archive_handle->file_header;
12   int dst_fd;   int dst_fd;
13   int res;   int res;
14    
15   if (archive_handle->flags & ARCHIVE_CREATE_LEADING_DIRS) {   if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) {
16   char *name = xstrdup(file_header->name);   char *name = xstrdup(file_header->name);
17   bb_make_directory(dirname(name), -1, FILEUTILS_RECUR);   bb_make_directory(dirname(name), -1, FILEUTILS_RECUR);
18   free(name);   free(name);
19   }   }
20    
21   /* Check if the file already exists */   /* Check if the file already exists */
22   if (archive_handle->flags & ARCHIVE_EXTRACT_UNCONDITIONAL) {   if (archive_handle->ah_flags & ARCHIVE_EXTRACT_UNCONDITIONAL) {
23   /* Remove the existing entry if it exists */   /* Remove the entry if it exists */
24   if (((file_header->mode & S_IFMT) != S_IFDIR)   if (((file_header->mode & S_IFMT) != S_IFDIR)
25   && (unlink(file_header->name) == -1)   && (unlink(file_header->name) == -1)
26   && (errno != ENOENT)   && (errno != ENOENT)
27   ) {   ) {
28   bb_perror_msg_and_die("cannot remove old file");   bb_perror_msg_and_die("cannot remove old file %s",
29     file_header->name);
30   }   }
31   }   }
32   else if (archive_handle->flags & ARCHIVE_EXTRACT_NEWER) {   else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) {
33   /* Remove the existing entry if its older than the extracted entry */   /* Remove the existing entry if its older than the extracted entry */
34   struct stat statbuf;   struct stat statbuf;
35   if (lstat(file_header->name, &statbuf) == -1) {   if (lstat(file_header->name, &statbuf) == -1) {
# Line 37  void data_extract_all(archive_handle_t * Line 38  void data_extract_all(archive_handle_t *
38   }   }
39   }   }
40   else if (statbuf.st_mtime <= file_header->mtime) {   else if (statbuf.st_mtime <= file_header->mtime) {
41   if (!(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) {   if (!(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
42   bb_error_msg("%s not created: newer or "   bb_error_msg("%s not created: newer or "
43   "same age file exists", file_header->name);   "same age file exists", file_header->name);
44   }   }
# Line 52  void data_extract_all(archive_handle_t * Line 53  void data_extract_all(archive_handle_t *
53    
54   /* Handle hard links separately   /* Handle hard links separately
55   * 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 */
56   if (S_ISREG(file_header->mode) && (file_header->link_name)   if (S_ISREG(file_header->mode) && (file_header->link_target)
57   && (file_header->size == 0)   && (file_header->size == 0)
58   ) {   ) {
59   /* hard link */   /* hard link */
60   res = link(file_header->link_name, file_header->name);   res = link(file_header->link_target, file_header->name);
61   if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) {   if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
62   bb_perror_msg("cannot create hard link");   bb_perror_msg("cannot create %slink "
63     "from %s to %s", "hard",
64     file_header->name,
65     file_header->link_target);
66   }   }
67   } else {   } else {
68   /* Create the filesystem entry */   /* Create the filesystem entry */
# Line 73  void data_extract_all(archive_handle_t * Line 77  void data_extract_all(archive_handle_t *
77   }   }
78   case S_IFDIR:   case S_IFDIR:
79   res = mkdir(file_header->name, file_header->mode);   res = mkdir(file_header->name, file_header->mode);
80   if ((errno != EISDIR) && (res == -1)   if ((res == -1)
81   && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)   && (errno != EISDIR) /* btw, Linux doesn't return this */
82     && (errno != EEXIST)
83     && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
84   ) {   ) {
85   bb_perror_msg("extract_archive: %s", file_header->name);   bb_perror_msg("cannot make dir %s", file_header->name);
86   }   }
87   break;   break;
88   case S_IFLNK:   case S_IFLNK:
89   /* Symlink */   /* Symlink */
90   res = symlink(file_header->link_name, file_header->name);   res = symlink(file_header->link_target, file_header->name);
91   if ((res == -1)   if ((res == -1)
92   && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)   && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
93   ) {   ) {
94   bb_perror_msg("cannot create symlink "   bb_perror_msg("cannot create %slink "
95   "from %s to '%s'",   "from %s to %s", "sym",
96   file_header->name,   file_header->name,
97   file_header->link_name);   file_header->link_target);
98   }   }
99   break;   break;
100   case S_IFSOCK:   case S_IFSOCK:
# Line 97  void data_extract_all(archive_handle_t * Line 103  void data_extract_all(archive_handle_t *
103   case S_IFIFO:   case S_IFIFO:
104   res = mknod(file_header->name, file_header->mode, file_header->device);   res = mknod(file_header->name, file_header->mode, file_header->device);
105   if ((res == -1)   if ((res == -1)
106   && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)   && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
107   ) {   ) {
108   bb_perror_msg("cannot create node %s", file_header->name);   bb_perror_msg("cannot create node %s", file_header->name);
109   }   }
# Line 107  void data_extract_all(archive_handle_t * Line 113  void data_extract_all(archive_handle_t *
113   }   }
114   }   }
115    
116   if (!(archive_handle->flags & ARCHIVE_NOPRESERVE_OWN)) {   if (!(archive_handle->ah_flags & ARCHIVE_NOPRESERVE_OWN)) {
117    #if ENABLE_FEATURE_TAR_UNAME_GNAME
118     uid_t uid = file_header->uid;
119     gid_t gid = file_header->gid;
120    
121     if (file_header->uname) {
122     struct passwd *pwd = getpwnam(file_header->uname);
123     if (pwd) uid = pwd->pw_uid;
124     }
125     if (file_header->gname) {
126     struct group *grp = getgrnam(file_header->gname);
127     if (grp) gid = grp->gr_gid;
128     }
129     lchown(file_header->name, uid, gid);
130    #else
131   lchown(file_header->name, file_header->uid, file_header->gid);   lchown(file_header->name, file_header->uid, file_header->gid);
132    #endif
133   }   }
134     if ((file_header->mode & S_IFMT) != S_IFLNK) {
135   if (archive_handle->flags & ARCHIVE_PRESERVE_DATE) {   /* uclibc has no lchmod, glibc is even stranger -
136   struct utimbuf t;   * it has lchmod which seems to do nothing!
137   t.actime = t.modtime = file_header->mtime;   * so we use chmod... */
138   utime(file_header->name, &t);   if (!(archive_handle->ah_flags & ARCHIVE_NOPRESERVE_PERM)) {
139     chmod(file_header->name, file_header->mode);
140     }
141     /* same for utime */
142     if (archive_handle->ah_flags & ARCHIVE_PRESERVE_DATE) {
143     struct utimbuf t;
144     t.actime = t.modtime = file_header->mtime;
145     utime(file_header->name, &t);
146     }
147   }   }
148  }  }

Legend:
Removed from v.815  
changed lines
  Added in v.816