fix packman sort col, and make sort case-insensitive
[minix3.git] / servers / vfs / stadir.c
blob544a315c8231e753e92d9740a02c9a176a6c2f0b
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_stat: perform the STAT system call
8 * do_fstat: perform the FSTAT system call
9 * do_fstatfs: perform the FSTATFS system call
10 * do_lstat: perform the LSTAT system call
12 * Changes for VFS:
13 * Jul 2006 (Balazs Gerofi)
16 #include "fs.h"
17 #include <sys/stat.h>
18 #include <sys/statfs.h>
19 #include <minix/com.h>
20 #include <minix/u64.h>
21 #include <string.h>
22 #include "file.h"
23 #include "fproc.h"
24 #include "param.h"
26 #include <minix/vfsif.h>
27 #include "vnode.h"
28 #include "vmnt.h"
30 FORWARD _PROTOTYPE( int change, (struct vnode **iip, char *name_ptr, int len));
31 FORWARD _PROTOTYPE( int change_into, (struct vnode **iip, struct vnode *vp));
33 /*===========================================================================*
34 * do_fchdir *
35 *===========================================================================*/
36 PUBLIC int do_fchdir()
38 /* Change directory on already-opened fd. */
39 struct filp *rfilp;
40 int r;
42 /* Is the file descriptor valid? */
43 if ( (rfilp = get_filp(m_in.fd)) == NIL_FILP) return(err_code);
45 /* Is it a dir? */
46 if ((rfilp->filp_vno->v_mode & I_TYPE) != I_DIRECTORY)
47 return ENOTDIR;
49 /* Issue request and handle error */
50 r = forbidden(rfilp->filp_vno, X_BIT);
51 if (r != OK) return r;
53 rfilp->filp_vno->v_ref_count++; /* change_into expects a reference */
55 return change_into(&fp->fp_wd, rfilp->filp_vno);
58 /*===========================================================================*
59 * do_chdir *
60 *===========================================================================*/
61 PUBLIC int do_chdir()
63 /* Change directory. This function is also called by MM to simulate a chdir
64 * in order to do EXEC, etc. It also changes the root directory, the uids and
65 * gids, and the umask.
67 int r;
68 register struct fproc *rfp;
70 if (who_e == PM_PROC_NR) {
71 int slot;
72 if(isokendpt(m_in.endpt1, &slot) != OK)
73 return EINVAL;
74 rfp = &fproc[slot];
76 put_vnode(fp->fp_rd);
77 dup_vnode(fp->fp_rd = rfp->fp_rd);
78 put_vnode(fp->fp_wd);
79 dup_vnode(fp->fp_wd = rfp->fp_wd);
81 /* MM uses access() to check permissions. To make this work, pretend
82 * that the user's real ids are the same as the user's effective ids.
83 * FS calls other than access() do not use the real ids, so are not
84 * affected.
86 fp->fp_realuid =
87 fp->fp_effuid = rfp->fp_effuid;
88 fp->fp_realgid =
89 fp->fp_effgid = rfp->fp_effgid;
90 fp->fp_umask = rfp->fp_umask;
91 return(OK);
94 /* Perform the chdir(name) system call. */
95 r = change(&fp->fp_wd, m_in.name, m_in.name_length);
96 return(r);
99 /*===========================================================================*
100 * do_chroot *
101 *===========================================================================*/
102 PUBLIC int do_chroot()
104 /* Perform the chroot(name) system call. */
106 register int r;
108 if (!super_user) return(EPERM); /* only su may chroot() */
110 r = change(&fp->fp_rd, m_in.name, m_in.name_length);
111 return(r);
115 /*===========================================================================*
116 * change *
117 *===========================================================================*/
118 PRIVATE int change(iip, name_ptr, len)
119 struct vnode **iip; /* pointer to the inode pointer for the dir */
120 char *name_ptr; /* pointer to the directory name to change to */
121 int len; /* length of the directory name string */
123 /* Do the actual work for chdir() and chroot(). */
124 struct vnode *vp;
125 struct lookup_req lookup_req;
126 int r;
128 if (fetch_name(name_ptr, len, M3) != OK) return(err_code);
130 /* Fill in lookup request fields */
131 lookup_req.path = user_fullpath;
132 lookup_req.lastc = NULL;
133 lookup_req.flags = EAT_PATH;
135 /* Request lookup */
136 if ((r = lookup_vp(&lookup_req, &vp)) != OK) return r;
138 /* Is it a dir? */
139 if ((vp->v_mode & I_TYPE) != I_DIRECTORY)
141 put_vnode(vp);
142 return ENOTDIR;
145 /* Access check */
146 r = forbidden(vp, X_BIT);
147 if (r != OK) {
148 put_vnode(vp);
149 return r;
152 return change_into(iip, vp);
156 /*===========================================================================*
157 * change_into *
158 *===========================================================================*/
159 PRIVATE int change_into(iip, vp)
160 struct vnode **iip; /* pointer to the inode pointer for the dir */
161 struct vnode *vp; /* this is what the inode has to become */
163 /* Everything is OK. Make the change. */
164 put_vnode(*iip); /* release the old directory */
165 *iip = vp; /* acquire the new one */
167 return(OK);
171 /*===========================================================================*
172 * do_stat *
173 *===========================================================================*/
174 PUBLIC int do_stat()
176 /* Perform the stat(name, buf) system call. */
177 struct node_details res;
178 struct lookup_req lookup_req;
179 int r;
181 if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
183 /* Fill in lookup request fields */
184 lookup_req.path = user_fullpath;
185 lookup_req.lastc = NULL;
186 lookup_req.flags = EAT_PATH;
188 /* Request lookup */
189 if ((r = lookup(&lookup_req, &res)) != OK) return r;
191 /* Issue request */
192 return req_stat(res.fs_e, res.inode_nr, who_e, m_in.name2, 0);
197 /*===========================================================================*
198 * do_fstat *
199 *===========================================================================*/
200 PUBLIC int do_fstat()
202 /* Perform the fstat(fd, buf) system call. */
203 register struct filp *rfilp;
204 int pipe_pos = 0;
206 /* Is the file descriptor valid? */
207 if ( (rfilp = get_filp(m_in.fd)) == NIL_FILP) {
208 return(err_code);
211 /* If we read from a pipe, send position too */
212 pipe_pos= 0;
213 if (rfilp->filp_vno->v_pipe == I_PIPE) {
214 if (rfilp->filp_mode & R_BIT)
215 if (ex64hi(rfilp->filp_pos) != 0)
217 panic(__FILE__, "do_fstat: bad position in pipe",
218 NO_NUM);
220 pipe_pos = ex64lo(rfilp->filp_pos);
223 /* Issue request */
224 return req_stat(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr,
225 who_e, m_in.buffer, pipe_pos);
230 /*===========================================================================*
231 * do_fstatfs *
232 *===========================================================================*/
233 PUBLIC int do_fstatfs()
235 /* Perform the fstatfs(fd, buf) system call. */
236 register struct filp *rfilp;
238 /* Is the file descriptor valid? */
239 if ( (rfilp = get_filp(m_in.fd)) == NIL_FILP) return(err_code);
241 /* Issue request */
242 return req_fstatfs(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr,
243 who_e, m_in.buffer);
248 /*===========================================================================*
249 * do_lstat *
250 *===========================================================================*/
251 PUBLIC int do_lstat()
253 /* Perform the lstat(name, buf) system call. */
254 struct node_details res;
255 struct lookup_req lookup_req;
256 int r;
258 if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
260 /* Fill in lookup request fields */
261 lookup_req.path = user_fullpath;
262 lookup_req.lastc = NULL;
263 lookup_req.flags = EAT_PATH_OPAQUE;
265 /* Request lookup */
266 if ((r = lookup(&lookup_req, &res)) != OK) return r;
268 /* Issue request */
269 return req_stat(res.fs_e, res.inode_nr, who_e, m_in.name2, 0);