venus: Tidy up header includes
[openafs.git] / src / venus / cacheout.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10
11 #include <afsconfig.h>
12 #include <afs/param.h>
13
14 #include <roken.h>
15
16 #include <ctype.h>
17
18 #include <afs/cmd.h>
19 #include <afs/cellconfig.h>
20 #include <afs/afsint.h>
21 #include <afs/vlserver.h>
22 #include <rx/rx.h>
23 #include <rx/xdr.h>
24 #include <ubik.h>
25 #include <afs/kauth.h>
26 #include <afs/afsutil.h>
27 #include <afs/vldbint.h>
28
29 /*
30 File servers in NW byte order.
31 */
32
33 static afs_int32 server_count = 0;
34 static afs_int32 server_id[256];
35
36 static struct ubik_client *client;
37
38 static struct rx_securityClass *junk;
39
40 /*
41 Obtain list of file servers as known to VLDB. These may
42 not actually be configured as file servers in the cell.
43 */
44
45 static afs_int32
46 ListServers(void)
47 {
48     afs_int32 code;
49     int i;
50     struct VLCallBack vlcb;
51     struct VLCallBack spare3;
52     bulkaddrs addrs, m_addrs;
53     afs_uint32 ip;
54     afs_int32 base, index;
55     afsUUID m_uuid;
56     afs_int32 m_uniq = 0;
57     afs_int32 m_nentries;
58     char hoststr[16];
59     ListAddrByAttributes m_attrs;
60
61     memset(&addrs, 0, sizeof(addrs));
62     memset(&spare3, 0, sizeof(spare3));
63     code =
64         ubik_VL_GetAddrs(client, 0, 0, 0, &vlcb,
65                   &server_count, &addrs);
66     if (code) {
67         printf("Fatal error: could not get list of file servers\n");
68         return 1;
69     }
70
71     for (i = 0; i < server_count; ++i) {
72         ip = addrs.bulkaddrs_val[i];
73
74         if (((ip & 0xff000000) == 0xff000000) && (ip & 0xffff)) {
75             base = (ip >> 16) & 0xff;
76             index = ip & 0xffff;
77
78             /* server is a multihomed host; query the vldb for its addresses,
79              * and just pick the first one */
80
81             if ((base >= 0) && (base <= VL_MAX_ADDREXTBLKS) && (index >= 1)
82                 && (index <= VL_MHSRV_PERBLK)) {
83
84                 m_attrs.Mask = VLADDR_INDEX;
85                 m_attrs.index = (base * VL_MHSRV_PERBLK) + index;
86                 m_nentries = 0;
87                 m_addrs.bulkaddrs_val = 0;
88                 m_addrs.bulkaddrs_len = 0;
89
90                 code = ubik_VL_GetAddrsU(client, 0, &m_attrs, &m_uuid, &m_uniq,
91                                          &m_nentries, &m_addrs);
92
93                 if (code || m_addrs.bulkaddrs_len == 0) {
94                     printf("Error getting multihomed addresses for server "
95                            "%s (index %ld)\n",
96                            afs_inet_ntoa_r(m_addrs.bulkaddrs_val[0], hoststr),
97                            afs_printable_int32_ld(m_attrs.index));
98                     server_id[i] = 0;
99                 } else {
100                     server_id[i] = htonl(m_addrs.bulkaddrs_val[0]);
101                 }
102             }
103         } else {
104             server_id[i] = htonl(addrs.bulkaddrs_val[i]);
105         }
106     }
107
108     return code;
109 }
110
111
112 static int
113 InvalidateCache(struct cmd_syndesc *as, void *arock)
114 {
115     afs_int32 code = 0;
116     struct cmd_item *u;
117     struct rx_connection *conn;
118     int i;
119     afs_int32 port = 7000;
120     char hoststr[16];
121     int err = 0;
122
123     afs_int32 spare1 = 0;
124     afs_int32 spare2, spare3;
125
126     afs_int32 id[256];
127     afs_int32 ip[256];
128
129     struct ViceIds vid;
130     struct IPAddrs ipa;
131
132     code = ListServers();
133     if (code)
134         return code;
135
136
137     /* make sure something there */
138
139     if (!as->parms[0].items && !as->parms[1].items) {
140         printf("Use -help flag for list of optional argmuments\n");
141         return 1;
142     }
143
144     /* get user ids */
145
146     for (i = 0, u = as->parms[0].items; i < 255 && u; ++i, u = u->next) {
147         code = util_GetInt32(u->data, &id[i]);
148         if (code) {
149             printf("Fatal error: bad conversion to long for %s\n", u->data);
150             return code;
151         }
152     }
153
154     id[i] = 0;
155     vid.ViceIds_len = i;
156     vid.ViceIds_val = id;
157
158     /* get IP addresses, convert to NW byte order */
159
160     for (i = 0, u = as->parms[1].items; i < 255 && u; ++i, u = u->next)
161         ip[i] = inet_addr(u->data);
162
163     ip[i] = 0;
164     ipa.IPAddrs_len = i;
165     ipa.IPAddrs_val = ip;
166
167     for (i = 0; i < server_count; ++i) {
168         if (!server_id[i]) {
169             err = 1;
170             continue;
171         }
172         conn = rx_NewConnection(server_id[i], htons(port), 1, junk, 0);
173         if (!conn) {
174             printf("Informational: could not connect to \
175 file server %s\n", afs_inet_ntoa_r(server_id[i], hoststr));
176             err = 1;
177             continue;
178         }
179
180         /* invalidate the cache */
181
182         code = RXAFS_FlushCPS(conn, &vid, &ipa, spare1, &spare2, &spare3);
183
184         /*
185          * May get spurious error codes in case server is
186          * down or is reported by VLDB as a file server
187          * even though it is not configured as such in the
188          * cell.
189          */
190
191         if (code) {
192             printf("Informational: failed to invalidate \
193 file server %s cache code = %ld\n", afs_inet_ntoa_r(server_id[i], hoststr),
194             afs_printable_int32_ld(code));
195             err = 1;
196         }
197
198         rx_DestroyConnection(conn);
199     }
200     return err;
201 }
202
203 static int
204 GetServerList(struct cmd_syndesc *as, void *arock)
205 {
206     int code;
207     int i;
208
209     code = ListServers();
210     if (code)
211         return (code);
212
213     printf("There are %d file servers in the cell\n\n", server_count);
214     fflush(stdout);
215     for (i = 0; i < server_count; ++i)
216         printf("%s\n", hostutil_GetNameByINet(server_id[i]));
217     fflush(stdout);
218
219     return code;
220 }
221
222 /*
223 User enters lists of:
224
225         1. AFS user ids - say from "pts exam username".
226         2. IP addresses - say from /etc/hosts (no wildcards).
227
228 Command is executed in user's cell.
229 */
230
231 static int
232 MyBeforeProc(struct cmd_syndesc *as, void *arock)
233 {
234     char *tcell = NULL;
235     char confdir[200];
236     struct afsconf_dir *tdir;
237     struct afsconf_cell info;
238     struct rx_connection *serverconns[MAXSERVERS];
239     afs_int32 code, i;
240
241     sprintf(confdir, "%s", AFSDIR_CLIENT_ETC_DIRPATH);
242     /* setup to talk to servers */
243     code = rx_Init(0);
244     if (code) {
245         printf("Warning: could not initialize network communication.\n");
246         return 1;
247     }
248
249     junk = rxnull_NewClientSecurityObject();
250     tdir = afsconf_Open(confdir);
251     if (!tdir) {
252         printf("Warning: could not get cell configuration.\n");
253         return 1;
254     }
255
256     if (as->parms[2].items)     /* if -cell specified */
257         tcell = as->parms[2].items->data;
258     code = afsconf_GetCellInfo(tdir, tcell, AFSCONF_VLDBSERVICE, &info);
259     if (code || info.numServers > MAXSERVERS) {
260         printf("Warning: could not init cell info.\n");
261         return 1;
262     }
263
264     for (i = 0; i < info.numServers; ++i)
265         serverconns[i] =
266             rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
267                              info.hostAddr[i].sin_port, USER_SERVICE_ID, junk,
268                              0);
269     for (; i < MAXSERVERS; ++i) {
270         serverconns[i] = (struct rx_connection *)0;
271     }
272     code = ubik_ClientInit(serverconns, &client);
273     if (code) {
274         printf("Warning: could not initialize RPC interface.\n");
275         return 1;
276     }
277     return 0;
278 }
279
280
281 int
282 main(int argc, char **argv)
283 {
284     afs_int32 code = 0;
285     struct cmd_syndesc *ts;
286
287 #ifdef  AFS_AIX32_ENV
288     struct sigaction nsa;
289
290     sigemptyset(&nsa.sa_mask);
291     nsa.sa_handler = SIG_DFL;
292     nsa.sa_flags = SA_FULLDUMP;
293     sigaction(SIGSEGV, &nsa, NULL);
294 #endif
295
296     /*
297      * Look in /usr/vice/etc (client side database).
298      */
299     cmd_SetBeforeProc(MyBeforeProc, NULL);
300
301     ts = cmd_CreateSyntax("initcmd" /*"invalidatecache" */ , InvalidateCache,
302                           NULL, "invalidate server ACL cache");
303     cmd_AddParm(ts, "-id", CMD_LIST, CMD_OPTIONAL, "user identifier");
304     cmd_AddParm(ts, "-ip", CMD_LIST, CMD_OPTIONAL, "IP address");
305     cmd_CreateAlias(ts, "ic");
306     cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");
307
308     ts = cmd_CreateSyntax("listservers", GetServerList, NULL,
309                           "list servers in the cell");
310     cmd_CreateAlias(ts, "ls");
311
312     code = cmd_Dispatch(argc, argv);
313
314     rx_Finalize();
315
316     exit(code);
317 }