3 * dumpscan - routines for scanning and manipulating AFS volume dumps
5 * Copyright (c) 1998 Carnegie Mellon University
8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 * Carnegie Mellon requests users of this software to return to
20 * Software Distribution Coordinator or Software_Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
25 * any improvements or extensions that they make and grant Carnegie Mellon
26 * the rights to redistribute these changes.
29 /* xf_rxcall.c - XFILE routines for Rx bulk data transfers */
31 #include <sys/types.h>
32 #include <netinet/in.h>
44 #include <rx/rx_null.h>
47 #include <afs/cellconfig.h>
48 #include <afs/vlserver.h>
49 #include <afs/volser.h>
51 #ifndef AFSCONF_CLIENTNAME
52 #include <afs/dirpath.h>
53 #define AFSCONF_CLIENTNAME AFSDIR_CLIENT_ETC_DIRPATH
56 #define O_MODE_MASK (O_RDONLY | O_WRONLY | O_RDWR)
59 struct rx_connection *conn; /* connection */
60 struct rx_call *call; /* call */
61 afs_int32 tid; /* volser transaction ID */
62 afs_uint32 code; /* result code */
65 static afs_uint32 xf_rxcall_do_read(XFILE *X, void *buf, afs_uint32 count)
67 struct rxinfo *i = X->refcon;
70 xcount = rx_Read(i->call, buf, count);
71 if (xcount == count) return 0;
72 i->code = rx_EndCall(i->call, 0);
74 return i->code ? i->code : ERROR_XFILE_RDONLY;
78 static afs_uint32 xf_rxcall_do_write(XFILE *X, void *buf, afs_uint32 count)
80 struct rxinfo *i = X->refcon;
83 xcount = rx_Write(i->call, buf, count);
84 if (xcount == count) return 0;
85 i->code = rx_EndCall(i->call, 0);
91 static afs_uint32 xf_rxcall_do_close(XFILE *X)
93 struct rxinfo *i = X->refcon;
97 code = rx_EndCall(i->call, i->code);
107 static afs_uint32 xf_voldump_do_close(XFILE *X)
109 struct rxinfo *i = X->refcon;
110 struct rx_connection *conn = i->conn;
111 afs_uint32 code, rcode, xcode;
112 afs_int32 tid = i->tid;
114 code = xf_rxcall_do_close(X);
115 xcode = AFSVolEndTrans(conn, tid, &rcode);
116 if (!code) code = xcode ? xcode : rcode;
121 afs_uint32 xfopen_rxcall(XFILE *X, int flag, struct rx_call *call)
126 if (flag == O_WRONLY) return ERROR_XFILE_WRONLY;
127 memset(X, 0, sizeof(*X));
128 if (!(i = (struct rxinfo *)malloc(sizeof(struct rxinfo)))) return ENOMEM;
131 X->do_read = xf_rxcall_do_read;
132 X->do_write = xf_rxcall_do_write;
133 X->do_close = xf_rxcall_do_close;
134 X->is_writable = (flag == O_RDWR);
140 afs_uint32 xfopen_voldump(XFILE *X, struct rx_connection *conn,
141 afs_int32 part, afs_int32 volid, afs_int32 date)
143 struct rx_call *call;
145 afs_uint32 code, rcode;
148 if (code = AFSVolTransCreate(conn, volid, part, ITBusy, &tid)) return code;
149 call = rx_NewCall(conn);
150 if ((code = StartAFSVolDump(call, tid, date))
151 || (code = xfopen_rxcall(X, O_RDONLY, call))) {
153 AFSVolEndTrans(conn, tid, &rcode);
160 X->do_close = xf_voldump_do_close;
165 afs_uint32 xfon_voldump(XFILE *X, int flag, char *name)
168 struct rx_securityClass *class;
169 struct rx_connection *conn;
170 struct ktc_principal sname;
171 struct ktc_token token;
172 struct afsconf_dir *confdir;
173 afs_uint32 code, server_addr;
174 afs_int32 volid, partid, date;
178 /* Parse out the optional date and server location */
179 if (code = rx_Init(0)) return code;
180 if (!(name = strdup(name))) return ENOMEM;
181 if (x = strrchr(name, ',')) {
187 if (x = strrchr(name, '@')) {
191 if (!(y = strchr(x, '/'))) {
193 return VL_BADPARTITION;
196 if (sscanf(x, "%d.%d.%d.%d", &a, &b, &c, &d) == 4
197 && a >= 0 && a <= 255 && b >= 0 && b <= 255
198 && c >= 0 && c <= 255 && d >= 0 && d <= 255) {
199 server_addr = (a << 24) | (b << 16) | (c << 8) | d;
200 server_addr = htonl(server_addr);
202 he = gethostbyname(x);
207 memcpy(&server_addr, he->h_addr, sizeof(server_addr));
209 partid = volutil_GetPartitionID(y);
212 return VL_BADPARTITION;
216 /* Get tokens and set up a security object */
217 confdir = afsconf_Open(AFSCONF_CLIENTNAME);
222 if (code = afsconf_GetLocalCell(confdir, sname.cell, MAXKTCNAMELEN)) {
226 afsconf_Close(confdir);
227 strcpy(sname.name, "afs");
228 sname.instance[0] = 0;
229 code = ktc_GetToken(&sname, &token, sizeof(token), 0);
231 class = rxnull_NewClientSecurityObject();
234 class = rxkad_NewClientSecurityObject(rxkad_clear, &token.sessionKey,
235 token.kvno, token.ticketLen, token.ticket);
239 /* Figure out the volume ID, looking it up in the VLDB if neccessary.
240 * Also look up the server and partition, if they were not specified.
242 for (isnum = 1, y = name; *y; y++)
243 if (*y < '0' || *y > '9') isnum = 0;
247 fprintf(stderr, "XXX: need to lookup volume by ID!\n");
251 fprintf(stderr, "XXX: need to lookup volume by name!\n");
256 /* Establish a connection and start the call */
257 conn = rx_NewConnection(server_addr, htons(AFSCONF_VOLUMEPORT),
258 VOLSERVICE_ID, class, index);
259 return xfopen_voldump(X, conn, partid, volid, date);