common.c
changeset 8 4d38ccbeb93e
parent 2 69f8c0acaac7
child 11 082bfaf38cf0
equal deleted inserted replaced
7:446c0b816b91 8:4d38ccbeb93e
     1 #include <stdlib.h>
     1 #include <stdlib.h>
     2 #include <stdio.h>
     2 #include <stdio.h>
     3 #include <stdarg.h>
     3 #include <stdarg.h>
     4 #include <errno.h>
     4 #include <errno.h>
     5 #include <string.h>
     5 #include <string.h>
       
     6 #include <ctype.h>
     6 
     7 
     7 #include "common.h"
     8 #include "common.h"
     8 
     9 
     9 void die (const char *msg) {
    10 void die (const char *msg) {
    10     perror(msg);
    11     perror(msg);
    50     va_end(va);
    51     va_end(va);
    51 
    52 
    52     fprintf(stderr, "\n");
    53     fprintf(stderr, "\n");
    53     exit(EXIT_FAILURE);
    54     exit(EXIT_FAILURE);
    54 }
    55 }
       
    56 
       
    57 int parse_hostport (char *hostport, char **host, char **port) {
       
    58     char *c;
       
    59 
       
    60     char brace = 0, colon = 0;
       
    61 
       
    62     *host = *port = NULL;
       
    63 
       
    64     for (c = hostport; *c != '\0'; c++) {
       
    65         if (isspace(*c))
       
    66             continue;
       
    67 
       
    68         switch (*c) {
       
    69             case '[':
       
    70                 if (c > hostport) {
       
    71                     error("parse_hostport: %c must be first char, if any: %s", *c, hostport);
       
    72                     return -1;
       
    73                 }
       
    74                 
       
    75                 brace = *c;
       
    76                 break;
       
    77 
       
    78             case ']':
       
    79                 if (!brace) {
       
    80                     error("parse_hostport: %c without matching brace: %s", *c, hostport);
       
    81                     return -1;
       
    82                 }
       
    83 
       
    84                 if (!*host) {
       
    85                     error("parse_hostport: empty hostname: %s", hostport);
       
    86                     return -1;
       
    87                 }
       
    88 
       
    89                 brace = 0;
       
    90                 break;
       
    91             
       
    92             case ':':
       
    93                 if (brace) {
       
    94                     // colons inside braces are left as-is
       
    95                     continue;
       
    96                 }
       
    97 
       
    98                 if (!*host) {
       
    99                     error("parse_hostport: colon before hostname: %s", hostport);
       
   100                     return -1;
       
   101                 }
       
   102 
       
   103                 if (*port) {
       
   104                     error("parse_hostport: colon after port: %s", hostport);
       
   105                     return -1;
       
   106                 }
       
   107 
       
   108                 if (colon) {
       
   109                     error("parse_hostport: too many colons: %s", hostport);
       
   110                     return -1;
       
   111                 };
       
   112 
       
   113                 // finished parsing the host part, move on to the port part
       
   114                 colon = ':';
       
   115                 *c = '\0';
       
   116                 break;
       
   117 
       
   118             default:
       
   119                 if (!*host) {
       
   120                     // first char of the host
       
   121                     *host = c;
       
   122 
       
   123                 } else if (colon && !*port) {
       
   124                     // first char of the port
       
   125                     *port = c;
       
   126 
       
   127                 } // else a part of either, don't care about it
       
   128 
       
   129                 break;
       
   130         }
       
   131     }
       
   132 
       
   133     if (!*host) {
       
   134         error("parse_hostport: missing hostname: %s", hostport);
       
   135         return -1;
       
   136     }
       
   137 
       
   138     if (brace) {
       
   139         error("parse_hostport: missing close-brace for %c: %s", brace, hostport);
       
   140         return -1;
       
   141     }
       
   142 
       
   143     if (colon && !*port) {
       
   144         error("parse_hostport: missing port: %s", hostport);
       
   145         return -1;
       
   146     }
       
   147 
       
   148     return 0;
       
   149 }
       
   150