rx: Don't cast returns from allocator
[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, BULK_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 }