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
);
161 int fsync_file(int fd
, int datasync
)
174 void close_file(void *stream
)
176 close(*((int *) stream
));
179 void close_dir(void *stream
)
184 int file_create(char *name
, int ur
, int uw
, int ux
, int gr
,
185 int gw
, int gx
, int or, int ow
, int ox
)
190 mode
|= ur
? S_IRUSR
: 0;
191 mode
|= uw
? S_IWUSR
: 0;
192 mode
|= ux
? S_IXUSR
: 0;
193 mode
|= gr
? S_IRGRP
: 0;
194 mode
|= gw
? S_IWGRP
: 0;
195 mode
|= gx
? S_IXGRP
: 0;
196 mode
|= or ? S_IROTH
: 0;
197 mode
|= ow
? S_IWOTH
: 0;
198 mode
|= ox
? S_IXOTH
: 0;
199 fd
= open64(name
, O_CREAT
| O_RDWR
, mode
);
205 int set_attr(const char *file
, struct hostfs_iattr
*attrs
)
210 if(attrs
->ia_valid
& HOSTFS_ATTR_MODE
){
211 if(chmod(file
, attrs
->ia_mode
) != 0) return(-errno
);
213 if(attrs
->ia_valid
& HOSTFS_ATTR_UID
){
214 if(chown(file
, attrs
->ia_uid
, -1)) return(-errno
);
216 if(attrs
->ia_valid
& HOSTFS_ATTR_GID
){
217 if(chown(file
, -1, attrs
->ia_gid
)) return(-errno
);
219 if(attrs
->ia_valid
& HOSTFS_ATTR_SIZE
){
220 if(truncate(file
, attrs
->ia_size
)) return(-errno
);
222 ma
= HOSTFS_ATTR_ATIME_SET
| HOSTFS_ATTR_MTIME_SET
;
223 if((attrs
->ia_valid
& ma
) == ma
){
224 buf
.actime
= attrs
->ia_atime
.tv_sec
;
225 buf
.modtime
= attrs
->ia_mtime
.tv_sec
;
226 if(utime(file
, &buf
) != 0) return(-errno
);
231 if(attrs
->ia_valid
& HOSTFS_ATTR_ATIME_SET
){
232 err
= stat_file(file
, NULL
, NULL
, NULL
, NULL
, NULL
,
233 NULL
, NULL
, &ts
, NULL
, NULL
, NULL
);
236 buf
.actime
= attrs
->ia_atime
.tv_sec
;
237 buf
.modtime
= ts
.tv_sec
;
238 if(utime(file
, &buf
) != 0)
241 if(attrs
->ia_valid
& HOSTFS_ATTR_MTIME_SET
){
242 err
= stat_file(file
, NULL
, NULL
, NULL
, NULL
, NULL
,
243 NULL
, &ts
, NULL
, NULL
, NULL
, NULL
);
246 buf
.actime
= ts
.tv_sec
;
247 buf
.modtime
= attrs
->ia_mtime
.tv_sec
;
248 if(utime(file
, &buf
) != 0)
252 if(attrs
->ia_valid
& HOSTFS_ATTR_CTIME
) ;
253 if(attrs
->ia_valid
& (HOSTFS_ATTR_ATIME
| HOSTFS_ATTR_MTIME
)){
254 err
= stat_file(file
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
255 &attrs
->ia_atime
, &attrs
->ia_mtime
, NULL
,
257 if(err
!= 0) return(err
);
262 int make_symlink(const char *from
, const char *to
)
266 err
= symlink(to
, from
);
267 if(err
) return(-errno
);
271 int unlink_file(const char *file
)
276 if(err
) return(-errno
);
280 int do_mkdir(const char *file
, int mode
)
284 err
= mkdir(file
, mode
);
285 if(err
) return(-errno
);
289 int do_rmdir(const char *file
)
294 if(err
) return(-errno
);
298 int do_mknod(const char *file
, int mode
, int dev
)
302 err
= mknod(file
, mode
, dev
);
303 if(err
) return(-errno
);
307 int link_file(const char *to
, const char *from
)
311 err
= link(to
, from
);
312 if(err
) return(-errno
);
316 int do_readlink(char *file
, char *buf
, int size
)
320 n
= readlink(file
, buf
, size
);
328 int rename_file(char *from
, char *to
)
332 err
= rename(from
, to
);
333 if(err
< 0) return(-errno
);
337 int do_statfs(char *root
, long *bsize_out
, long long *blocks_out
,
338 long long *bfree_out
, long long *bavail_out
,
339 long long *files_out
, long long *ffree_out
,
340 void *fsid_out
, int fsid_size
, long *namelen_out
,
346 err
= statfs64(root
, &buf
);
347 if(err
< 0) return(-errno
);
348 *bsize_out
= buf
.f_bsize
;
349 *blocks_out
= buf
.f_blocks
;
350 *bfree_out
= buf
.f_bfree
;
351 *bavail_out
= buf
.f_bavail
;
352 *files_out
= buf
.f_files
;
353 *ffree_out
= buf
.f_ffree
;
354 memcpy(fsid_out
, &buf
.f_fsid
,
355 sizeof(buf
.f_fsid
) > fsid_size
? fsid_size
:
357 *namelen_out
= buf
.f_namelen
;
358 spare_out
[0] = buf
.f_spare
[0];
359 spare_out
[1] = buf
.f_spare
[1];
360 spare_out
[2] = buf
.f_spare
[2];
361 spare_out
[3] = buf
.f_spare
[3];
362 spare_out
[4] = buf
.f_spare
[4];
363 spare_out
[5] = buf
.f_spare
[5];
368 * Overrides for Emacs so that we follow Linus's tabbing style.
369 * Emacs will notice this stuff at the end of the file and automatically
370 * adjust the settings for this buffer only. This must remain at the end
372 * ---------------------------------------------------------------------------
374 * c-file-style: "linux"