* Parse a database URL of form * scheme://[username[:password]@]hostname[:port]/database[?parameters] * * \param id filled id struct * \param url parsed URL * \return 0 if parsing was successful and -1 otherwise */
| 68 | * \return 0 if parsing was successful and -1 otherwise |
| 69 | */ |
| 70 | static int parse_db_url(struct db_id* id, const str* url) |
| 71 | { |
| 72 | #define SHORTEST_DB_URL "s://a/b" |
| 73 | #define SHORTEST_DB_URL_LEN (sizeof(SHORTEST_DB_URL) - 1) |
| 74 | |
| 75 | enum state { |
| 76 | ST_SCHEME, /* Scheme part */ |
| 77 | ST_SLASH1, /* First slash */ |
| 78 | ST_SLASH2, /* Second slash */ |
| 79 | ST_USER_HOST, /* Username or hostname */ |
| 80 | ST_PASS_PORT, /* Password or port part */ |
| 81 | ST_PASSWORD, /* Explicitly the password */ |
| 82 | ST_HOST, /* Hostname part */ |
| 83 | ST_HOST6, /* Hostname part IPv6 */ |
| 84 | ST_PORT, /* Port part */ |
| 85 | ST_UNIX_SOCKET, /* Unix socket */ |
| 86 | ST_DB, /* Database part */ |
| 87 | ST_PARAMS /* Parameters part */ |
| 88 | }; |
| 89 | |
| 90 | enum state st; |
| 91 | unsigned int len, i, ipv6_flag = 0; |
| 92 | const char* begin; |
| 93 | char* prev_token = NULL, *p; |
| 94 | str unix_socket_host = str_init("localhost"); |
| 95 | int have_pass = 0; |
| 96 | |
| 97 | if (!id || !url || !url->s) { |
| 98 | return -1; |
| 99 | } |
| 100 | |
| 101 | len = url->len; |
| 102 | if (len < SHORTEST_DB_URL_LEN) { |
| 103 | return -1; |
| 104 | } |
| 105 | |
| 106 | /* Initialize all attributes to 0 */ |
| 107 | memset(id, 0, sizeof(struct db_id)); |
| 108 | st = ST_SCHEME; |
| 109 | begin = url->s; |
| 110 | |
| 111 | /* to allow support for '/' characters in password => look ahead! */ |
| 112 | p = q_memchr(url->s, ':', len); |
| 113 | if (p && q_memchr(p, '@', len - (p - url->s))) |
| 114 | have_pass = 1; |
| 115 | |
| 116 | for(i = 0; i < len; i++) { |
| 117 | switch(st) { |
| 118 | case ST_SCHEME: |
| 119 | switch(url->s[i]) { |
| 120 | case ':': |
| 121 | st = ST_SLASH1; |
| 122 | if (dupl_string(&id->scheme, begin, url->s + i) < 0) goto err; |
| 123 | break; |
| 124 | } |
| 125 | break; |
| 126 | |
| 127 | case ST_SLASH1: |
no test coverage detected