Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / rx / bulktest / bulk_client.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 /* Sample program using multi_Rx, to execute calls in parallel to multiple hosts */
11
12 #include <afsconfig.h>
13 #include <afs/param.h>
14
15
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <sys/file.h>
19 #include <netdb.h>
20 #include <netinet/in.h>
21 #include <signal.h>
22 #include <stdio.h>
23 #include <rx/rx.h>
24 #include <rx/rx_null.h>
25 #include "bulk.h"
26
27 char myHostName[256];
28
29 InterruptSignal()
30 {
31 rx_PrintStats(stdout);
32 exit(0);
33 }
34
35
36 /* Bogus procedure to get internet address of host */
37 static u_long
38 GetIpAddress(hostname)
39 char *hostname;
40 {
41 struct hostent *hostent;
42 u_long host;
43 hostent = gethostbyname(hostname);
44 if (!hostent) {
45 printf("host %s not found", hostname);
46 exit(1);
47 }
48 if (hostent->h_length != sizeof(u_long)) {
49 printf("host address is disagreeable length (%d)", hostent->h_length);
50 exit(1);
51 }
52 memcpy((char *)&host, hostent->h_addr, sizeof(host));
53 return host;
54 }
55
56 long FetchFile(), StoreFile();
57
58 struct async_work {
59 char *host;
60 struct rx_connection *conn;
61 int store;
62 int count;
63 int verbose;
64 char *local;
65 char *remote;
66 };
67
68 int async_nProcs = 0;
69
70 void
71 async_BulkProc(data)
72 char *data;
73 {
74 struct async_work *work = (struct async_work *)data;
75 struct rx_call *call;
76 struct clock startTime, endTime;
77 long length;
78 long error;
79 long msec;
80 int i;
81
82 for (i = 0; i < work->count; i++) {
83 call = rx_NewCall(work->conn);
84 clock_NewTime();
85 clock_GetTime(&startTime);
86 error =
87 ((work->store ? StoreFile : FetchFile) (call, work->verbose,
88 work->local, work->remote,
89 &length));
90 error = rx_EndCall(call, error);
91
92 clock_NewTime();
93 clock_GetTime(&endTime);
94 msec = clock_ElapsedTime(&startTime, &endTime);
95 if (work->verbose && !error)
96 printf("%s: %s %s, %d bytes in %d msec, %d bps\n", work->host,
97 work->store ? "stored" : "fetched",
98 work->store ? work->local : work->remote, length, msec,
99 length * 1000 / msec);
100 else if (error)
101 printf("%s: %s of %s failed: error %d\n", work->host,
102 work->store ? "store" : "fetch",
103 work->store ? work->local : work->remote, error);
104 }
105 async_nProcs--;
106 osi_Wakeup(&async_nProcs);
107 }
108
109 async_BulkTest(host, conn, store, count, verbose, file)
110 char *host;
111 struct rx_connection *conn;
112 int store;
113 int count;
114 int verbose;
115 char *file;
116 {
117 char tempfile[256];
118 char *name;
119 PROCESS pid;
120 struct async_work *work = malloc(sizeof(struct async_work));
121 work->host = host;
122 work->conn = conn;
123 work->store = store;
124 work->count = count;
125 work->verbose = verbose;
126 name = strrchr(file, '/');
127 if (!name)
128 name = file;
129 else
130 name++;
131 /* sprintf(tempfile, "/usr/tmp/%s.%s", myHostName, name);*/
132 sprintf(tempfile, "/usr/tmp/%s", name);
133 work->local = strdup(store ? file : tempfile);
134 work->remote = strdup(store ? tempfile : file);
135 async_nProcs += 1;
136 LWP_CreateProcess(async_BulkProc, 3000, RX_PROCESS_PRIORITY, (void *)work,
137 "bulk", &pid);
138 }
139
140 long
141 FetchFile(call, verbose, localFile, remoteFile, length_ptr)
142 struct rx_call *call;
143 int verbose;
144 char *localFile, *remoteFile;
145 long *length_ptr;
146 {
147 int fd = -1, error = 0;
148 struct stat status;
149
150 if (StartBULK_FetchFile(call, verbose, remoteFile))
151 return BULK_ERROR;
152 fd = open(localFile, O_CREAT | O_TRUNC | O_WRONLY, 0666);
153 if (fd < 0 || fstat(fd, &status) < 0) {
154 fprintf("Could not create %s\n", localFile);
155 error = BULK_ERROR;
156 } else if (bulk_ReceiveFile(fd, call, &status))
157 error = BULK_ERROR;
158 *length_ptr = status.st_size;
159 if (fd >= 0)
160 close(fd);
161 /* If there were any output parameters, then it would be necessary to call EndBULKFetchFile(call, &out1,...) here to pick them up */
162 return error;
163 }
164
165 long
166 StoreFile(call, verbose, localFile, remoteFile, length_ptr)
167 struct rx_call *call;
168 int verbose;
169 char *localFile, *remoteFile;
170 long *length_ptr;
171 {
172 int fd = -1, error = 0;
173 struct stat status;
174
175 fd = open(localFile, O_RDONLY, 0);
176 if (fd < 0 || fstat(fd, &status) < 0) {
177 fprintf("Could not open %s\n", localFile);
178 return BULK_ERROR;
179 }
180 error = StartBULK_StoreFile(call, verbose, remoteFile);
181 if (!error)
182 error = bulk_SendFile(fd, call, &status);
183 /* If there were any output parameters, then it would be necessary to call EndBULKStoreFile(call, &out1,...) here to pick them up */
184 close(fd);
185 *length_ptr = status.st_size;
186 return error;
187 }
188
189 main(argc, argv)
190 char **argv;
191 {
192 int store = 0;
193 int count = 1;
194 int verbose = 0;
195 char *hostname = NULL;
196 u_long host;
197 struct rx_securityClass *null_securityObject;
198 struct rx_connection *conn = (struct rx_connection *)0;
199 gethostname(myHostName, sizeof(myHostName));
200 signal(SIGINT, InterruptSignal);
201 rx_Init(0);
202
203 null_securityObject = rxnull_NewClientSecurityObject();
204 argc--;
205 argv++;
206 while (argc) {
207 while (**argv == '-') {
208 if (strcmp(*argv, "-h") == 0) {
209 hostname = *++argv;
210 argc--;
211 host = GetIpAddress(hostname);
212 conn =
213 rx_NewConnection(host, BULK_SERVER_PORT, BULK_SERVICE_ID,
214 null_securityObject, RX_SECIDX_NULL);
215 } else if (strcmp(*argv, "-f") == 0)
216 store = 0;
217 else if (strcmp(*argv, "-s") == 0)
218 store = 1;
219 else if (strcmp(*argv, "-v") == 0)
220 verbose = 1;
221 else if (strcmp(*argv, "-c") == 0)
222 (count = atoi(*++argv)), argc--;
223 else {
224 fprintf(stderr, "Unknown option %s\n", *argv);
225 exit(1);
226 }
227 argc--;
228 argv++;
229 }
230 if (argc < 1) {
231 fprintf(stderr, "local + remote file names expected\n");
232 exit(1);
233 }
234 if (conn == (struct rx_connection *)0) {
235 fprintf(stderr, "No host specified\n");
236 exit(1);
237 }
238 async_BulkTest(hostname, conn, store, count, verbose, argv[0]);
239 argv++;
240 argc--;
241 }
242 while (async_nProcs)
243 osi_Sleep(&async_nProcs);
244 if (verbose)
245 fprintf(stderr, "All transfers done\n");
246 rx_PrintStats(stdout);
247 /* Allow Rx to idle down any calls; it's a good idea, but not essential, to call this routine */
248 rx_Finalize();
249 }