1 /* Created (MFS based):
2 * June 2011 (Evgeniy Ivanov)
10 #include <minix/vfsif.h>
13 #include "puffs_priv.h"
16 /*===========================================================================*
18 *===========================================================================*/
22 struct puffs_node
*pn_dir
;
23 struct puffs_node
*pn
;
25 struct puffs_newinfo pni
;
26 struct puffs_kcn pkcnp
;
27 PUFFS_MAKECRED(pcr
, &global_kcred
);
28 struct puffs_cn pcn
= {&pkcnp
, (struct puffs_cred
*) __UNCONST(pcr
), {0,0,0}};
33 if (global_pu
->pu_ops
.puffs_node_create
== NULL
) {
34 lpuffs_debug("No puffs_node_create");
38 /* Read request message */
39 omode
= (mode_t
) fs_m_in
.REQ_MODE
;
40 caller_uid
= (uid_t
) fs_m_in
.REQ_UID
;
41 caller_gid
= (gid_t
) fs_m_in
.REQ_GID
;
43 /* Copy the last component (i.e., file name) */
44 len
= fs_m_in
.REQ_PATH_LEN
;
45 pcn
.pcn_namelen
= len
- 1;
46 if (pcn
.pcn_namelen
> NAME_MAX
)
49 err_code
= sys_safecopyfrom(VFS_PROC_NR
, (cp_grant_id_t
) fs_m_in
.REQ_GRANT
,
50 (vir_bytes
) 0, (vir_bytes
) pcn
.pcn_name
,
52 if (err_code
!= OK
) return(err_code
);
53 NUL(pcn
.pcn_name
, len
, sizeof(pcn
.pcn_name
));
55 /* Get last directory pnode (i.e., directory that will hold the new pnode) */
56 if ((pn_dir
= puffs_pn_nodewalk(global_pu
, 0, &fs_m_in
.REQ_INODE_NR
)) == NULL
)
59 memset(&pni
, 0, sizeof(pni
));
60 pni
.pni_cookie
= (void** )&pn
;
62 cur_time
= clock_time();
64 memset(&va
, 0, sizeof(va
));
67 va
.va_uid
= caller_uid
;
68 va
.va_gid
= caller_gid
;
69 va
.va_atime
.tv_sec
= va
.va_mtime
.tv_sec
= va
.va_ctime
.tv_sec
= cur_time
;
72 r
= puffs_path_pcnbuild(global_pu
, &pcn
, pn_dir
);
74 lpuffs_debug("pathbuild error\n");
79 r
= global_pu
->pu_ops
.puffs_node_create(global_pu
, pn_dir
, &pni
, &pcn
, &va
);
82 global_pu
->pu_pathfree(global_pu
, &pcn
.pcn_po_full
);
84 struct puffs_node
*_pn
;
86 _pn
= PU_CMAP(global_pu
, pn
);
87 _pn
->pn_po
= pcn
.pcn_po_full
;
99 update_times(pn_dir
, MTIME
| CTIME
, cur_time
);
102 fs_m_out
.RES_INODE_NR
= pn
->pn_va
.va_fileid
;
103 fs_m_out
.RES_MODE
= pn
->pn_va
.va_mode
;
104 fs_m_out
.RES_FILE_SIZE_LO
= pn
->pn_va
.va_size
;
106 /* This values are needed for the execution */
107 fs_m_out
.RES_UID
= pn
->pn_va
.va_uid
;
108 fs_m_out
.RES_GID
= pn
->pn_va
.va_gid
;
114 /*===========================================================================*
116 *===========================================================================*/
120 struct puffs_node
*pn_dir
;
121 struct puffs_node
*pn
;
122 struct puffs_newinfo pni
;
123 struct puffs_kcn pkcnp
;
124 PUFFS_MAKECRED(pcr
, &global_kcred
);
125 struct puffs_cn pcn
= {&pkcnp
, (struct puffs_cred
*) __UNCONST(pcr
), {0,0,0}};
130 if (global_pu
->pu_ops
.puffs_node_mknod
== NULL
) {
131 lpuffs_debug("No puffs_node_mknod");
135 /* Copy the last component and set up caller's user and group id */
136 len
= fs_m_in
.REQ_PATH_LEN
;
137 pcn
.pcn_namelen
= len
- 1;
138 if (pcn
.pcn_namelen
> NAME_MAX
)
139 return(ENAMETOOLONG
);
141 err_code
= sys_safecopyfrom(VFS_PROC_NR
, (cp_grant_id_t
) fs_m_in
.REQ_GRANT
,
142 (vir_bytes
) 0, (vir_bytes
) pcn
.pcn_name
,
144 if (err_code
!= OK
) return(err_code
);
145 NUL(pcn
.pcn_name
, len
, sizeof(pcn
.pcn_name
));
147 caller_uid
= (uid_t
) fs_m_in
.REQ_UID
;
148 caller_gid
= (gid_t
) fs_m_in
.REQ_GID
;
150 /* Get last directory pnode */
151 if ((pn_dir
= puffs_pn_nodewalk(global_pu
, 0, &fs_m_in
.REQ_INODE_NR
)) == NULL
)
154 memset(&pni
, 0, sizeof(pni
));
155 pni
.pni_cookie
= (void** )&pn
;
157 cur_time
= clock_time();
159 memset(&va
, 0, sizeof(va
));
161 va
.va_mode
= (mode_t
) fs_m_in
.REQ_MODE
;
162 va
.va_uid
= caller_uid
;
163 va
.va_gid
= caller_gid
;
164 va
.va_rdev
= (dev_t
) fs_m_in
.REQ_DEV
;
165 va
.va_atime
.tv_sec
= va
.va_mtime
.tv_sec
= va
.va_ctime
.tv_sec
= cur_time
;
168 if (puffs_path_pcnbuild(global_pu
, &pcn
, pn_dir
) != 0) {
169 lpuffs_debug("pathbuild error\n");
174 r
= global_pu
->pu_ops
.puffs_node_mknod(global_pu
, pn_dir
, &pni
, &pcn
, &va
);
177 global_pu
->pu_pathfree(global_pu
, &pcn
.pcn_po_full
);
179 struct puffs_node
*_pn
;
181 _pn
= PU_CMAP(global_pu
, pn
);
182 _pn
->pn_po
= pcn
.pcn_po_full
;
191 update_times(pn_dir
, MTIME
| CTIME
, cur_time
);
197 /*===========================================================================*
199 *===========================================================================*/
203 struct puffs_node
*pn_dir
;
204 struct puffs_node
*pn
;
205 struct puffs_newinfo pni
;
206 struct puffs_kcn pkcnp
;
207 PUFFS_MAKECRED(pcr
, &global_kcred
);
208 struct puffs_cn pcn
= {&pkcnp
, (struct puffs_cred
*) __UNCONST(pcr
), {0,0,0}};
213 if (global_pu
->pu_ops
.puffs_node_mkdir
== NULL
) {
214 lpuffs_debug("No puffs_node_mkdir");
218 /* Copy the last component and set up caller's user and group id */
219 len
= fs_m_in
.REQ_PATH_LEN
;
220 pcn
.pcn_namelen
= len
- 1;
221 if (pcn
.pcn_namelen
> NAME_MAX
)
222 return(ENAMETOOLONG
);
224 err_code
= sys_safecopyfrom(VFS_PROC_NR
, (cp_grant_id_t
) fs_m_in
.REQ_GRANT
,
225 (vir_bytes
) 0, (vir_bytes
) pcn
.pcn_name
,
227 if (err_code
!= OK
) return(err_code
);
228 NUL(pcn
.pcn_name
, len
, sizeof(pcn
.pcn_name
));
230 caller_uid
= (uid_t
) fs_m_in
.REQ_UID
;
231 caller_gid
= (gid_t
) fs_m_in
.REQ_GID
;
233 /* Get last directory pnode */
234 if ((pn_dir
= puffs_pn_nodewalk(global_pu
, 0, &fs_m_in
.REQ_INODE_NR
)) == NULL
)
237 cur_time
= clock_time();
239 memset(&pni
, 0, sizeof(pni
));
240 pni
.pni_cookie
= (void** )&pn
;
242 memset(&va
, 0, sizeof(va
));
244 va
.va_mode
= (mode_t
) fs_m_in
.REQ_MODE
;
245 va
.va_uid
= caller_uid
;
246 va
.va_gid
= caller_gid
;
247 va
.va_atime
.tv_sec
= va
.va_mtime
.tv_sec
= va
.va_ctime
.tv_sec
= cur_time
;
250 r
= puffs_path_pcnbuild(global_pu
, &pcn
, pn_dir
);
252 lpuffs_debug("pathbuild error\n");
257 r
= global_pu
->pu_ops
.puffs_node_mkdir(global_pu
, pn_dir
, &pni
, &pcn
, &va
);
260 global_pu
->pu_pathfree(global_pu
, &pcn
.pcn_po_full
);
262 struct puffs_node
*_pn
;
264 _pn
= PU_CMAP(global_pu
, pn
);
265 _pn
->pn_po
= pcn
.pcn_po_full
;
274 update_times(pn_dir
, MTIME
| CTIME
, cur_time
);
280 /*===========================================================================*
282 *===========================================================================*/
286 struct pnode
*pn
; /* pnode containing symbolic link */
287 struct pnode
*pn_dir
; /* directory containing link */
288 char target
[PATH_MAX
+ 1]; /* target path */
289 struct puffs_newinfo pni
;
290 struct puffs_kcn pkcnp
;
291 PUFFS_MAKECRED(pcr
, &global_kcred
);
292 struct puffs_cn pcn
= {&pkcnp
, (struct puffs_cred
*) __UNCONST(pcr
), {0,0,0}};
296 caller_uid
= (uid_t
) fs_m_in
.REQ_UID
;
297 caller_gid
= (gid_t
) fs_m_in
.REQ_GID
;
299 /* Copy the link name's last component */
300 len
= fs_m_in
.REQ_PATH_LEN
;
301 pcn
.pcn_namelen
= len
- 1;
302 if (pcn
.pcn_namelen
> NAME_MAX
)
303 return(ENAMETOOLONG
);
305 if (fs_m_in
.REQ_MEM_SIZE
>= PATH_MAX
)
306 return(ENAMETOOLONG
);
308 r
= sys_safecopyfrom(VFS_PROC_NR
, (cp_grant_id_t
) fs_m_in
.REQ_GRANT
,
309 (vir_bytes
) 0, (vir_bytes
) pcn
.pcn_name
,
311 if (r
!= OK
) return(r
);
312 NUL(pcn
.pcn_name
, len
, sizeof(pcn
.pcn_name
));
314 /* Copy the target path (note that it's not null terminated) */
315 r
= sys_safecopyfrom(VFS_PROC_NR
, (cp_grant_id_t
) fs_m_in
.REQ_GRANT3
,
316 (vir_bytes
) 0, (vir_bytes
) target
,
317 (size_t) fs_m_in
.REQ_MEM_SIZE
);
318 if (r
!= OK
) return(r
);
319 target
[fs_m_in
.REQ_MEM_SIZE
] = '\0';
321 if (strlen(target
) != fs_m_in
.REQ_MEM_SIZE
) {
322 /* This can happen if the user provides a buffer
323 * with a \0 in it. This can cause a lot of trouble
324 * when the symlink is used later. We could just use
325 * the strlen() value, but we want to let the user
326 * know he did something wrong. ENAMETOOLONG doesn't
327 * exactly describe the error, but there is no
330 return(ENAMETOOLONG
);
333 if ((pn_dir
= puffs_pn_nodewalk(global_pu
, 0, &fs_m_in
.REQ_INODE_NR
)) == NULL
)
336 memset(&pni
, 0, sizeof(pni
));
337 pni
.pni_cookie
= (void** )&pn
;
339 memset(&va
, 0, sizeof(va
));
341 va
.va_mode
= (mode_t
) (I_SYMBOLIC_LINK
| RWX_MODES
);
342 va
.va_uid
= caller_uid
;
343 va
.va_gid
= caller_gid
;
344 va
.va_atime
.tv_sec
= va
.va_mtime
.tv_sec
= va
.va_ctime
.tv_sec
= clock_time();
347 r
= puffs_path_pcnbuild(global_pu
, &pcn
, pn_dir
);
349 lpuffs_debug("pathbuild error\n");
354 r
= global_pu
->pu_ops
.puffs_node_symlink(global_pu
, pn_dir
, &pni
, &pcn
, &va
, target
);
357 global_pu
->pu_pathfree(global_pu
, &pcn
.pcn_po_full
);
359 struct puffs_node
*_pn
;
361 _pn
= PU_CMAP(global_pu
, pn
);
362 _pn
->pn_po
= pcn
.pcn_po_full
;
372 /*===========================================================================*
374 *===========================================================================*/