Remove building with NOCRYPTO option
[minix.git] / minix / lib / libpuffs / open.c
blobccd588572c76f34d438a4d0adf5e0591bdda21db
1 /* Created (MFS based):
2 * June 2011 (Evgeniy Ivanov)
3 */
5 #include "fs.h"
7 /*===========================================================================*
8 * fs_create *
9 *===========================================================================*/
10 int fs_create(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
11 struct fsdriver_node *node)
13 int r;
14 struct puffs_node *pn_dir;
15 struct puffs_node *pn;
16 struct puffs_newinfo pni;
17 struct puffs_kcn pkcnp;
18 PUFFS_MAKECRED(pcr, &global_kcred);
19 struct puffs_cn pcn = {&pkcnp, (struct puffs_cred *) __UNCONST(pcr), {0,0,0}};
20 struct vattr va;
21 struct timespec cur_time;
23 if (global_pu->pu_ops.puffs_node_create == NULL) {
24 lpuffs_debug("No puffs_node_create");
25 return(ENFILE);
28 /* Copy the last component (i.e., file name) */
29 pcn.pcn_namelen = strlen(name);
30 assert(pcn.pcn_namelen <= NAME_MAX);
31 strcpy(pcn.pcn_name, name);
33 /* Get last directory pnode (i.e., directory that will hold the new pnode) */
34 if ((pn_dir = puffs_pn_nodewalk(global_pu, find_inode_cb, &dir_nr)) == NULL)
35 return(ENOENT);
37 memset(&pni, 0, sizeof(pni));
38 pni.pni_cookie = (void** )&pn;
40 (void)clock_time(&cur_time);
42 memset(&va, 0, sizeof(va));
43 va.va_type = VREG;
44 va.va_mode = mode;
45 va.va_uid = uid;
46 va.va_gid = gid;
47 va.va_atime = va.va_mtime = va.va_ctime = cur_time;
49 if (buildpath) {
50 r = puffs_path_pcnbuild(global_pu, &pcn, pn_dir);
51 if (r) {
52 lpuffs_debug("pathbuild error\n");
53 return(ENOENT);
57 r = global_pu->pu_ops.puffs_node_create(global_pu, pn_dir, &pni, &pcn, &va);
58 if (buildpath) {
59 if (r) {
60 global_pu->pu_pathfree(global_pu, &pcn.pcn_po_full);
61 } else {
62 struct puffs_node *_pn;
64 _pn = PU_CMAP(global_pu, pn);
65 _pn->pn_po = pcn.pcn_po_full;
69 if (r != OK) {
70 if (r > 0) r = -r;
71 return(r);
74 /* Open pnode */
75 pn->pn_count++;
77 update_timens(pn_dir, MTIME | CTIME, &cur_time);
79 /* Reply message */
80 node->fn_ino_nr = pn->pn_va.va_fileid;
81 node->fn_mode = pn->pn_va.va_mode;
82 node->fn_size = pn->pn_va.va_size;
83 node->fn_uid = pn->pn_va.va_uid;
84 node->fn_gid = pn->pn_va.va_gid;
85 node->fn_dev = NO_DEV;
87 return(OK);
91 /*===========================================================================*
92 * fs_mknod *
93 *===========================================================================*/
94 int fs_mknod(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
95 dev_t dev)
97 int r;
98 struct puffs_node *pn_dir;
99 struct puffs_node *pn;
100 struct puffs_newinfo pni;
101 struct puffs_kcn pkcnp;
102 PUFFS_MAKECRED(pcr, &global_kcred);
103 struct puffs_cn pcn = {&pkcnp, (struct puffs_cred *) __UNCONST(pcr), {0,0,0}};
104 struct vattr va;
105 struct timespec cur_time;
107 if (global_pu->pu_ops.puffs_node_mknod == NULL) {
108 lpuffs_debug("No puffs_node_mknod");
109 return(ENFILE);
112 /* Copy the last component */
113 pcn.pcn_namelen = strlen(name);
114 assert(pcn.pcn_namelen <= NAME_MAX);
115 strcpy(pcn.pcn_name, name);
117 /* Get last directory pnode */
118 if ((pn_dir = puffs_pn_nodewalk(global_pu, find_inode_cb, &dir_nr)) == NULL)
119 return(ENOENT);
121 memset(&pni, 0, sizeof(pni));
122 pni.pni_cookie = (void** )&pn;
124 (void)clock_time(&cur_time);
126 memset(&va, 0, sizeof(va));
127 va.va_type = VDIR;
128 va.va_mode = mode;
129 va.va_uid = uid;
130 va.va_gid = gid;
131 va.va_rdev = dev;
132 va.va_atime = va.va_mtime = va.va_ctime = cur_time;
134 if (buildpath) {
135 if (puffs_path_pcnbuild(global_pu, &pcn, pn_dir) != 0) {
136 lpuffs_debug("pathbuild error\n");
137 return(ENOENT);
141 r = global_pu->pu_ops.puffs_node_mknod(global_pu, pn_dir, &pni, &pcn, &va);
142 if (buildpath) {
143 if (r) {
144 global_pu->pu_pathfree(global_pu, &pcn.pcn_po_full);
145 } else {
146 struct puffs_node *_pn;
148 _pn = PU_CMAP(global_pu, pn);
149 _pn->pn_po = pcn.pcn_po_full;
153 if (r != OK) {
154 if (r > 0) r = -r;
155 return(r);
158 update_timens(pn_dir, MTIME | CTIME, &cur_time);
160 return(OK);
164 /*===========================================================================*
165 * fs_mkdir *
166 *===========================================================================*/
167 int fs_mkdir(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid)
169 int r;
170 struct puffs_node *pn_dir;
171 struct puffs_node *pn;
172 struct puffs_newinfo pni;
173 struct puffs_kcn pkcnp;
174 PUFFS_MAKECRED(pcr, &global_kcred);
175 struct puffs_cn pcn = {&pkcnp, (struct puffs_cred *) __UNCONST(pcr), {0,0,0}};
176 struct vattr va;
177 struct timespec cur_time;
179 if (global_pu->pu_ops.puffs_node_mkdir == NULL) {
180 lpuffs_debug("No puffs_node_mkdir");
181 return(ENFILE);
184 /* Copy the last component */
185 pcn.pcn_namelen = strlen(name);
186 assert(pcn.pcn_namelen <= NAME_MAX);
187 strcpy(pcn.pcn_name, name);
189 /* Get last directory pnode */
190 if ((pn_dir = puffs_pn_nodewalk(global_pu, find_inode_cb, &dir_nr)) == NULL)
191 return(ENOENT);
193 (void)clock_time(&cur_time);
195 memset(&pni, 0, sizeof(pni));
196 pni.pni_cookie = (void** )&pn;
198 memset(&va, 0, sizeof(va));
199 va.va_type = VDIR;
200 va.va_mode = mode;
201 va.va_uid = uid;
202 va.va_gid = gid;
203 va.va_atime = va.va_mtime = va.va_ctime = cur_time;
205 if (buildpath) {
206 r = puffs_path_pcnbuild(global_pu, &pcn, pn_dir);
207 if (r) {
208 lpuffs_debug("pathbuild error\n");
209 return(ENOENT);
213 r = global_pu->pu_ops.puffs_node_mkdir(global_pu, pn_dir, &pni, &pcn, &va);
214 if (buildpath) {
215 if (r) {
216 global_pu->pu_pathfree(global_pu, &pcn.pcn_po_full);
217 } else {
218 struct puffs_node *_pn;
220 _pn = PU_CMAP(global_pu, pn);
221 _pn->pn_po = pcn.pcn_po_full;
225 if (r != OK) {
226 if (r > 0) r = -r;
227 return(r);
230 update_timens(pn_dir, MTIME | CTIME, &cur_time);
232 return(OK);
236 /*===========================================================================*
237 * fs_slink *
238 *===========================================================================*/
239 int fs_slink(ino_t dir_nr, char *name, uid_t uid, gid_t gid,
240 struct fsdriver_data *data, size_t bytes)
242 int r;
243 struct pnode *pn; /* pnode containing symbolic link */
244 struct pnode *pn_dir; /* directory containing link */
245 char target[PATH_MAX + 1]; /* target path */
246 struct puffs_newinfo pni;
247 struct puffs_kcn pkcnp;
248 PUFFS_MAKECRED(pcr, &global_kcred);
249 struct puffs_cn pcn = {&pkcnp, (struct puffs_cred *) __UNCONST(pcr), {0,0,0}};
250 struct vattr va;
251 struct timespec cur_time;
253 /* Copy the link name's last component */
254 pcn.pcn_namelen = strlen(name);
255 if (pcn.pcn_namelen > NAME_MAX)
256 return(ENAMETOOLONG);
257 strcpy(pcn.pcn_name, name);
259 if (bytes >= PATH_MAX)
260 return(ENAMETOOLONG);
262 /* Copy the target path (note that it's not null terminated) */
263 if ((r = fsdriver_copyin(data, 0, target, bytes)) != OK)
264 return r;
266 target[bytes] = '\0';
268 if (strlen(target) != bytes) {
269 /* This can happen if the user provides a buffer
270 * with a \0 in it. This can cause a lot of trouble
271 * when the symlink is used later. We could just use
272 * the strlen() value, but we want to let the user
273 * know he did something wrong. ENAMETOOLONG doesn't
274 * exactly describe the error, but there is no
275 * ENAMETOOWRONG.
277 return(ENAMETOOLONG);
280 if ((pn_dir = puffs_pn_nodewalk(global_pu, find_inode_cb, &dir_nr)) == NULL)
281 return(EINVAL);
283 memset(&pni, 0, sizeof(pni));
284 pni.pni_cookie = (void** )&pn;
286 (void)clock_time(&cur_time);
288 memset(&va, 0, sizeof(va));
289 va.va_type = VLNK;
290 va.va_mode = (I_SYMBOLIC_LINK | RWX_MODES);
291 va.va_uid = uid;
292 va.va_gid = gid;
293 va.va_atime = va.va_mtime = va.va_ctime = cur_time;
295 if (buildpath) {
296 r = puffs_path_pcnbuild(global_pu, &pcn, pn_dir);
297 if (r) {
298 lpuffs_debug("pathbuild error\n");
299 return(ENOENT);
303 r = global_pu->pu_ops.puffs_node_symlink(global_pu, pn_dir, &pni, &pcn, &va, target);
304 if (buildpath) {
305 if (r) {
306 global_pu->pu_pathfree(global_pu, &pcn.pcn_po_full);
307 } else {
308 struct puffs_node *_pn;
310 _pn = PU_CMAP(global_pu, pn);
311 _pn->pn_po = pcn.pcn_po_full;
315 if (r > 0) r = -r;
317 return(r);