1 /* This file contains the code for performing four system calls relating to
2 * status and directories.
4 * The entry points into this file are
5 * do_chdir: perform the CHDIR system call
6 * do_chroot: perform the CHROOT system call
7 * do_lstat: perform the LSTAT system call
8 * do_stat: perform the STAT system call
9 * do_fstat: perform the FSTAT system call
10 * do_fstatfs: perform the FSTATFS system call
11 * do_statvfs: perform the STATVFS system call
12 * do_fstatvfs: perform the FSTATVFS system call
17 #include <sys/statfs.h>
18 #include <minix/com.h>
19 #include <minix/u64.h>
25 #include <minix/vfsif.h>
26 #include <minix/callnr.h>
30 static int change_into(struct vnode
**iip
, struct vnode
*vp
);
32 /*===========================================================================*
34 *===========================================================================*/
37 /* Change directory on already-opened fd. */
43 /* Is the file descriptor valid? */
44 if ((rfilp
= get_filp(rfd
, VNODE_READ
)) == NULL
) return(err_code
);
45 r
= change_into(&fp
->fp_wd
, rfilp
->filp_vno
);
50 /*===========================================================================*
52 *===========================================================================*/
55 /* Perform the chdir(name) system call.
56 * syscall might provide 'name' embedded in the message.
62 char fullpath
[PATH_MAX
];
63 struct lookup resolve
;
67 vname
= (vir_bytes
) job_m_in
.name
;
68 vname_length
= (size_t) job_m_in
.name_length
;
70 if (copy_name(vname_length
, fullpath
) != OK
) {
71 /* Direct copy failed, try fetching from user space */
72 if (fetch_name(vname
, vname_length
, fullpath
) != OK
)
76 /* Try to open the directory */
77 lookup_init(&resolve
, fullpath
, PATH_NOFLAGS
, &vmp
, &vp
);
78 resolve
.l_vmnt_lock
= VMNT_READ
;
79 resolve
.l_vnode_lock
= VNODE_READ
;
80 if ((vp
= eat_path(&resolve
, fp
)) == NULL
) return(err_code
);
82 r
= change_into(&fp
->fp_wd
, vp
);
91 /*===========================================================================*
93 *===========================================================================*/
96 /* Perform the chroot(name) system call.
97 * syscall might provide 'name' embedded in the message.
102 char fullpath
[PATH_MAX
];
103 struct lookup resolve
;
107 vname
= (vir_bytes
) job_m_in
.name
;
108 vname_length
= (size_t) job_m_in
.name_length
;
110 if (!super_user
) return(EPERM
); /* only su may chroot() */
112 if (copy_name(vname_length
, fullpath
) != OK
) {
113 /* Direct copy failed, try fetching from user space */
114 if (fetch_name(vname
, vname_length
, fullpath
) != OK
)
118 /* Try to open the directory */
119 lookup_init(&resolve
, fullpath
, PATH_NOFLAGS
, &vmp
, &vp
);
120 resolve
.l_vmnt_lock
= VMNT_READ
;
121 resolve
.l_vnode_lock
= VNODE_READ
;
122 if ((vp
= eat_path(&resolve
, fp
)) == NULL
) return(err_code
);
124 r
= change_into(&fp
->fp_rd
, vp
);
133 /*===========================================================================*
135 *===========================================================================*/
136 static int change_into(struct vnode
**result
, struct vnode
*vp
)
140 if (*result
== vp
) return(OK
); /* Nothing to do */
142 /* It must be a directory and also be searchable */
143 if (!S_ISDIR(vp
->v_mode
))
146 r
= forbidden(fp
, vp
, X_BIT
); /* Check if dir is searchable*/
147 if (r
!= OK
) return(r
);
149 /* Everything is OK. Make the change. */
150 put_vnode(*result
); /* release the old directory */
152 *result
= vp
; /* acquire the new one */
156 /*===========================================================================*
158 *===========================================================================*/
161 /* Perform the stat(name, buf) system call. */
165 char fullpath
[PATH_MAX
];
166 struct lookup resolve
;
168 vir_bytes vname1
, statbuf
;
169 size_t vname1_length
;
171 vname1
= (vir_bytes
) job_m_in
.name1
;
172 vname1_length
= (size_t) job_m_in
.name1_length
;
173 statbuf
= (vir_bytes
) job_m_in
.m1_p2
;
175 lookup_init(&resolve
, fullpath
, PATH_NOFLAGS
, &vmp
, &vp
);
176 resolve
.l_vmnt_lock
= VMNT_READ
;
177 resolve
.l_vnode_lock
= VNODE_READ
;
179 if (job_call_nr
== PREV_STAT
)
182 if (fetch_name(vname1
, vname1_length
, fullpath
) != OK
) return(err_code
);
183 if ((vp
= eat_path(&resolve
, fp
)) == NULL
) return(err_code
);
184 r
= req_stat(vp
->v_fs_e
, vp
->v_inode_nr
, who_e
, statbuf
, old_stat
);
193 /*===========================================================================*
195 *===========================================================================*/
198 /* Perform the fstat(fd, buf) system call. */
199 register struct filp
*rfilp
;
200 int r
, old_stat
= 0, rfd
;
203 statbuf
= (vir_bytes
) job_m_in
.buffer
;
206 if (job_call_nr
== PREV_FSTAT
)
209 /* Is the file descriptor valid? */
210 if ((rfilp
= get_filp(rfd
, VNODE_READ
)) == NULL
) return(err_code
);
212 r
= req_stat(rfilp
->filp_vno
->v_fs_e
, rfilp
->filp_vno
->v_inode_nr
,
213 who_e
, statbuf
, old_stat
);
220 /*===========================================================================*
222 *===========================================================================*/
225 /* Perform the fstatfs(fd, buf) system call. */
231 statbuf
= (vir_bytes
) job_m_in
.buffer
;
233 /* Is the file descriptor valid? */
234 if( (rfilp
= get_filp(rfd
, VNODE_READ
)) == NULL
) return(err_code
);
236 r
= req_fstatfs(rfilp
->filp_vno
->v_fs_e
, who_e
, statbuf
);
243 /*===========================================================================*
245 *===========================================================================*/
248 /* Perform the stat(name, buf) system call. */
252 char fullpath
[PATH_MAX
];
253 struct lookup resolve
;
254 vir_bytes vname1
, statbuf
;
255 size_t vname1_length
;
257 vname1
= (vir_bytes
) job_m_in
.name1
;
258 vname1_length
= (size_t) job_m_in
.name1_length
;
259 statbuf
= (vir_bytes
) job_m_in
.name2
;
261 lookup_init(&resolve
, fullpath
, PATH_NOFLAGS
, &vmp
, &vp
);
262 resolve
.l_vmnt_lock
= VMNT_READ
;
263 resolve
.l_vnode_lock
= VNODE_READ
;
265 if (fetch_name(vname1
, vname1_length
, fullpath
) != OK
) return(err_code
);
266 if ((vp
= eat_path(&resolve
, fp
)) == NULL
) return(err_code
);
267 r
= req_statvfs(vp
->v_fs_e
, who_e
, statbuf
);
276 /*===========================================================================*
278 *===========================================================================*/
281 /* Perform the fstat(fd, buf) system call. */
282 register struct filp
*rfilp
;
287 statbuf
= (vir_bytes
) job_m_in
.name2
;
289 /* Is the file descriptor valid? */
290 if ((rfilp
= get_filp(rfd
, VNODE_READ
)) == NULL
) return(err_code
);
291 r
= req_statvfs(rfilp
->filp_vno
->v_fs_e
, who_e
, statbuf
);
298 /*===========================================================================*
300 *===========================================================================*/
303 /* Perform the lstat(name, buf) system call. */
307 char fullpath
[PATH_MAX
];
308 struct lookup resolve
;
310 vir_bytes vname1
, statbuf
;
311 size_t vname1_length
;
313 vname1
= (vir_bytes
) job_m_in
.name1
;
314 vname1_length
= (size_t) job_m_in
.name1_length
;
315 statbuf
= (vir_bytes
) job_m_in
.name2
;
317 lookup_init(&resolve
, fullpath
, PATH_RET_SYMLINK
, &vmp
, &vp
);
318 resolve
.l_vmnt_lock
= VMNT_READ
;
319 resolve
.l_vnode_lock
= VNODE_READ
;
321 if (job_call_nr
== PREV_LSTAT
)
323 if (fetch_name(vname1
, vname1_length
, fullpath
) != OK
) return(err_code
);
324 if ((vp
= eat_path(&resolve
, fp
)) == NULL
) return(err_code
);
325 r
= req_stat(vp
->v_fs_e
, vp
->v_inode_nr
, who_e
, statbuf
, old_stat
);