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