2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
17 #include "kern_util.h"
20 int stat_file(const char *path
, unsigned long long *inode_out
, int *mode_out
,
21 int *nlink_out
, int *uid_out
, int *gid_out
,
22 unsigned long long *size_out
, struct timespec
*atime_out
,
23 struct timespec
*mtime_out
, struct timespec
*ctime_out
,
24 int *blksize_out
, unsigned long long *blocks_out
)
28 if(lstat64(path
, &buf
) < 0)
31 if(inode_out
!= NULL
) *inode_out
= buf
.st_ino
;
32 if(mode_out
!= NULL
) *mode_out
= buf
.st_mode
;
33 if(nlink_out
!= NULL
) *nlink_out
= buf
.st_nlink
;
34 if(uid_out
!= NULL
) *uid_out
= buf
.st_uid
;
35 if(gid_out
!= NULL
) *gid_out
= buf
.st_gid
;
36 if(size_out
!= NULL
) *size_out
= buf
.st_size
;
37 if(atime_out
!= NULL
) {
38 atime_out
->tv_sec
= buf
.st_atime
;
39 atime_out
->tv_nsec
= 0;
41 if(mtime_out
!= NULL
) {
42 mtime_out
->tv_sec
= buf
.st_mtime
;
43 mtime_out
->tv_nsec
= 0;
45 if(ctime_out
!= NULL
) {
46 ctime_out
->tv_sec
= buf
.st_ctime
;
47 ctime_out
->tv_nsec
= 0;
49 if(blksize_out
!= NULL
) *blksize_out
= buf
.st_blksize
;
50 if(blocks_out
!= NULL
) *blocks_out
= buf
.st_blocks
;
54 int file_type(const char *path
, int *maj
, int *min
)
58 if(lstat64(path
, &buf
) < 0)
60 /*We cannot pass rdev as is because glibc and the kernel disagree
61 *about its definition.*/
63 *maj
= major(buf
.st_rdev
);
65 *min
= minor(buf
.st_rdev
);
67 if(S_ISDIR(buf
.st_mode
)) return(OS_TYPE_DIR
);
68 else if(S_ISLNK(buf
.st_mode
)) return(OS_TYPE_SYMLINK
);
69 else if(S_ISCHR(buf
.st_mode
)) return(OS_TYPE_CHARDEV
);
70 else if(S_ISBLK(buf
.st_mode
)) return(OS_TYPE_BLOCKDEV
);
71 else if(S_ISFIFO(buf
.st_mode
))return(OS_TYPE_FIFO
);
72 else if(S_ISSOCK(buf
.st_mode
))return(OS_TYPE_SOCK
);
73 else return(OS_TYPE_FILE
);
76 int access_file(char *path
, int r
, int w
, int x
)
83 if(access(path
, mode
) != 0) return(-errno
);
87 int open_file(char *path
, int r
, int w
, int append
)
97 else panic("Impossible mode in open_file");
101 fd
= open64(path
, mode
);
102 if(fd
< 0) return(-errno
);
106 void *open_dir(char *path
, int *err_out
)
112 if(dir
== NULL
) return(NULL
);
116 char *read_dir(void *stream
, unsigned long long *pos
,
117 unsigned long long *ino_out
, int *len_out
)
124 if(ent
== NULL
) return(NULL
);
125 *len_out
= strlen(ent
->d_name
);
126 *ino_out
= ent
->d_ino
;
131 int read_file(int fd
, unsigned long long *offset
, char *buf
, int len
)
135 n
= pread64(fd
, buf
, len
, *offset
);
136 if(n
< 0) return(-errno
);
141 int write_file(int fd
, unsigned long long *offset
, const char *buf
, int len
)
145 n
= pwrite64(fd
, buf
, len
, *offset
);
146 if(n
< 0) return(-errno
);
151 int lseek_file(int fd
, long long offset
, int whence
)
155 ret
= lseek64(fd
, offset
, whence
);
156 if(ret
< 0) return(-errno
);
160 void close_file(void *stream
)
162 close(*((int *) stream
));
165 void close_dir(void *stream
)
170 int file_create(char *name
, int ur
, int uw
, int ux
, int gr
,
171 int gw
, int gx
, int or, int ow
, int ox
)
176 mode
|= ur
? S_IRUSR
: 0;
177 mode
|= uw
? S_IWUSR
: 0;
178 mode
|= ux
? S_IXUSR
: 0;
179 mode
|= gr
? S_IRGRP
: 0;
180 mode
|= gw
? S_IWGRP
: 0;
181 mode
|= gx
? S_IXGRP
: 0;
182 mode
|= or ? S_IROTH
: 0;
183 mode
|= ow
? S_IWOTH
: 0;
184 mode
|= ox
? S_IXOTH
: 0;
185 fd
= open64(name
, O_CREAT
| O_RDWR
, mode
);
191 int set_attr(const char *file
, struct hostfs_iattr
*attrs
)
196 if(attrs
->ia_valid
& HOSTFS_ATTR_MODE
){
197 if(chmod(file
, attrs
->ia_mode
) != 0) return(-errno
);
199 if(attrs
->ia_valid
& HOSTFS_ATTR_UID
){
200 if(chown(file
, attrs
->ia_uid
, -1)) return(-errno
);
202 if(attrs
->ia_valid
& HOSTFS_ATTR_GID
){
203 if(chown(file
, -1, attrs
->ia_gid
)) return(-errno
);
205 if(attrs
->ia_valid
& HOSTFS_ATTR_SIZE
){
206 if(truncate(file
, attrs
->ia_size
)) return(-errno
);
208 ma
= HOSTFS_ATTR_ATIME_SET
| HOSTFS_ATTR_MTIME_SET
;
209 if((attrs
->ia_valid
& ma
) == ma
){
210 buf
.actime
= attrs
->ia_atime
.tv_sec
;
211 buf
.modtime
= attrs
->ia_mtime
.tv_sec
;
212 if(utime(file
, &buf
) != 0) return(-errno
);
217 if(attrs
->ia_valid
& HOSTFS_ATTR_ATIME_SET
){
218 err
= stat_file(file
, NULL
, NULL
, NULL
, NULL
, NULL
,
219 NULL
, NULL
, &ts
, NULL
, NULL
, NULL
);
222 buf
.actime
= attrs
->ia_atime
.tv_sec
;
223 buf
.modtime
= ts
.tv_sec
;
224 if(utime(file
, &buf
) != 0)
227 if(attrs
->ia_valid
& HOSTFS_ATTR_MTIME_SET
){
228 err
= stat_file(file
, NULL
, NULL
, NULL
, NULL
, NULL
,
229 NULL
, &ts
, NULL
, NULL
, NULL
, NULL
);
232 buf
.actime
= ts
.tv_sec
;
233 buf
.modtime
= attrs
->ia_mtime
.tv_sec
;
234 if(utime(file
, &buf
) != 0)
238 if(attrs
->ia_valid
& HOSTFS_ATTR_CTIME
) ;
239 if(attrs
->ia_valid
& (HOSTFS_ATTR_ATIME
| HOSTFS_ATTR_MTIME
)){
240 err
= stat_file(file
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
241 &attrs
->ia_atime
, &attrs
->ia_mtime
, NULL
,
243 if(err
!= 0) return(err
);
248 int make_symlink(const char *from
, const char *to
)
252 err
= symlink(to
, from
);
253 if(err
) return(-errno
);
257 int unlink_file(const char *file
)
262 if(err
) return(-errno
);
266 int do_mkdir(const char *file
, int mode
)
270 err
= mkdir(file
, mode
);
271 if(err
) return(-errno
);
275 int do_rmdir(const char *file
)
280 if(err
) return(-errno
);
284 int do_mknod(const char *file
, int mode
, int dev
)
288 err
= mknod(file
, mode
, dev
);
289 if(err
) return(-errno
);
293 int link_file(const char *to
, const char *from
)
297 err
= link(to
, from
);
298 if(err
) return(-errno
);
302 int do_readlink(char *file
, char *buf
, int size
)
306 n
= readlink(file
, buf
, size
);
314 int rename_file(char *from
, char *to
)
318 err
= rename(from
, to
);
319 if(err
< 0) return(-errno
);
323 int do_statfs(char *root
, long *bsize_out
, long long *blocks_out
,
324 long long *bfree_out
, long long *bavail_out
,
325 long long *files_out
, long long *ffree_out
,
326 void *fsid_out
, int fsid_size
, long *namelen_out
,
332 err
= statfs64(root
, &buf
);
333 if(err
< 0) return(-errno
);
334 *bsize_out
= buf
.f_bsize
;
335 *blocks_out
= buf
.f_blocks
;
336 *bfree_out
= buf
.f_bfree
;
337 *bavail_out
= buf
.f_bavail
;
338 *files_out
= buf
.f_files
;
339 *ffree_out
= buf
.f_ffree
;
340 memcpy(fsid_out
, &buf
.f_fsid
,
341 sizeof(buf
.f_fsid
) > fsid_size
? fsid_size
:
343 *namelen_out
= buf
.f_namelen
;
344 spare_out
[0] = buf
.f_spare
[0];
345 spare_out
[1] = buf
.f_spare
[1];
346 spare_out
[2] = buf
.f_spare
[2];
347 spare_out
[3] = buf
.f_spare
[3];
348 spare_out
[4] = buf
.f_spare
[4];
349 spare_out
[5] = buf
.f_spare
[5];
354 * Overrides for Emacs so that we follow Linus's tabbing style.
355 * Emacs will notice this stuff at the end of the file and automatically
356 * adjust the settings for this buffer only. This must remain at the end
358 * ---------------------------------------------------------------------------
360 * c-file-style: "linux"