root/branches/Orange-Branch/test/io/bmi/pingpong.c @ 8873

Revision 8873, 28.5 KB (checked in by mtmoore, 2 years ago)

compiler warning cleanup

Line 
1/*
2 * (C) 2001 Clemson University and The University of Chicago
3 *
4 * See COPYING in top-level directory.
5 */
6
7
8
9
10/*
11 * This is an example of a server program that uses the BMI
12 * library for communications
13 */
14
15#include <stdio.h>
16#include <errno.h>
17#include <unistd.h>
18#include <stdlib.h>
19#include <string.h>
20#include <netinet/in.h>
21#include <sys/time.h>
22#include <time.h>
23#include <math.h>
24
25#include "pvfs2.h"
26#include "bmi.h"
27#include "gossip.h"
28#include "test-bmi.h"
29#include <src/common/misc/pvfs2-internal.h>  /* lld(), llu() */
30
31#include "pvfs2-test-config.h"
32#include <test/shared/test-common.h> /* now lld(), llu() here */
33
34#ifdef HAVE_ZLIB_H
35#include <zlib.h>
36#endif
37
38/**************************************************************
39 * Data structures
40 */
41
42#define SERVER          1
43#define CLIENT          2
44#define MIN_BYTES       1
45#define MAX_BYTES       (4<<20)
46
47#define RECV            0
48#define SEND            1
49
50#define EXPECTED        0
51#define UNEXPECTED      1
52
53#define ITERATIONS      10000
54
55struct msg {
56        int test;
57};
58
59/* A little structure to hold program options, either defaults or
60 * specified on the command line
61 */
62struct options
63{
64        char *hostid;           /* host identifier */
65        char *method;
66        int  which;
67        int  test;
68        int  crc;
69};
70
71
72/**************************************************************
73 * Internal utility functions
74 */
75
76static struct options *parse_args(int argc, char *argv[]);
77static int do_server(struct options *opts, bmi_context_id *context);
78static int do_client(struct options *opts, bmi_context_id *context);
79
80static void print_usage(void)
81{
82        fprintf(stderr, "usage: pingpong -h HOST_URI -s|-c [-u] [-r]\n");
83        fprintf(stderr, "       where:\n");
84        fprintf(stderr, "       HOST_URI is tcp://host:port, mx://host:board:endpoint, etc\n");
85        fprintf(stderr, "       -s is server and -c is client\n");
86        fprintf(stderr, "       -u will use unexpected messages (pass to client only)\n");
87        fprintf(stderr, "       -r will calculate and verify checksums (adler32)\n");
88        return;
89}
90
91/**************************************************************/
92
93int main(int argc, char **argv)
94{
95        struct options                  *opts = NULL;
96        int                             ret = -1;
97        bmi_context_id                  context;
98
99        /* grab any command line options */
100        opts = parse_args(argc, argv);
101        if (!opts) {
102                print_usage();
103                return (-1);
104        }
105
106        /* set debugging stuff */
107        gossip_enable_stderr();
108        gossip_set_debug_mask(0, GOSSIP_BMI_DEBUG_ALL);
109
110        /* initialize local interface (default options) */
111        if (opts->which == SERVER)
112            ret = BMI_initialize(opts->method, opts->hostid, BMI_INIT_SERVER);
113        else
114            ret = BMI_initialize(NULL, NULL, 0);
115
116        if (ret < 0) {
117                errno = -ret;
118                perror("BMI_initialize");
119                return (-1);
120        }
121
122        ret = BMI_open_context(&context);
123        if (ret < 0) {
124                errno = -ret;
125                perror("BMI_open_context()");
126                return (-1);
127        }
128
129        if (opts->which == SERVER) {
130                ret = do_server(opts, &context);
131        } else {
132                ret = do_client(opts, &context);
133        }
134
135        /* shutdown the local interface */
136        BMI_close_context(context);
137        ret = BMI_finalize();
138        if (ret < 0) {
139                errno = -ret;
140                perror("BMI_finalize");
141                return (-1);
142        }
143
144        /* turn off debugging stuff */
145        gossip_disable();
146
147        return (0);
148}
149
150static int bytes_to_iterations(int bytes)
151{
152        int     ret     = ITERATIONS;
153        if (bytes >= (128*1024)) ret = 5000;
154        if (bytes >= (256*1024)) ret = 2500;
155        if (bytes >= (1024*1024)) ret = 1000;
156        if (bytes >= (2*1024*1024)) ret = 500;
157        if (bytes >= (4*1024*1024)) ret = 250;
158        return ret;
159}
160
161static int do_server(struct options *opts, bmi_context_id *context)
162{
163        int                             ret = 0;
164        int                             i = 0;
165        PVFS_BMI_addr_t                 peer_addr;
166        PVFS_BMI_addr_t                 server_addr;
167        void                            *recv_buffer = NULL;
168        void                            *send_buffer = NULL;
169        bmi_op_id_t                     op_id[2];
170        bmi_error_code_t                error_code;
171        int                             outcount = 0;
172        struct BMI_unexpected_info      request_info;
173        bmi_size_t                      actual_size;
174        struct msg                      *tx_msg  = NULL;
175        struct msg                      *rx_msg  = NULL;
176        int                             bytes   = MIN_BYTES;
177        int                             max_bytes       = MAX_BYTES;
178        int                             warmup  = 1;
179        int                             iterations      = 0;
180        int                             msg_len         = 0;
181        int                             run     = 0;
182
183        /* wait for an initial request to get size */
184        do {
185                ret = BMI_testunexpected(1, &outcount, &request_info, 10);
186        } while (ret == 0 && outcount == 0);
187
188        if (ret < 0) {
189                fprintf(stderr, "Request recv failure (bad state).\n");
190                errno = -ret;
191                perror("BMI_testunexpected");
192                return ret;
193        }
194        if (request_info.error_code != 0) {
195                fprintf(stderr, "Request recv failure (bad state).\n");
196                return ret;
197        }
198       
199        if (request_info.size != sizeof(struct msg)) {
200                fprintf(stderr, "Bad Request! Received %d bytes\n",
201                                (int) request_info.size);
202                return ret;
203        }
204
205        rx_msg = (struct msg *) request_info.buffer;
206        opts->test = ntohl(rx_msg->test);
207
208        printf("Starting %s test%s\n", opts->test == EXPECTED ? "expected" : "unexpected",
209               opts->crc ? " with checksums" : "");
210
211        peer_addr = request_info.addr;
212
213        BMI_unexpected_free(peer_addr, request_info.buffer);
214
215        ret = BMI_get_info(server_addr, BMI_CHECK_MAXSIZE,
216                           (void *)&max_bytes);
217        if (ret < 0) {
218                fprintf(stderr, "BMI_get_info() returned %d\n", ret);
219                return ret;
220        }
221        if (max_bytes > MAX_BYTES) max_bytes = MAX_BYTES;
222
223        if (opts->test == UNEXPECTED) {
224                ret = BMI_addr_lookup(&server_addr, opts->hostid);
225                if (ret < 0) {
226                        errno = -ret;
227                        perror("BMI_addr_lookup");
228                        return (-1);
229                }
230                ret = BMI_get_info(server_addr, BMI_GET_UNEXP_SIZE,
231                                   (void *)&max_bytes);
232                if (ret < 0) {
233                        fprintf(stderr, "BMI_get_info() returned %d\n", ret);
234                        return ret;
235                }
236        } else {
237                int     maxsize = 0;
238                ret = BMI_get_info(server_addr, BMI_CHECK_MAXSIZE,
239                                (void *)&maxsize);
240                if (ret < 0) {
241                        fprintf(stderr, "BMI_get_info() returned %d\n", ret);
242                        return ret;
243                }
244                if (maxsize < max_bytes) max_bytes = maxsize;
245        }
246
247        msg_len = sizeof(struct msg);
248   
249        /* create an ack */
250        send_buffer = BMI_memalloc(peer_addr, max_bytes, BMI_SEND);
251        if (!send_buffer) {
252                fprintf(stderr, "BMI_memalloc failed.\n");
253                return (-1);
254        }
255        memset(send_buffer, 0, max_bytes);
256
257        tx_msg = (struct msg *) send_buffer;
258        tx_msg->test = htonl(opts->test);
259
260           
261        /* create a buffer to recv into */
262        recv_buffer = BMI_memalloc(peer_addr, max_bytes, BMI_RECV);
263        if (!recv_buffer) {
264                fprintf(stderr, "BMI_memalloc failed.\n");
265                return (-1);
266        }
267
268        /* post the ack */
269        ret = BMI_post_send(&(op_id[SEND]), peer_addr, tx_msg,
270                        msg_len, BMI_PRE_ALLOC, 0, NULL,
271                        *context, NULL);
272        if (ret < 0) {
273                fprintf(stderr, "BMI_post_send failure.\n");
274                return (-1);
275        } else if (ret == 0) {
276                do {
277                        ret = BMI_test(op_id[SEND], &outcount, &error_code,
278                                   &actual_size, NULL, 10, *context);
279                } while (ret == 0 && outcount == 0);
280       
281                if (ret < 0 || error_code != 0) {
282                        fprintf(stderr, "ack send failed.\n");
283                        return (-1);
284                }
285
286                if (actual_size != (bmi_size_t) msg_len) {
287                        fprintf(stderr, "Expected %d but received %llu\n",
288                                        msg_len, llu(actual_size));
289                }
290        }
291
292        /* start iterations */
293        while (bytes <= max_bytes) {
294                iterations = bytes_to_iterations(bytes);
295
296                for (i=0; i < iterations; i++) {
297                        /* receive the ping */
298                        if (opts->test == EXPECTED) {
299                                ret = BMI_post_recv(&(op_id[RECV]), peer_addr, recv_buffer,
300                                                bytes, &actual_size, BMI_PRE_ALLOC, i, NULL,
301                                                *context, NULL);
302                   
303                                if (ret < 0) {
304                                        fprintf(stderr, "BMI_post_recv_failure.\n");
305                                        return (-1);
306                                } else if (ret == 0) {
307                                        do {
308                                                ret = BMI_test(op_id[RECV], &outcount, &error_code,
309                                                        &actual_size, NULL, 10, *context);
310                                        } while (ret == 0 && outcount == 0);
311               
312                                        if (ret < 0 || error_code != 0) {
313                                                fprintf(stderr, "data recv failed.\n");
314                                                return (-1);
315                                        }
316                                        if (actual_size != bytes) {
317                                                fprintf(stderr, "Expected %d but received %llu\n",
318                                                                bytes, llu(actual_size));
319                                                return (-1);
320                                        }
321                                }
322                        } else { /* UNEXPECTED */
323                                do {
324                                        ret = BMI_testunexpected(1, &outcount, &request_info, 10);
325                                } while (ret == 0 && outcount == 0);
326                       
327                                if (ret < 0) {
328                                        fprintf(stderr, "Request recv failure (bad state).\n");
329                                        errno = -ret;
330                                        perror("BMI_testunexpected");
331                                        return ret;
332                                }
333                                if (request_info.error_code != 0) {
334                                        fprintf(stderr, "Request recv failure (bad state).\n");
335                                        return ret;
336                                }
337                               
338                                if (request_info.size != bytes) {
339                                        fprintf(stderr, "Bad Request! Received %d bytes\n",
340                                                        (int) request_info.size);
341                                        return ret;
342                                }
343                        }
344                        /* send the pong */
345                        ret = BMI_post_send(&(op_id[SEND]), peer_addr,
346                                            (opts->test == EXPECTED ?
347                                             recv_buffer : request_info.buffer),
348                                        bytes, BMI_PRE_ALLOC, i, NULL, *context, NULL);
349                        if (ret < 0) {
350                                fprintf(stderr, "BMI_post_send failure.\n");
351                                return (-1);
352                        } else if (ret == 0) {
353                                do {
354                                        ret = BMI_test(op_id[SEND], &outcount, &error_code,
355                                                &actual_size, NULL, 10, *context);
356                                } while (ret == 0 && outcount == 0);
357       
358                                if (ret < 0 || error_code != 0) {
359                                        fprintf(stderr, "ack send failed.\n");
360                                        return (-1);
361                                }
362                                if (actual_size != bytes) {
363                                        fprintf(stderr, "Expected %d but received %llu\n",
364                                                        bytes, llu(actual_size));
365                                        return (-1);
366                                }
367                        }
368                }
369                if (!warmup) {
370                        bytes *= 2;
371                        run++;
372                }
373                else warmup = 0;
374        }
375
376        /* free up the message buffers */
377        BMI_memfree(peer_addr, recv_buffer, max_bytes, BMI_RECV);
378        BMI_memfree(peer_addr, send_buffer, max_bytes, BMI_SEND);
379
380        return ret;
381}
382
383static int do_client(struct options *opts, bmi_context_id *context)
384{
385        int                     ret             = 0;
386        int                     i               = 0;
387        PVFS_BMI_addr_t         peer_addr;
388        void                    *recv_buffer    = NULL;
389        void                    *send_buffer    = NULL;
390        bmi_op_id_t             op_id[2];
391        bmi_error_code_t        error_code;
392        int                     outcount        = 0;
393        bmi_size_t              actual_size;
394        struct msg              *tx_msg         = NULL;
395        int                     bytes           = MIN_BYTES;
396        int                     max_bytes       = MAX_BYTES;
397        int                     warmup          = 1;
398        int                     iterations      = 0;
399        int                     msg_len         = 0;
400        int                     run             = 0;
401        struct timeval          start;
402        struct timeval          end;
403        double                  *val            = NULL;
404        double                  lat             = 0.0;
405        double                  min             = 99999.9;
406        double                  max             = 0.0;
407        double                  avg             = 0.0;
408        int                     offset;
409#ifdef HAVE_LIBZ
410        unsigned long           crc=0, rcrc=0;
411#endif
412
413        /* get a bmi_addr for the server */
414        ret = BMI_addr_lookup(&peer_addr, opts->hostid);
415        if (ret < 0) {
416                errno = -ret;
417                perror("BMI_addr_lookup");
418                return (-1);
419        }
420
421        if (opts->test == UNEXPECTED) {
422                ret = BMI_get_info(peer_addr, BMI_GET_UNEXP_SIZE,
423                                   (void *)&max_bytes);
424                if (ret < 0) {
425                        fprintf(stderr, "BMI_get_info() returned %d\n", ret);
426                        return ret;
427                }
428        } else {
429                int     maxsize = 0;
430                ret = BMI_get_info(peer_addr, BMI_CHECK_MAXSIZE,
431                                (void *)&maxsize);
432                if (ret < 0) {
433                        fprintf(stderr, "BMI_get_info() returned %d\n", ret);
434                        return ret;
435                }
436                if (maxsize < max_bytes) max_bytes = maxsize;
437        }
438
439        msg_len = sizeof(struct msg);
440
441        /* create send buffer */
442        send_buffer = BMI_memalloc(peer_addr, max_bytes, BMI_SEND);
443        if (!send_buffer) {
444                fprintf(stderr, "BMI_memalloc failed.\n");
445                return (-1);
446        }
447
448        if(opts->crc)
449        {
450            for(i = 0; i < max_bytes; ++i)
451            {
452                ((char *)send_buffer)[i] = i;
453            }
454        }
455        else
456        {
457            memset(send_buffer, 0, max_bytes);
458        }
459
460        tx_msg = (struct msg *) send_buffer;
461        tx_msg->test = htonl(opts->test);
462   
463        /* create a buffer to recv into */
464        recv_buffer = BMI_memalloc(peer_addr, max_bytes, BMI_RECV);
465        if (!recv_buffer) {
466                fprintf(stderr, "BMI_memalloc failed.\n");
467                return (-1);
468        }
469
470        /* post the test parameters */
471        ret = BMI_post_sendunexpected(&(op_id[SEND]), peer_addr, tx_msg,
472                        msg_len, BMI_PRE_ALLOC, 0, NULL, *context, NULL);
473        if (ret < 0) {
474                fprintf(stderr, "BMI_post_sendunexpected failure.\n");
475                return (-1);
476        } else if (ret == 0) {
477                do {
478                        ret = BMI_test(op_id[SEND], &outcount, &error_code,
479                                &actual_size, NULL, 10, *context);
480                } while (ret == 0 && outcount == 0);
481                if (ret < 0 || error_code != 0) {
482                        fprintf(stderr, "data send failed.\n");
483                        return (-1);
484                }
485                if (actual_size != msg_len) {
486                        fprintf(stderr, "Expected %d but received %llu\n",
487                                        msg_len, llu(actual_size));
488                        return (-1);
489                }
490        }
491
492        /* post a recv for the ack */
493        ret = BMI_post_recv(&(op_id[RECV]), peer_addr, recv_buffer,
494                        msg_len, &actual_size, BMI_PRE_ALLOC, 0, NULL, *context, NULL);
495        if (ret < 0) {
496                fprintf(stderr, "BMI_post_recv_failure.\n");
497                return (-1);
498        } else if (ret == 0) {
499                do {
500                        ret = BMI_test(op_id[RECV], &outcount, &error_code,
501                                &actual_size, NULL, 10, *context);
502                } while (ret == 0 && outcount == 0);
503
504                if (ret < 0 || error_code != 0) {
505                        fprintf(stderr, "data recv failed.\n");
506                        return (-1);
507                }
508                if (actual_size != msg_len) {
509                        fprintf(stderr, "Expected %d but received %llu\n",
510                                        msg_len, llu(actual_size));
511                        return (-1);
512                }
513        }
514
515        val = calloc(ITERATIONS, sizeof(double));
516        if (val == NULL) {
517                fprintf(stderr, "calloc() for val failed\n");
518                return -1;
519        }
520
521        /* make sure server has posted first recv */
522        sleep(1);
523
524        fprintf(stdout, "     Bytes        usecs         MB/s       StdDev          Min          Max\n");
525
526        /* start iterations */
527        while (bytes <= max_bytes) {
528
529                iterations = bytes_to_iterations(bytes);
530
531                for (i=0; i < iterations; i++) {
532
533                        offset = random() % (max_bytes - bytes - 1);
534                        gettimeofday(&start, NULL);
535
536#ifdef HAVE_LIBZ
537                        if(opts->crc)
538                        {
539                            crc = adler32(0L, Z_NULL, 0);
540                            crc = adler32(crc, ((unsigned char *)send_buffer + (unsigned int)offset), bytes);
541                        }
542#endif
543
544                        /* post the recv for the pong */
545                        ret = BMI_post_recv(&(op_id[RECV]), peer_addr, recv_buffer,
546                                        bytes, &actual_size, BMI_PRE_ALLOC, i,
547                                        NULL, *context, NULL);
548           
549                        if (ret < 0) {
550                                fprintf(stderr, "BMI_post_recv_failure.\n");
551                                return (-1);
552                        }
553       
554                        /* send the ping */
555                        if (opts->test == EXPECTED) {
556                                ret = BMI_post_send(&(op_id[SEND]), peer_addr, ((char *)send_buffer) + offset,
557                                                bytes, BMI_PRE_ALLOC, i, NULL, *context, NULL);
558                        } else {
559                                ret = BMI_post_sendunexpected(&(op_id[SEND]), peer_addr,
560                                                ((char*)send_buffer) + offset, bytes, BMI_PRE_ALLOC, i,
561                                                NULL, *context, NULL);
562                        }
563                        if (ret < 0) {
564                                fprintf(stderr, "BMI_post_sendunexpected failure.\n");
565                                return (-1);
566                        } else if (ret == 0) {
567                                do {
568                                        ret = BMI_test(op_id[SEND], &outcount, &error_code,
569                                                        &actual_size, NULL, 10, *context);
570                                } while (ret == 0 && outcount == 0);
571                       
572                                if (ret < 0 || error_code != 0) {
573                                        fprintf(stderr, "send ping failed.\n");
574                                        return (-1);
575                                }
576                                if (actual_size != bytes) {
577                                        fprintf(stderr, "Expected %d but received %llu\n",
578                                                        bytes, llu(actual_size));
579                                        return (-1);
580                                }
581                        }
582                        /* complete the receive for the pong */
583                        do {
584                                ret = BMI_test(op_id[RECV], &outcount, &error_code,
585                                                &actual_size, NULL, 10, *context);
586                        } while (ret == 0 && outcount == 0);
587       
588                        if (ret < 0 || error_code != 0) {
589                                fprintf(stderr, "data recv failed.\n");
590                                return (-1);
591                        }
592                        if (actual_size != bytes) {
593                                fprintf(stderr, "Expected %d but received %llu\n",
594                                                bytes, llu(actual_size));
595                                return (-1);
596                        }
597
598#ifdef HAVE_LIBZ
599                        if(opts->crc && opts->test == EXPECTED)
600                        {
601                            rcrc = adler32(0L, Z_NULL, 0);
602                            rcrc = adler32(rcrc, recv_buffer, bytes);
603                            if(rcrc != crc)
604                            {
605                                fprintf(stderr, "CRC Mismatch! "
606                                        "Sent %llu but received %llu\n",
607                                        (long long unsigned int)crc,
608                                        (long long unsigned int)rcrc);
609                            }
610                        }
611#endif
612                        gettimeofday(&end, NULL);
613
614                        if (!warmup) {
615                                val[i] =  (double) end.tv_sec +
616                                          (double) end.tv_usec * 0.000001;
617                                val[i] -= (double) start.tv_sec +
618                                          (double) start.tv_usec * 0.000001;
619                                lat += val[i];
620                        }
621                }
622                if (!warmup) {
623                        double stdev    = 0.0;
624
625                        lat = lat / (double) iterations * 1000000.0 / 2.0;
626                        min = 999999.9;
627                        max = 0.0;
628                        avg = 0.0;
629
630                        /* convert seconds to MB/s */
631                        for (i=0; i < iterations; i++) {
632                                val[i] = (double) bytes * 2 / val[i] / 1000000.0;
633                                avg += val[i];
634                                if (val[i] < min) min = val[i];
635                                if (val[i] > max) max = val[i];
636                        }
637                        avg /= iterations;
638
639                        if (iterations > 1) {
640                                for (i=0; i < iterations; i++) {
641                                        double diff = val[i] - avg;
642                                        stdev += diff * diff;
643                                }
644                                stdev = sqrt(stdev / (iterations - 1));
645                        }
646
647                        fprintf(stdout, "%10d %12.3f %12.3f +- %9.3f %12.3f %12.3f\n", bytes, lat, avg, stdev, min, max);
648
649                        lat = 0.0;
650                        bytes *= 2;
651                        run++;
652                } else warmup = 0;
653        }
654
655        /* free up the message buffers */
656        BMI_memfree(peer_addr, recv_buffer, max_bytes, BMI_RECV);
657        BMI_memfree(peer_addr, send_buffer, max_bytes, BMI_SEND);
658
659        return ret;
660}
661
662static int check_uri(char *uri)
663{
664        int ret = 0; /* failure */
665        if (uri[0] == ':' && uri[1] == '/' && uri[2] == '/') ret = 1;
666        return ret;
667}
668
669
670static void get_method(struct options *opts)
671{
672        char *id = opts->hostid;
673
674        if (id[0] == 't' && id[1] == 'c' && id[2] == 'p' && check_uri(&id[3])) {
675                opts->method = strdup("bmi_tcp");
676        } else if (id[0] == 'g' && id[1] == 'm' && check_uri(&id[2])) {
677                opts->method = strdup("bmi_gm");
678        } else if (id[0] == 'm' && id[1] == 'x' && check_uri(&id[2])) {
679                opts->method = strdup("bmi_mx");
680        } else if (id[0] == 'i' && id[1] == 'b' && check_uri(&id[2])) {
681                opts->method = strdup("bmi_ib");
682        }
683        return;
684}
685
686static struct options *parse_args(int argc, char *argv[])
687{
688
689        /* getopt stuff */
690        extern char *optarg;
691        char flags[] = "h:scur";
692        int one_opt = 0;
693
694        struct options *opts = NULL;
695
696        /* create storage for the command line options */
697        opts = (struct options *) calloc(1, sizeof(struct options));
698        if (!opts) {
699            goto parse_args_error;
700        }
701   
702        /* look at command line arguments */
703        while ((one_opt = getopt(argc, argv, flags)) != EOF) {
704                switch (one_opt) {
705                case ('h'):
706                        opts->hostid = (char *) strdup(optarg);
707                        if (opts->hostid == NULL) {
708                                goto parse_args_error;
709                        }
710                        get_method(opts);
711                        break;
712                case ('s'):
713                        if (opts->which == CLIENT) {
714                                fprintf(stderr, "use -s OR -c, not both\n");
715                                goto parse_args_error;
716                        }
717                        opts->which = SERVER;
718                        break;
719                case ('c'):
720                        if (opts->which == SERVER) {
721                                fprintf(stderr, "use -s OR -c, not both\n");
722                                goto parse_args_error;
723                        }
724                        opts->which = CLIENT;
725                        break;
726                case ('u'):
727                        opts->test = UNEXPECTED;
728                        break;
729                case ('r'):
730                        opts->crc = 1;
731                        break;
732                default:
733                        break;
734                }
735        }
736   
737        /* if we didn't get a host argument, bail: */
738        if (opts->hostid == NULL) {
739                fprintf(stderr, "you must specify -h\n");
740                goto parse_args_error;
741        }
742        if (opts->method == NULL) {
743                fprintf(stderr, "you must use a valid HOST_URI\n");
744                goto parse_args_error;
745        }
746        if (opts->which == 0) {
747                fprintf(stderr, "you must specify -s OR -c\n");
748                goto parse_args_error;
749        }
750
751        return (opts);
752
753parse_args_error:
754
755        /* if an error occurs, just free everything and return NULL */
756        if (opts) {
757                if (opts->hostid) {
758                        free(opts->hostid);
759                }
760                free(opts);
761        }
762        return (NULL);
763}
764
765/*
766 * vim:expandtab:shiftwidth=8:tabstop=8:
767 */
Note: See TracBrowser for help on using the browser.