Changeset b5e68c8 in mainline for uspace/app/netecho/netecho.c


Ignore:
Timestamp:
2011-05-12T16:49:44Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f36787d7
Parents:
e80329d6 (diff), 750636a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/netecho/netecho.c

    re80329d6 rb5e68c8  
    2828
    2929/** @addtogroup netecho
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Network echo application.
    35  *  Answers received packets.
     34 * Network echo server.
     35 *
     36 * Sockets-based server that echoes incomming messages. If stream mode
     37 * is selected, accepts incoming connections.
    3638 */
    3739
    38 #include <malloc.h>
     40#include <assert.h>
    3941#include <stdio.h>
     42#include <stdlib.h>
    4043#include <str.h>
    4144#include <task.h>
    4245#include <arg_parse.h>
    43 #include <err.h>
    4446
    4547#include <net/in.h>
     
    5153#include "print_error.h"
    5254
    53 /** Network echo module name.
    54  */
    55 #define NAME    "Network Echo"
    56 
    57 /** Prints the application help.
    58  */
    59 void echo_print_help(void);
    60 
    61 /** Module entry point.
    62  *  Reads command line parameters and starts listenning.
    63  *  @param[in] argc The number of command line parameters.
    64  *  @param[in] argv The command line parameters.
    65  *  @returns EOK on success.
    66  */
    67 int main(int argc, char * argv[]);
    68 
    69 void echo_print_help(void){
     55#define NAME "netecho"
     56
     57static int count = -1;
     58static int family = PF_INET;
     59static sock_type_t type = SOCK_DGRAM;
     60static uint16_t port = 7;
     61static int backlog = 3;
     62static size_t size = 1024;
     63static int verbose = 0;
     64
     65static char *reply = NULL;
     66static size_t reply_length;
     67
     68static char *data;
     69
     70static void echo_print_help(void)
     71{
    7072        printf(
    71                 "Network Echo aplication\n" \
    72                 "Usage: echo [options]\n" \
    73                 "Where options are:\n" \
    74                 "-b backlog | --backlog=size\n" \
    75                 "\tThe size of the accepted sockets queue. Only for SOCK_STREAM. The default is 3.\n" \
    76                 "\n" \
    77                 "-c count | --count=count\n" \
    78                 "\tThe number of received messages to handle. A negative number means infinity. The default is infinity.\n" \
    79                 "\n" \
    80                 "-f protocol_family | --family=protocol_family\n" \
    81                 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
    82                 "\n" \
    83                 "-h | --help\n" \
    84                 "\tShow this application help.\n"
    85                 "\n" \
    86                 "-p port_number | --port=port_number\n" \
    87                 "\tThe port number the application should listen at. The default is 7.\n" \
    88                 "\n" \
    89                 "-r reply_string | --reply=reply_string\n" \
    90                 "\tThe constant reply string. The default is the original data received.\n" \
    91                 "\n" \
    92                 "-s receive_size | --size=receive_size\n" \
    93                 "\tThe maximum receive data size the application should accept. The default is 1024 bytes.\n" \
    94                 "\n" \
    95                 "-t socket_type | --type=socket_type\n" \
    96                 "\tThe listenning socket type. Only the SOCK_DGRAM and the SOCK_STREAM are supported.\n" \
    97                 "\n" \
    98                 "-v | --verbose\n" \
    99                 "\tShow all output messages.\n"
     73            "Network echo server\n"
     74            "Usage: " NAME " [options]\n"
     75            "Where options are:\n"
     76            "-b backlog | --backlog=size\n"
     77            "\tThe size of the accepted sockets queue. Only for SOCK_STREAM. "
     78            "The default is 3.\n"
     79            "\n"
     80            "-c count | --count=count\n"
     81            "\tThe number of received messages to handle. A negative number "
     82            "means infinity. The default is infinity.\n"
     83            "\n"
     84            "-f protocol_family | --family=protocol_family\n"
     85            "\tThe listenning socket protocol family. Only the PF_INET and "
     86            "PF_INET6 are supported.\n"
     87            "\n"
     88            "-h | --help\n"
     89            "\tShow this application help.\n"
     90            "\n"
     91            "-p port_number | --port=port_number\n"
     92            "\tThe port number the application should listen at. The default "
     93            "is 7.\n"
     94            "\n"
     95            "-r reply_string | --reply=reply_string\n"
     96            "\tThe constant reply string. The default is the original data "
     97            "received.\n"
     98            "\n"
     99            "-s receive_size | --size=receive_size\n"
     100            "\tThe maximum receive data size the application should accept. "
     101            "The default is 1024 bytes.\n"
     102            "\n"
     103            "-t socket_type | --type=socket_type\n"
     104            "\tThe listenning socket type. Only the SOCK_DGRAM and the "
     105            "SOCK_STREAM are supported.\n"
     106            "\n"
     107            "-v | --verbose\n"
     108            "\tShow all output messages.\n"
    100109        );
    101110}
    102111
    103 int main(int argc, char * argv[]){
    104         ERROR_DECLARE;
    105 
    106         size_t size                     = 1024;
    107         int verbose                     = 0;
    108         char * reply            = NULL;
    109         sock_type_t type        = SOCK_DGRAM;
    110         int count                       = -1;
    111         int family                      = PF_INET;
    112         uint16_t port           = 7;
    113         int backlog                     = 3;
    114 
    115         socklen_t max_length                            = sizeof(struct sockaddr_in6);
    116         uint8_t address_data[max_length];
    117         struct sockaddr * address                       = (struct sockaddr *) address_data;
    118         struct sockaddr_in * address_in         = (struct sockaddr_in *) address;
    119         struct sockaddr_in6 * address_in6       = (struct sockaddr_in6 *) address;
     112static int netecho_parse_option(int argc, char *argv[], int *index)
     113{
     114        int value;
     115        int rc;
     116
     117        switch (argv[*index][1]) {
     118        case 'b':
     119                rc = arg_parse_int(argc, argv, index, &backlog, 0);
     120                if (rc != EOK)
     121                        return rc;
     122                break;
     123        case 'c':
     124                rc = arg_parse_int(argc, argv, index, &count, 0);
     125                if (rc != EOK)
     126                        return rc;
     127                break;
     128        case 'f':
     129                rc = arg_parse_name_int(argc, argv, index, &family, 0,
     130                    socket_parse_protocol_family);
     131                if (rc != EOK)
     132                        return rc;
     133                break;
     134        case 'h':
     135                echo_print_help();
     136                exit(0);
     137                break;
     138        case 'p':
     139                rc = arg_parse_int(argc, argv, index, &value, 0);
     140                if (rc != EOK)
     141                        return rc;
     142                port = (uint16_t) value;
     143                break;
     144        case 'r':
     145                rc = arg_parse_string(argc, argv, index, &reply, 0);
     146                if (rc != EOK)
     147                        return rc;
     148                break;
     149        case 's':
     150                rc = arg_parse_int(argc, argv, index, &value, 0);
     151                if (rc != EOK)
     152                        return rc;
     153                size = (value >= 0) ? (size_t) value : 0;
     154                break;
     155        case 't':
     156                rc = arg_parse_name_int(argc, argv, index, &value, 0,
     157                    socket_parse_socket_type);
     158                if (rc != EOK)
     159                        return rc;
     160                type = (sock_type_t) value;
     161                break;
     162        case 'v':
     163                verbose = 1;
     164                break;
     165        /* Long options with double dash */
     166        case '-':
     167                if (str_lcmp(argv[*index] + 2, "backlog=", 6) == 0) {
     168                        rc = arg_parse_int(argc, argv, index, &backlog, 8);
     169                        if (rc != EOK)
     170                                return rc;
     171                } else if (str_lcmp(argv[*index] + 2, "count=", 6) == 0) {
     172                        rc = arg_parse_int(argc, argv, index, &count, 8);
     173                        if (rc != EOK)
     174                                return rc;
     175                } else if (str_lcmp(argv[*index] + 2, "family=", 7) == 0) {
     176                        rc = arg_parse_name_int(argc, argv, index, &family, 9,
     177                            socket_parse_protocol_family);
     178                        if (rc != EOK)
     179                                return rc;
     180                } else if (str_lcmp(argv[*index] + 2, "help", 5) == 0) {
     181                        echo_print_help();
     182                        exit(0);
     183                } else if (str_lcmp(argv[*index] + 2, "port=", 5) == 0) {
     184                        rc = arg_parse_int(argc, argv, index, &value, 7);
     185                        if (rc != EOK)
     186                                return rc;
     187                        port = (uint16_t) value;
     188                } else if (str_lcmp(argv[*index] + 2, "reply=", 6) == 0) {
     189                        rc = arg_parse_string(argc, argv, index, &reply, 8);
     190                        if (rc != EOK)
     191                                return rc;
     192                } else if (str_lcmp(argv[*index] + 2, "size=", 5) == 0) {
     193                        rc = arg_parse_int(argc, argv, index, &value, 7);
     194                        if (rc != EOK)
     195                                return rc;
     196                        size = (value >= 0) ? (size_t) value : 0;
     197                } else if (str_lcmp(argv[*index] + 2, "type=", 5) == 0) {
     198                        rc = arg_parse_name_int(argc, argv, index, &value, 7,
     199                            socket_parse_socket_type);
     200                        if (rc != EOK)
     201                                return rc;
     202                        type = (sock_type_t) value;
     203                } else if (str_lcmp(argv[*index] + 2, "verbose", 8) == 0) {
     204                        verbose = 1;
     205                } else {
     206                        echo_print_help();
     207                        return EINVAL;
     208                }
     209                break;
     210        default:
     211                echo_print_help();
     212                return EINVAL;
     213        }
     214
     215        return EOK;
     216}
     217
     218/** Echo one message (accept one connection and echo message).
     219 *
     220 * @param listening_id  Listening socket.
     221 * @return              EOK on success or negative error code.
     222 */
     223static int netecho_socket_process_message(int listening_id)
     224{
     225        uint8_t address_buf[sizeof(struct sockaddr_in6)];
     226
    120227        socklen_t addrlen;
     228        int socket_id;
     229        ssize_t rcv_size;
     230        size_t length;
     231        uint8_t *address_start;
     232
    121233        char address_string[INET6_ADDRSTRLEN];
    122         uint8_t * address_start;
    123         int socket_id;
    124         int listening_id;
    125         char * data;
    126         size_t length;
    127         int index;
    128         size_t reply_length;
    129         int value;
    130 
    131         // parse the command line arguments
    132         for(index = 1; index < argc; ++ index){
    133                 if(argv[index][0] == '-'){
    134                         switch(argv[index][1]){
    135                                 case 'b':
    136                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 0));
     234        struct sockaddr_in *address_in = (struct sockaddr_in *) address_buf;
     235        struct sockaddr_in6 *address_in6 = (struct sockaddr_in6 *) address_buf;
     236        struct sockaddr *address = (struct sockaddr *) address_buf;
     237
     238        int rc;
     239
     240        if (type == SOCK_STREAM) {
     241                /* Accept a socket if a stream socket is used */
     242                addrlen = sizeof(address_buf);
     243                socket_id = accept(listening_id, (void *) address_buf, &addrlen);
     244                if (socket_id <= 0) {
     245                        socket_print_error(stderr, socket_id, "Socket accept: ", "\n");
     246                } else {
     247                        if (verbose)
     248                                printf("Socket %d accepted\n", socket_id);
     249                }
     250
     251                assert((size_t) addrlen <= sizeof(address_buf));
     252        } else {
     253                socket_id = listening_id;
     254        }
     255
     256        /* if the datagram socket is used or the stream socked was accepted */
     257        if (socket_id > 0) {
     258
     259                /* Receive a message to echo */
     260                rcv_size = recvfrom(socket_id, data, size, 0, address,
     261                    &addrlen);
     262                if (rcv_size < 0) {
     263                        socket_print_error(stderr, rcv_size, "Socket receive: ", "\n");
     264                } else {
     265                        length = (size_t) rcv_size;
     266                        if (verbose) {
     267                                /* Print the header */
     268
     269                                /* Get the source port and prepare the address buffer */
     270                                address_start = NULL;
     271                                switch (address->sa_family) {
     272                                case AF_INET:
     273                                        port = ntohs(address_in->sin_port);
     274                                        address_start = (uint8_t *) &address_in->sin_addr.s_addr;
    137275                                        break;
    138                                 case 'c':
    139                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 0));
    140                                         break;
    141                                 case 'f':
    142                                         ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family));
    143                                         break;
    144                                 case 'h':
    145                                         echo_print_help();
    146                                         return EOK;
    147                                         break;
    148                                 case 'p':
    149                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    150                                         port = (uint16_t) value;
    151                                         break;
    152                                 case 'r':
    153                                         ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 0));
    154                                         break;
    155                                 case 's':
    156                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    157                                         size = (value >= 0) ? (size_t) value : 0;
    158                                         break;
    159                                 case 't':
    160                                         ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type));
    161                                         type = (sock_type_t) value;
    162                                         break;
    163                                 case 'v':
    164                                         verbose = 1;
    165                                         break;
    166                                 // long options with the double minus sign ('-')
    167                                 case '-':
    168                                         if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){
    169                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 8));
    170                                         }else if(str_lcmp(argv[index] + 2, "count=", 6) == 0){
    171                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 8));
    172                                         }else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    173                                                 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family));
    174                                         }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    175                                                 echo_print_help();
    176                                                 return EOK;
    177                                         }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
    178                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
    179                                                 port = (uint16_t) value;
    180                                         }else if(str_lcmp(argv[index] + 2, "reply=", 6) == 0){
    181                                                 ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 8));
    182                                         }else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){
    183                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
    184                                                 size = (value >= 0) ? (size_t) value : 0;
    185                                         }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
    186                                                 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type));
    187                                                 type = (sock_type_t) value;
    188                                         }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
    189                                                 verbose = 1;
    190                                         }else{
    191                                                 echo_print_help();
    192                                                 return EINVAL;
    193                                         }
     276                                case AF_INET6:
     277                                        port = ntohs(address_in6->sin6_port);
     278                                        address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
    194279                                        break;
    195280                                default:
    196                                         echo_print_help();
    197                                         return EINVAL;
     281                                        fprintf(stderr, "Address family %u (%#x) is not supported.\n",
     282                                            address->sa_family, address->sa_family);
     283                                }
     284
     285                                /* Parse source address */
     286                                if (address_start) {
     287                                        rc = inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string));
     288                                        if (rc != EOK) {
     289                                                fprintf(stderr, "Received address error %d\n", rc);
     290                                        } else {
     291                                                data[length] = '\0';
     292                                                printf("Socket %d received %zu bytes from %s:%d\n%s\n",
     293                                                    socket_id, length, address_string, port, data);
     294                                        }
     295                                }
    198296                        }
    199                 }else{
     297
     298                        /* Answer the request either with the static reply or the original data */
     299                        rc = sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen);
     300                        if (rc != EOK)
     301                                socket_print_error(stderr, rc, "Socket send: ", "\n");
     302                }
     303
     304                /* Close accepted stream socket */
     305                if (type == SOCK_STREAM) {
     306                        rc = closesocket(socket_id);
     307                        if (rc != EOK)
     308                                socket_print_error(stderr, rc, "Close socket: ", "\n");
     309                }
     310
     311        }
     312
     313        return EOK;
     314}
     315
     316
     317int main(int argc, char *argv[])
     318{
     319        struct sockaddr *address;;
     320        struct sockaddr_in address_in;
     321        struct sockaddr_in6 address_in6;
     322        socklen_t addrlen;
     323
     324        int listening_id;
     325        int index;
     326        int rc;
     327
     328        /* Parse command line arguments */
     329        for (index = 1; index < argc; ++index) {
     330                if (argv[index][0] == '-') {
     331                        rc = netecho_parse_option(argc, argv, &index);
     332                        if (rc != EOK)
     333                                return rc;
     334                } else {
    200335                        echo_print_help();
    201336                        return EINVAL;
     
    203338        }
    204339
    205         // check the buffer size
    206         if(size <= 0){
    207                 fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size);
     340        /* Check buffer size */
     341        if (size <= 0) {
     342                fprintf(stderr, "Receive size too small (%zu). Using 1024 bytes instead.\n", size);
    208343                size = 1024;
    209344        }
    210         // size plus the terminating null (\0)
     345
     346        /* size plus the terminating null character. */
    211347        data = (char *) malloc(size + 1);
    212         if(! data){
     348        if (!data) {
    213349                fprintf(stderr, "Failed to allocate receive buffer.\n");
    214350                return ENOMEM;
    215351        }
    216352
    217         // set the reply size if set
     353        /* Set the reply size if set */
    218354        reply_length = reply ? str_length(reply) : 0;
    219355
    220         // prepare the address buffer
    221         bzero(address_data, max_length);
    222         switch(family){
    223                 case PF_INET:
    224                         address_in->sin_family = AF_INET;
    225                         address_in->sin_port = htons(port);
    226                         addrlen = sizeof(struct sockaddr_in);
    227                         break;
    228                 case PF_INET6:
    229                         address_in6->sin6_family = AF_INET6;
    230                         address_in6->sin6_port = htons(port);
    231                         addrlen = sizeof(struct sockaddr_in6);
    232                         break;
    233                 default:
    234                         fprintf(stderr, "Protocol family is not supported\n");
    235                         return EAFNOSUPPORT;
    236         }
    237 
    238         // get a listening socket
     356        /* Prepare the address buffer */
     357        switch (family) {
     358        case PF_INET:
     359                address_in.sin_family = AF_INET;
     360                address_in.sin_port = htons(port);
     361                address = (struct sockaddr *) &address_in;
     362                addrlen = sizeof(address_in);
     363                break;
     364        case PF_INET6:
     365                address_in6.sin6_family = AF_INET6;
     366                address_in6.sin6_port = htons(port);
     367                address = (struct sockaddr *) &address_in6;
     368                addrlen = sizeof(address_in6);
     369                break;
     370        default:
     371                fprintf(stderr, "Protocol family is not supported\n");
     372                return EAFNOSUPPORT;
     373        }
     374
     375        /* Get a listening socket */
    239376        listening_id = socket(family, type, 0);
    240         if(listening_id < 0){
     377        if (listening_id < 0) {
    241378                socket_print_error(stderr, listening_id, "Socket create: ", "\n");
    242379                return listening_id;
    243380        }
    244381
    245         // if the stream socket is used
    246         if(type == SOCK_STREAM){
    247                 // check the backlog
    248                 if(backlog <= 0){
    249                         fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size);
     382        /* if the stream socket is used */
     383        if (type == SOCK_STREAM) {
     384                /* Check backlog size */
     385                if (backlog <= 0) {
     386                        fprintf(stderr, "Accepted sockets queue size too small (%zu). Using 3 instead.\n", size);
    250387                        backlog = 3;
    251388                }
    252                 // set the backlog
    253                 if(ERROR_OCCURRED(listen(listening_id, backlog))){
    254                         socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n");
    255                         return ERROR_CODE;
    256                 }
    257         }
    258 
    259         // bind the listenning socket
    260         if(ERROR_OCCURRED(bind(listening_id, address, addrlen))){
    261                 socket_print_error(stderr, ERROR_CODE, "Socket bind: ", "\n");
    262                 return ERROR_CODE;
    263         }
    264 
    265         if(verbose){
     389
     390                /* Set the backlog */
     391                rc = listen(listening_id, backlog);
     392                if (rc != EOK) {
     393                        socket_print_error(stderr, rc, "Socket listen: ", "\n");
     394                        return rc;
     395                }
     396        }
     397
     398        /* Bind the listening socket */
     399        rc = bind(listening_id, address, addrlen);
     400        if (rc != EOK) {
     401                socket_print_error(stderr, rc, "Socket bind: ", "\n");
     402                return rc;
     403        }
     404
     405        if (verbose)
    266406                printf("Socket %d listenning at %d\n", listening_id, port);
    267         }
    268 
    269         socket_id = listening_id;
    270 
    271         // do count times
    272         // or indefinitely if set to a negative value
    273         while(count){
    274 
    275                 addrlen = max_length;
    276                 if(type == SOCK_STREAM){
    277                         // acceept a socket if the stream socket is used
    278                         socket_id = accept(listening_id, address, &addrlen);
    279                         if(socket_id <= 0){
    280                                 socket_print_error(stderr, socket_id, "Socket accept: ", "\n");
    281                         }else{
    282                                 if(verbose){
    283                                         printf("Socket %d accepted\n", socket_id);
    284                                 }
    285                         }
    286                 }
    287 
    288                 // if the datagram socket is used or the stream socked was accepted
    289                 if(socket_id > 0){
    290 
    291                         // receive an echo request
    292                         value = recvfrom(socket_id, data, size, 0, address, &addrlen);
    293                         if(value < 0){
    294                                 socket_print_error(stderr, value, "Socket receive: ", "\n");
    295                         }else{
    296                                 length = (size_t) value;
    297                                 if(verbose){
    298                                         // print the header
    299 
    300                                         // get the source port and prepare the address buffer
    301                                         address_start = NULL;
    302                                         switch(address->sa_family){
    303                                                 case AF_INET:
    304                                                         port = ntohs(address_in->sin_port);
    305                                                         address_start = (uint8_t *) &address_in->sin_addr.s_addr;
    306                                                         break;
    307                                                 case AF_INET6:
    308                                                         port = ntohs(address_in6->sin6_port);
    309                                                         address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
    310                                                         break;
    311                                                 default:
    312                                                         fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family);
    313                                         }
    314                                         // parse the source address
    315                                         if(address_start){
    316                                                 if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){
    317                                                         fprintf(stderr, "Received address error %d\n", ERROR_CODE);
    318                                                 }else{
    319                                                         data[length] = '\0';
    320                                                         printf("Socket %d received %d bytes from %s:%d\n%s\n", socket_id, length, address_string, port, data);
    321                                                 }
    322                                         }
    323                                 }
    324 
    325                                 // answer the request either with the static reply or the original data
    326                                 if(ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen))){
    327                                         socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
    328                                 }
    329 
    330                         }
    331 
    332                         // close the accepted stream socket
    333                         if(type == SOCK_STREAM){
    334                                 if(ERROR_OCCURRED(closesocket(socket_id))){
    335                                         socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");
    336                                 }
    337                         }
    338 
    339                 }
    340 
    341                 // decrease the count if positive
    342                 if(count > 0){
    343                         -- count;
    344                         if(verbose){
    345                                 printf("Waiting for next %d packet(s)\n", count);
    346                         }
    347                 }
    348         }
    349 
    350         if(verbose){
     407
     408        /*
     409         * do count times
     410         * or indefinitely if set to a negative value
     411         */
     412        while (count) {
     413                rc = netecho_socket_process_message(listening_id);
     414                if (rc != EOK)
     415                        break;
     416
     417                /* Decrease count if positive */
     418                if (count > 0) {
     419                        count--;
     420                        if (verbose)
     421                                printf("Waiting for next %d message(s)\n", count);
     422                }
     423        }
     424
     425        if (verbose)
    351426                printf("Closing the socket\n");
    352         }
    353 
    354         // close the listenning socket
    355         if(ERROR_OCCURRED(closesocket(listening_id))){
    356                 socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");
    357                 return ERROR_CODE;
    358         }
    359 
    360         if(verbose){
     427
     428        /* Close listenning socket */
     429        rc = closesocket(listening_id);
     430        if (rc != EOK) {
     431                socket_print_error(stderr, rc, "Close socket: ", "\n");
     432                return rc;
     433        }
     434
     435        if (verbose)
    361436                printf("Exiting\n");
    362         }
    363437
    364438        return EOK;
Note: See TracChangeset for help on using the changeset viewer.