2 * Large portions of tar.c & extfs.c were nearly same. I killed this
3 * redundancy, so code is maintainable, again.
5 * Actually, tar no longer uses this code :-).
9 * Namespace: no pollution.
12 static char *get_path (char *inname
, struct archive
**archive
, int is_dir
,
15 char *buf
= g_strdup (inname
);
16 char *res
= get_path_mangle( buf
, archive
, is_dir
, do_not_open
);
25 __find_entry (struct entry
*dir
, char *name
,
26 struct loop_protect
*list
, int make_dirs
, int make_file
)
28 struct entry
*pent
, *pdir
;
29 char *p
, *q
, *name_end
;
32 if (*name
== '/') { /* Handle absolute paths */
34 dir
= dir
->inode
->archive
->root_entry
;
39 name_end
= name
+ strlen (name
);
45 for (; pent
!= NULL
&& c
&& *p
; ){
50 if (!strcmp (p
, ".."))
53 if ((pent
= __resolve_symlinks (pent
, list
))==NULL
){
57 if (c
== '/' && !S_ISDIR (pent
->inode
->mode
)){
63 for (pent
= pent
->inode
->first_in_subdir
; pent
; pent
= pent
->next_in_dir
)
64 /* Hack: I keep the original semanthic unless
65 q+1 would break in the strchr */
66 if (!strcmp (pent
->name
, p
)){
67 if (q
+ 1 > name_end
){
69 notadir
= !S_ISDIR (pent
->inode
->mode
);
75 /* When we load archive, we create automagically
76 * non-existant directories
78 if (pent
== NULL
&& make_dirs
) {
79 pent
= generate_entry (dir
->inode
->archive
, p
, pdir
, S_IFDIR
| 0777);
81 if (pent
== NULL
&& make_file
) {
82 pent
= generate_entry (dir
->inode
->archive
, p
, pdir
, 0777);
98 static struct entry
*find_entry (struct entry
*dir
, char *name
, int make_dirs
, int make_file
)
104 res
= __find_entry (dir
, name
, NULL
, make_dirs
, make_file
);
115 static int s_errno (vfs
*me
)
120 static void * s_opendir (vfs
*me
, char *dirname
)
122 struct archive
*archive
;
127 if ((q
= get_path_mangle (dirname
, &archive
, 1, 0)) == NULL
)
129 entry
= find_entry (archive
->root_entry
, q
, 0, 0);
132 if ((entry
= my_resolve_symlinks (entry
)) == NULL
)
134 if (!S_ISDIR (entry
->inode
->mode
)) ERRNOR (ENOTDIR
, NULL
);
136 info
= g_new (struct entry
*, 2);
137 info
[0] = entry
->inode
->first_in_subdir
;
138 info
[1] = entry
->inode
->first_in_subdir
;
143 static void * s_readdir (void *data
)
147 #ifdef NEED_EXTRA_DIRENT_BUFFER
148 char extra_buffer
[MC_MAXPATHLEN
];
152 struct entry
**info
= (struct entry
**) data
;
157 strcpy (&(dir
.dir
.d_name
[0]), (*info
)->name
);
159 #ifndef DIRENT_LENGTH_COMPUTED
160 dir
.d_namlen
= strlen (dir
.dir
.d_name
);
162 *info
= (*info
)->next_in_dir
;
167 static int s_telldir (void *data
)
169 struct entry
**info
= (struct entry
**) data
;
175 if (cur
== info
[0]) return num
;
177 cur
= cur
->next_in_dir
;
182 static void s_seekdir (void *data
, int offset
)
184 struct entry
**info
= (struct entry
**) data
;
187 for (i
=0; i
<offset
; i
++)
191 static int s_closedir (void *data
)
197 static void stat_move( struct stat
*buf
, struct inode
*inode
)
199 buf
->st_dev
= inode
->dev
;
200 buf
->st_ino
= inode
->inode
;
201 buf
->st_mode
= inode
->mode
;
202 buf
->st_nlink
= inode
->nlink
;
203 buf
->st_uid
= inode
->uid
;
204 buf
->st_gid
= inode
->gid
;
206 buf
->st_rdev
= inode
->rdev
;
208 buf
->st_size
= inode
->size
;
209 #ifdef HAVE_ST_BLKSIZE
210 buf
->st_blksize
= RECORDSIZE
;
212 #ifdef HAVE_ST_BLOCKS
213 buf
->st_blocks
= (inode
->size
+ RECORDSIZE
- 1) / RECORDSIZE
;
215 buf
->st_atime
= inode
->atime
;
216 buf
->st_mtime
= inode
->mtime
;
217 buf
->st_ctime
= inode
->ctime
;
220 static int s_internal_stat (char *path
, struct stat
*buf
, int resolve
)
222 struct archive
*archive
;
227 if ((q
= get_path_mangle (path
, &archive
, 0, 0)) == NULL
)
229 entry
= find_entry (archive
->root_entry
, q
, 0, 0);
232 if (resolve
&& (entry
= my_resolve_symlinks (entry
)) == NULL
)
234 inode
= entry
->inode
;
235 stat_move( buf
, inode
);
239 static int s_stat (vfs
*me
, char *path
, struct stat
*buf
)
241 return s_internal_stat (path
, buf
, 1);
244 static int s_lstat (vfs
*me
, char *path
, struct stat
*buf
)
246 return s_internal_stat (path
, buf
, 0);
249 static int s_fstat (void *data
, struct stat
*buf
)
251 struct pseudofile
*file
= (struct pseudofile
*)data
;
254 inode
= file
->entry
->inode
;
255 stat_move( buf
, inode
);
259 static int s_readlink (vfs
*me
, char *path
, char *buf
, int size
)
261 struct archive
*archive
;
266 if ((q
= get_path_mangle (path
, &archive
, 0, 0)) == NULL
)
268 entry
= find_entry (archive
->root_entry
, q
, 0, 0);
271 if (!S_ISLNK (entry
->inode
->mode
)) ERRNOR (EINVAL
, -1);
272 if (size
> (i
= strlen (entry
->inode
->linkname
))) {
275 strncpy (buf
, entry
->inode
->linkname
, i
);