libafscp: code cleanup
[openafs.git] / src / libafscp / afscp_dirops.c
1 /* AUTORIGHTS
2 Copyright (C) 2003 - 2010 Chaskiel Grundman
3 All rights reserved
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 1. Redistributions of source code must retain the above copyright
10    notice, this list of conditions and the following disclaimer.
11
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.
15
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.
26 */
27 #include <afsconfig.h>
28 #include <afs/param.h>
29
30 #include <roken.h>
31
32 #include <afs/vlserver.h>
33 #include <afs/vldbint.h>
34 #include <afs/dir.h>
35 #include "afscp.h"
36 #include "afscp_internal.h"
37
38 int
39 afscp_CreateFile(const struct afscp_venusfid *dir, char *name,
40                  struct AFSStoreStatus *sst, struct afscp_venusfid **ret)
41 {
42     int code, i, j;
43     struct AFSFid df = dir->fid;
44     struct afscp_volume *vol;
45     struct AFSFetchStatus dfst, fst;
46     struct AFSVolSync vs;
47     struct AFSCallBack cb;
48     struct AFSFid ff;
49     struct afscp_server *server;
50     struct rx_connection *c;
51     time_t now;
52
53     if (dir == NULL || name == NULL || sst == NULL) {
54         fprintf(stderr,
55                 "afscp_CreateFile called with NULL args, cannot continue\n");
56         return -1;
57     }
58     vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
59     if (vol == NULL) {
60         afscp_errno = ENOENT;
61         return -1;
62     }
63     code = ENOENT;
64     for (i = 0; i < vol->nservers; i++) {
65         server = afscp_ServerByIndex(vol->servers[i]);
66         if (server && server->naddrs > 0) {
67             for (j = 0; j < server->naddrs; j++) {
68                 c = afscp_ServerConnection(server, j);
69                 if (c == NULL) {
70                     break;
71                 }
72                 time(&now);
73                 code = RXAFS_CreateFile(c, &df, name, sst, &ff,
74                                         &fst, &dfst, &cb, &vs);
75                 if (code >= 0) {
76                     break;
77                 }
78             }
79         }
80         if (code >= 0) {
81             break;
82         }
83     }
84     if (code != 0) {
85         _StatInvalidate(dir);
86         afscp_errno = code;
87         return -1;
88     }
89     _StatStuff(dir, &dfst);
90     afscp_AddCallBack(server, &ff, &fst, &cb, now);
91     if (ret != NULL)
92         *ret = afscp_MakeFid(vol->cell, ff.Volume, ff.Vnode, ff.Unique);
93     return 0;
94 }
95
96 int
97 afscp_MakeDir(const struct afscp_venusfid *dir, char *name,
98               struct AFSStoreStatus *sst, struct afscp_venusfid **ret)
99 {
100     int code, i, j;
101     struct AFSFid df = dir->fid;
102     struct afscp_volume *vol;
103     struct AFSFetchStatus dfst, fst;
104     struct AFSVolSync vs;
105     struct AFSCallBack cb;
106     struct AFSFid ff;
107     struct afscp_server *server;
108     struct rx_connection *c;
109     time_t now;
110
111     vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
112     if (vol == NULL) {
113         afscp_errno = ENOENT;
114         return -1;
115     }
116     code = ENOENT;
117     for (i = 0; i < vol->nservers; i++) {
118         server = afscp_ServerByIndex(vol->servers[i]);
119         if (server && server->naddrs > 0) {
120             for (j = 0; j < server->naddrs; j++) {
121                 c = afscp_ServerConnection(server, j);
122                 if (c == NULL)
123                     break;
124                 time(&now);
125                 code = RXAFS_MakeDir(c, &df, name, sst, &ff,
126                                      &fst, &dfst, &cb, &vs);
127                 if (code >= 0)
128                     break;
129             }
130         }
131         if (code >= 0)
132             break;
133     }
134     if (code != 0) {
135         _StatInvalidate(dir);
136         afscp_errno = code;
137         return -1;
138     }
139     _StatStuff(dir, &dfst);
140     afscp_AddCallBack(server, &ff, &fst, &cb, now);
141     if (ret != NULL)
142         *ret = afscp_MakeFid(vol->cell, ff.Volume, ff.Vnode, ff.Unique);
143     return 0;
144 }
145
146 int
147 afscp_Symlink(const struct afscp_venusfid *dir, char *name,
148               char *target, struct AFSStoreStatus *sst)
149 {
150     int code, i, j;
151     struct AFSFid df = dir->fid;
152     struct afscp_volume *vol;
153     struct AFSFetchStatus dfst, fst;
154     struct AFSVolSync vs;
155     struct AFSFid ff;
156     struct afscp_server *server;
157     struct rx_connection *c;
158
159     vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
160     if (vol == NULL) {
161         afscp_errno = ENOENT;
162         return -1;
163     }
164     code = ENOENT;
165     for (i = 0; i < vol->nservers; i++) {
166         server = afscp_ServerByIndex(vol->servers[i]);
167         if (server && server->naddrs > 0) {
168             for (j = 0; j < server->naddrs; j++) {
169                 c = afscp_ServerConnection(server, j);
170                 if (c == NULL)
171                     break;
172                 code = RXAFS_Symlink(c, &df, name, target, sst,
173                                      &ff, &fst, &dfst, &vs);
174                 if (code >= 0)
175                     break;
176             }
177         }
178         if (code >= 0)
179             break;
180     }
181     if (code != 0) {
182         _StatInvalidate(dir);
183         afscp_errno = code;
184         return -1;
185     }
186     _StatStuff(dir, &dfst);
187     return 0;
188 }
189
190
191 int
192 afscp_RemoveFile(const struct afscp_venusfid *dir, char *name)
193 {
194     int code, i, j;
195     struct AFSFid df = dir->fid;
196     struct afscp_volume *vol;
197     struct AFSFetchStatus dfst;
198     struct AFSVolSync vs;
199     struct afscp_server *server;
200     struct rx_connection *c;
201
202     vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
203     if (vol == NULL) {
204         afscp_errno = ENOENT;
205         return -1;
206     }
207     code = ENOENT;
208     for (i = 0; i < vol->nservers; i++) {
209         server = afscp_ServerByIndex(vol->servers[i]);
210         if (server && server->naddrs > 0) {
211             for (j = 0; j < server->naddrs; j++) {
212                 c = afscp_ServerConnection(server, j);
213                 if (c == NULL)
214                     break;
215                 code = RXAFS_RemoveFile(c, &df, name, &dfst, &vs);
216                 if (code >= 0)
217                     break;
218             }
219         }
220         if (code >= 0)
221             break;
222     }
223     if (code != 0) {
224         _StatInvalidate(dir);
225         afscp_errno = code;
226         return -1;
227     }
228     _StatStuff(dir, &dfst);
229     return 0;
230 }
231
232 int
233 afscp_RemoveDir(const struct afscp_venusfid *dir, char *name)
234 {
235     int code, i, j;
236     struct AFSFid df = dir->fid;
237     struct afscp_volume *vol;
238     struct AFSFetchStatus dfst;
239     struct AFSVolSync vs;
240     struct afscp_server *server;
241     struct rx_connection *c;
242
243     vol = afscp_VolumeById(dir->cell, dir->fid.Volume);
244     if (vol == NULL) {
245         afscp_errno = ENOENT;
246         return -1;
247     }
248     code = ENOENT;
249     for (i = 0; i < vol->nservers; i++) {
250         server = afscp_ServerByIndex(vol->servers[i]);
251         if (server && server->naddrs > 0) {
252             for (j = 0; j < server->naddrs; j++) {
253                 c = afscp_ServerConnection(server, j);
254                 if (c == NULL)
255                     break;
256                 code = RXAFS_RemoveDir(c, &df, name, &dfst, &vs);
257                 if (code >= 0)
258                     break;
259             }
260         }
261         if (code >= 0)
262             break;
263     }
264     if (code != 0) {
265         _StatInvalidate(dir);
266         afscp_errno = code;
267         return -1;
268     }
269     _StatStuff(dir, &dfst);
270     return 0;
271 }