| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| |
| #include "msgr-common.h" |
| #include <pncompat/misc_funcs.inc> |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <assert.h> |
| |
| void msgr_die(const char *file, int line, const char *message) |
| { |
| fprintf(stderr, "%s:%i: %s\n", file, line, message); |
| exit(1); |
| } |
| |
| //sigh - would be nice if proton exported pn_strdup() |
| char *msgr_strdup( const char *src ) |
| { |
| char *r = NULL; |
| if (src) { |
| r = (char *) malloc(sizeof(char) * (strlen(src) + 1)); |
| if (r) strcpy(r,src); |
| } |
| return r; |
| } |
| |
| |
| pn_timestamp_t msgr_now() |
| { |
| // from "pncompat/misc_funcs.inc" |
| return time_now(); |
| } |
| |
| void addresses_init( Addresses_t *a ) |
| { |
| a->size = 10; // whatever |
| a->count = 0; |
| a->addresses = (const char **) calloc( a->size, sizeof(const char *)); |
| check(a->addresses, "malloc failure"); |
| } |
| |
| void addresses_free( Addresses_t *a ) |
| { |
| if (a->addresses) { |
| int i; |
| for (i = 0; i < a->count; i++) |
| if (a->addresses[i]) free( (void *)a->addresses[i] ); |
| free( a->addresses ); |
| a->addresses = NULL; |
| } |
| } |
| |
| void addresses_add( Addresses_t *a, const char *addr ) |
| { |
| if (a->count == a->size) { |
| a->size += 10; |
| a->addresses = (const char **) realloc( a->addresses, |
| a->size * sizeof(const char *) ); |
| check( a->addresses, "malloc failure" ); |
| int i; |
| for (i = a->count; i < a->size; i++) |
| a->addresses[i] = NULL; |
| } |
| a->addresses[a->count] = msgr_strdup(addr); |
| check( a->addresses[a->count], "malloc failure" ); |
| a->count++; |
| } |
| |
| // merge a comma-separated list of addresses |
| void addresses_merge( Addresses_t *a, const char *list ) |
| { |
| char *const l = msgr_strdup(list); |
| check( l, "malloc failure" ); |
| char *addr = l; |
| while (addr && *addr) { |
| char *comma = strchr( addr, ',' ); |
| if (comma) { |
| *comma++ = '\0'; |
| } |
| addresses_add( a, addr ); |
| addr = comma; |
| } |
| free(l); |
| } |
| |
| |
| void statistics_start( Statistics_t *s ) |
| { |
| s->latency_samples = 0; |
| s->latency_total = s->latency_min = s->latency_max = 0.0; |
| s->start = msgr_now(); |
| } |
| |
| void statistics_msg_received( Statistics_t *s, pn_message_t *message ) |
| { |
| pn_timestamp_t ts = pn_message_get_creation_time( message ); |
| if (ts) { |
| double l = (double)(msgr_now() - ts); |
| if (l > 0) { |
| s->latency_total += l; |
| if (++s->latency_samples == 1) { |
| s->latency_min = s->latency_max = l; |
| } else { |
| if (s->latency_min > l) |
| s->latency_min = l; |
| if (s->latency_max < l) |
| s->latency_max = l; |
| } |
| } |
| } |
| } |
| |
| void statistics_report( Statistics_t *s, uint64_t sent, uint64_t received ) |
| { |
| pn_timestamp_t end = msgr_now() - s->start; |
| double secs = end/(double)1000.0; |
| |
| fprintf(stdout, "Messages sent: %" PRIu64 " recv: %" PRIu64 "\n", sent, received ); |
| fprintf(stdout, "Total time: %f sec\n", secs ); |
| fprintf(stdout, "Throughput: %f msgs/sec\n", (secs != 0.0) ? (double)sent/secs : 0); |
| fprintf(stdout, "Latency (sec): %f min %f max %f avg\n", |
| s->latency_min/1000.0, s->latency_max/1000.0, |
| (s->latency_samples) ? (s->latency_total/s->latency_samples)/1000.0 : 0); |
| } |
| |
| void parse_password( const char *input, char **password ) |
| { |
| if (strncmp( input, "pass:", 5 ) == 0) { |
| // password provided on command line (not secure, shows up in 'ps') |
| *password = msgr_strdup( input + 5 ); |
| } else { // input assumed to be file containing password |
| FILE *f = fopen( input, "r" ); |
| check( f, "Cannot open password file\n" ); |
| *password = (char *)malloc(256); // 256 should be enough for anybody! |
| check( *password, "malloc failure" ); |
| int rc = fscanf( f, "%255s", *password ); |
| check( rc == 1, "Cannot read password from file\n" ); |
| fclose(f); |
| } |
| } |
| |
| static int log = 0; |
| void enable_logging() |
| { |
| log = 1; |
| } |
| |
| void LOG( const char *fmt, ... ) |
| { |
| if (log) { |
| va_list ap; |
| va_start(ap, fmt); |
| vfprintf( stdout, fmt, ap ); |
| va_end(ap); |
| } |
| } |