1 /*
2  * Project: udptunnel
3  * File: destination.c
4  *
5  * Copyright (C) 2009 Andreas Rottmann
6  * Contact: a.rottmann@gmx.at
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include "destination.h"
26 
destination_create(const char * address)27 destination_t *destination_create(const char *address)
28 {
29     destination_t *dst;
30     char *cp;
31 
32     dst = calloc(sizeof(destination_t), 1);
33     if (!dst)
34         goto fail;
35 
36     dst->data = strdup(address);
37     if (!dst->data)
38         goto fail;
39 
40     /* Break address into both host and port, both optional */
41     cp = strchr(dst->data, ':');
42     if (!cp)
43     {
44         dst->host = dst->data;
45         dst->port = NULL;
46     }
47     else if (cp == dst->data)
48     {
49         dst->host = NULL;
50         dst->port = cp + 1;
51     }
52     else
53     {
54         *cp = '\0';
55         dst->host = dst->data;
56         dst->port = cp + 1;
57     }
58 
59     return dst;
60 
61 fail:
62     if (dst)
63         destination_free(dst);
64     return NULL;
65 }
66 
destination_copy(destination_t * dst,destination_t * src,size_t len)67 destination_t *destination_copy(destination_t *dst, destination_t *src, size_t len)
68 {
69     size_t host_len, port_len;
70 
71     host_len = src->host ? strlen(src->host) : 0;
72     port_len = src->port ? strlen(src->port) : 0;
73 
74     dst->data = calloc(host_len + port_len + 2, 1);
75     if (!dst->data)
76         return NULL;
77 
78     if (host_len > 0)
79     {
80         dst->host = dst->data;
81         memcpy((char *)dst->host, src->host, host_len + 1);
82     }
83     else
84     {
85         dst->host = NULL;
86     }
87 
88     if (port_len > 0)
89     {
90         dst->port = dst->data + host_len + 1;
91         memcpy((char *)dst->port, src->port, port_len + 1);
92     }
93     else
94     {
95         dst->port = NULL;
96     }
97 
98     return dst;
99 }
100 
strcmp_null(const char * s1,const char * s2)101 static int strcmp_null(const char *s1, const char *s2)
102 {
103     if (!s1)
104     {
105         if (s2) return -1;
106         else   return 0;
107     }
108     else if (!s2)
109     {
110         if (s1) return 1;
111         else   return 0;
112     }
113     else
114         return strcmp(s1, s2);
115 }
116 
destination_cmp(destination_t * d1,destination_t * d2,size_t len)117 int destination_cmp(destination_t *d1, destination_t *d2, size_t len)
118 {
119     int cmp;
120 
121     cmp = strcmp_null(d1->host, d2->host);
122     if (cmp)
123         return cmp;
124     return strcmp_null(d1->port, d2->port);
125 }
126 
destination_free(destination_t * dst)127 void destination_free(destination_t *dst)
128 {
129     if (dst->data)
130         free(dst->data);
131     free(dst);
132 }
133