added gentoo ebuilds
[libmixp.git] / libmixp / addr.c
blob7900508485e286ed9f8e2b3c0c3635e310d4422a
1 /*
2 Plan9 URI address handling.
4 Author(s): Enrico Weigelt, metux IT service <weigelt@metux.de>
6 */
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <9p-mixp/srv_addr.h>
12 #include <9p-mixp/err.h>
13 #include "mixp_local.h"
17 ninep://localhost:9999/
21 static MIXP_SERVER_ADDRESS* __parse_uri(const char* addr, const char* fulladdr, MIXP_PROTO_ID proto)
23 MIXP_SERVER_ADDRESS* as = calloc(1,sizeof(MIXP_SERVER_ADDRESS));
24 as->addrstr = strdup(fulladdr);
25 as->port = -1;
26 as->proto = proto;
28 char* tmp;
29 char buffer[4096]; // FIXME !
31 if ((tmp=strchr(addr,'/'))!=NULL)
33 as->path = strdup(tmp);
34 memset(&buffer, 0, sizeof(buffer));
35 strncpy(buffer,addr,(tmp-addr));
37 else
39 as->path=strdup("/");
40 strcpy(buffer,addr);
43 if ((tmp=strchr(buffer,':'))!=NULL)
45 *tmp=0;
46 tmp++;
47 as->hostname = strdup(buffer);
48 as->port = atoi(tmp);
50 else
52 as->hostname = strdup(buffer);
55 return as;
58 static MIXP_SERVER_ADDRESS* __parse_uri_unix(const char* addr, const char* fulladdr, MIXP_PROTO_ID proto)
60 MIXP_SERVER_ADDRESS* as = calloc(1,sizeof(MIXP_SERVER_ADDRESS));
61 as->addrstr = strdup(fulladdr);
62 as->port = -1;
63 as->proto = proto;
65 if (addr[0]=='/')
66 while (addr[1]=='/')
67 addr++;
69 as->path = strdup(addr);
70 as->hostname = strdup("");
72 return as;
75 static MIXP_SERVER_ADDRESS* __parse_old_tcp(const char* addr)
77 MIXP_SERVER_ADDRESS * a = calloc(1,sizeof(MIXP_SERVER_ADDRESS));
78 char buffer[4096];
79 strcpy(buffer,addr);
81 char* tmp = strchr(buffer,'!');
82 if (tmp)
84 *tmp=0;
85 tmp++;
86 a->port = atoi(tmp);
88 else
90 a->port = -1;
93 a->addrstr = strdup(addr);
94 a->proto = P9_PROTO_TCP;
95 a->hostname = buffer;
96 a->path = strdup("/");
98 return a;
101 static inline const char* cmpprefix(const char* str, const char* prefix)
103 int sz = strlen(prefix);
104 if (strncmp(str,prefix,sz)==0)
105 return str+sz;
106 else
107 return NULL;
110 MIXP_SERVER_ADDRESS* mixp_srv_addr_parse(const char* addr)
112 if (addr==NULL)
114 mixp_werrstr("null address given");
115 return NULL;
118 if (strlen(addr)>4096)
120 mixp_werrstr("address too long");
121 return NULL;
124 const char* c;
126 // --- try different URI schemes ---
128 // simple 9p:// scheme for implicit tcp
129 if ((c=cmpprefix(addr,"9p://")))
130 return __parse_uri(c, addr, P9_PROTO_TCP);
132 // explicit tcp
133 if ((c=cmpprefix(addr,"9p:tcp://")))
134 return __parse_uri(c, addr, P9_PROTO_TCP);
135 if ((c=cmpprefix(addr,"9p:tcp:/")))
136 return __parse_uri(c, addr, P9_PROTO_TCP);
138 // explicit unix
139 if (strncmp(addr,"9p:unix:/",9)==0)
140 return __parse_uri_unix(addr+8, addr, P9_PROTO_UNIX);
142 // shortcut 9p:/ scheme - implicit unix
143 if ((c=cmpprefix(addr,"9p:/")))
144 return __parse_uri(c, addr, P9_PROTO_TCP);
146 if ((c=cmpprefix(addr,"ninep://")))
147 return __parse_uri(c, addr, P9_PROTO_TCP);
149 if (strncmp(addr,"tcp!",4)==0)
150 return __parse_old_tcp(addr+4);
152 fprintf(stderr,"could not parse address \"%s\"\n", addr);
153 return NULL;
156 int mixp_srv_addr_free(MIXP_SERVER_ADDRESS* addr)
158 if (addr==NULL)
159 return -1;
161 if (addr->addrstr)
162 free(addr->addrstr);
163 if (addr->hostname)
164 free(addr->hostname);
165 if (addr->key)
166 free(addr->key);
167 if (addr->path)
168 free(addr->path);
169 if (addr->username)
170 free(addr->username);
172 free(addr);
173 return 0;