Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / libafscp / afscp_dirops.c
blob476aaa76a8c0263744330ee374391da4a3a53f98
1 /* AUTORIGHTS
2 Copyright (C) 2003 - 2010 Chaskiel Grundman
3 All rights reserved
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <afsconfig.h>
28 #include <afs/param.h>
30 #include <afs/vlserver.h>
31 #include <afs/vldbint.h>
32 #include <afs/dir.h>
33 #include "afscp.h"
34 #include "afscp_internal.h"
35 #include <afs/unified_afs.h>
37 int
38 afscp_CreateFile(const struct afscp_venusfid *dir, char *name,
39 struct AFSStoreStatus *sst, struct afscp_venusfid **ret)
41 int code, i, j;
42 struct AFSFid df = dir->fid;
43 struct afscp_volume *vol;
44 struct AFSFetchStatus dfst, fst;
45 struct AFSVolSync vs;
46 struct AFSCallBack cb;
47 struct AFSFid ff;
48 struct afscp_server *server;
49 struct rx_connection *c;
50 time_t now;
52 if (dir == NULL || name == NULL || sst == NULL) {
53 fprintf(stderr,
54 "afscp_CreateFile called with NULL args, cannot continue\n");
55 return -1;
57 vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
58 if (vol == NULL) {
59 afscp_errno = ENOENT;
60 return -1;
62 code = ENOENT;
63 for (i = 0; i < vol->nservers; i++) {
64 server = afscp_ServerByIndex(vol->servers[i]);
65 if (server && server->naddrs > 0) {
66 for (j = 0; j < server->naddrs; j++) {
67 c = afscp_ServerConnection(server, j);
68 if (c == NULL) {
69 break;
71 time(&now);
72 code = RXAFS_CreateFile(c, &df, name, sst, &ff,
73 &fst, &dfst, &cb, &vs);
74 if (code >= 0) {
75 break;
79 if (code >= 0) {
80 break;
83 if (code != 0) {
84 _StatInvalidate(dir);
85 afscp_errno = code;
86 return -1;
88 _StatStuff(dir, &dfst);
89 afscp_AddCallBack(server, &ff, &fst, &cb, now);
90 if (ret != NULL)
91 *ret = afscp_MakeFid(vol->cell, ff.Volume, ff.Vnode, ff.Unique);
92 return 0;
95 int
96 afscp_MakeDir(const struct afscp_venusfid *dir, char *name,
97 struct AFSStoreStatus *sst, struct afscp_venusfid **ret)
99 int code, i, j;
100 struct AFSFid df = dir->fid;
101 struct afscp_volume *vol;
102 struct AFSFetchStatus dfst, fst;
103 struct AFSVolSync vs;
104 struct AFSCallBack cb;
105 struct AFSFid ff;
106 struct afscp_server *server;
107 struct rx_connection *c;
108 time_t now;
110 vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
111 if (vol == NULL) {
112 afscp_errno = ENOENT;
113 return -1;
115 code = ENOENT;
116 for (i = 0; i < vol->nservers; i++) {
117 server = afscp_ServerByIndex(vol->servers[i]);
118 if (server && server->naddrs > 0) {
119 for (j = 0; j < server->naddrs; j++) {
120 c = afscp_ServerConnection(server, j);
121 if (c == NULL)
122 break;
123 time(&now);
124 code = RXAFS_MakeDir(c, &df, name, sst, &ff,
125 &fst, &dfst, &cb, &vs);
126 if (code >= 0)
127 break;
130 if (code >= 0)
131 break;
133 if (code != 0) {
134 _StatInvalidate(dir);
135 afscp_errno = code;
136 return -1;
138 _StatStuff(dir, &dfst);
139 afscp_AddCallBack(server, &ff, &fst, &cb, now);
140 if (ret != NULL)
141 *ret = afscp_MakeFid(vol->cell, ff.Volume, ff.Vnode, ff.Unique);
142 return 0;
146 afscp_Symlink(const struct afscp_venusfid *dir, char *name,
147 char *target, struct AFSStoreStatus *sst)
149 int code, i, j;
150 struct AFSFid df = dir->fid;
151 struct afscp_volume *vol;
152 struct AFSFetchStatus dfst, fst;
153 struct AFSVolSync vs;
154 struct AFSFid ff;
155 struct afscp_server *server;
156 struct rx_connection *c;
158 vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
159 if (vol == NULL) {
160 afscp_errno = ENOENT;
161 return -1;
163 code = ENOENT;
164 for (i = 0; i < vol->nservers; i++) {
165 server = afscp_ServerByIndex(vol->servers[i]);
166 if (server && server->naddrs > 0) {
167 for (j = 0; j < server->naddrs; j++) {
168 c = afscp_ServerConnection(server, j);
169 if (c == NULL)
170 break;
171 code = RXAFS_Symlink(c, &df, name, target, sst,
172 &ff, &fst, &dfst, &vs);
173 if (code >= 0)
174 break;
177 if (code >= 0)
178 break;
180 if (code != 0) {
181 _StatInvalidate(dir);
182 afscp_errno = code;
183 return -1;
185 _StatStuff(dir, &dfst);
186 return 0;
191 afscp_Lock(const struct afscp_venusfid *fid, int locktype)
193 int code, i, j;
194 struct AFSFid ff = fid->fid;
195 struct afscp_volume *vol;
196 struct AFSVolSync vs;
197 struct afscp_server *server;
198 struct rx_connection *c;
200 vol = afscp_VolumeById(fid->cell, fid->fid.Volume);
201 if (vol == NULL) {
202 afscp_errno = ENOENT;
203 return -1;
205 code = ENOENT;
206 for (i = 0; i < vol->nservers; i++) {
207 server = afscp_ServerByIndex(vol->servers[i]);
208 if (server && server->naddrs > 0) {
209 for (j = 0; j < server->naddrs; j++) {
210 c = afscp_ServerConnection(server, j);
211 if (c == NULL)
212 break;
213 if (locktype == LockRelease)
214 code = RXAFS_ReleaseLock(c, &ff, &vs);
215 /* read, write, extend */
216 else if (locktype < LockRelease)
217 code = RXAFS_SetLock(c, &ff, locktype, &vs);
218 if (code >= 0)
219 break;
222 if (code >= 0)
223 break;
225 if (code != 0) {
226 if ((code == EAGAIN) || (code == UAEWOULDBLOCK) || (code == UAEAGAIN))
227 code = EWOULDBLOCK;
228 afscp_errno = code;
229 return -1;
231 return 0;
236 afscp_RemoveFile(const struct afscp_venusfid *dir, char *name)
238 int code, i, j;
239 struct AFSFid df = dir->fid;
240 struct afscp_volume *vol;
241 struct AFSFetchStatus dfst;
242 struct AFSVolSync vs;
243 struct afscp_server *server;
244 struct rx_connection *c;
246 vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
247 if (vol == NULL) {
248 afscp_errno = ENOENT;
249 return -1;
251 code = ENOENT;
252 for (i = 0; i < vol->nservers; i++) {
253 server = afscp_ServerByIndex(vol->servers[i]);
254 if (server && server->naddrs > 0) {
255 for (j = 0; j < server->naddrs; j++) {
256 c = afscp_ServerConnection(server, j);
257 if (c == NULL)
258 break;
259 code = RXAFS_RemoveFile(c, &df, name, &dfst, &vs);
260 if (code >= 0)
261 break;
264 if (code >= 0)
265 break;
267 if (code != 0) {
268 _StatInvalidate(dir);
269 afscp_errno = code;
270 return -1;
272 _StatStuff(dir, &dfst);
273 return 0;
277 afscp_RemoveDir(const struct afscp_venusfid *dir, char *name)
279 int code, i, j;
280 struct AFSFid df = dir->fid;
281 struct afscp_volume *vol;
282 struct AFSFetchStatus dfst;
283 struct AFSVolSync vs;
284 struct afscp_server *server;
285 struct rx_connection *c;
287 vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
288 if (vol == NULL) {
289 afscp_errno = ENOENT;
290 return -1;
292 code = ENOENT;
293 for (i = 0; i < vol->nservers; i++) {
294 server = afscp_ServerByIndex(vol->servers[i]);
295 if (server && server->naddrs > 0) {
296 for (j = 0; j < server->naddrs; j++) {
297 c = afscp_ServerConnection(server, j);
298 if (c == NULL)
299 break;
300 code = RXAFS_RemoveDir(c, &df, name, &dfst, &vs);
301 if (code >= 0)
302 break;
305 if (code >= 0)
306 break;
308 if (code != 0) {
309 _StatInvalidate(dir);
310 afscp_errno = code;
311 return -1;
313 _StatStuff(dir, &dfst);
314 return 0;