]> sjero.net Git - linphone/blob - coreapi/enum.c
Aac-eld add missing header according to RFC3640 3.3.6
[linphone] / coreapi / enum.c
1 /*
2 linphone
3 Copyright (C) 2000-2009  Simon MORLAT (simon.morlat@linphone.org)
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 */
19
20 /* enum lookup code */
21
22 #ifndef _WIN32_WCE
23 #include <errno.h>
24 #endif
25
26 #include <string.h>
27
28 #include "enum.h"
29
30 #define DNS_ANSWER_MAX_SIZE 2048
31
32
33 static char *create_enum_domain(const char *number){
34         int len=strlen(number);
35         char *domain=ms_malloc((len*2)+10);
36         int i,j;
37         
38         for (i=0,j=len-1;j>=0;j--){
39                 domain[i]=number[j];
40                 i++;
41                 domain[i]='.';
42                 i++;
43         }
44         strcpy(&domain[i],"e164.arpa");
45         ms_message("enum domain for %s is %s",number,domain);
46         return domain;
47 }
48
49
50 static bool_t is_a_number(const char *str){
51         char *p=(char *)str;
52         bool_t res=FALSE;
53         bool_t space_found=FALSE;
54         for(;;p++){
55                 switch(p[0]){
56                         case '9':
57                         case '8':
58                         case '7':
59                         case '6':
60                         case '5':
61                         case '4':
62                         case '3':
63                         case '2':
64                         case '1':
65                         case '0':
66                                 res=TRUE;
67                                 if (space_found) return FALSE; /* avoid splited numbers */
68                                 break;
69                         case '\0':
70                                 return res;
71                                 break;
72                         case ' ':
73                                 space_found=TRUE;
74                                 break;
75                         default:
76                                 return FALSE;
77                 }
78         }
79         return FALSE;
80 }
81 //4970072278724
82 bool_t is_enum(const char *sipaddress, char **enum_domain){
83         char *p;
84         p=strstr(sipaddress,"sip:");
85         if (p==NULL) return FALSE; /* enum should look like sip:4369959250*/
86         else p+=4;
87         if (is_a_number(p)){
88                 if (enum_domain!=NULL){
89                         *enum_domain=create_enum_domain(p);
90                 }
91                 return TRUE;
92         }
93         return FALSE;
94 }
95
96
97
98 int enum_lookup(const char *enum_domain, enum_lookup_res_t **res){
99         int err;
100         //char dns_answer[DNS_ANSWER_MAX_SIZE];
101         char *begin,*end;
102         char *host_result, *command;
103         int i;
104         bool_t forkok;
105         /*
106         ns_msg handle;
107         int count;
108         
109         memset(&handle,0,sizeof(handle));
110         *res=NULL;
111         ms_message("Resolving %s...",enum_domain);
112         
113         err=res_search(enum_domain,ns_c_in,ns_t_naptr,dns_answer,DNS_ANSWER_MAX_SIZE);
114         if (err<0){
115                 ms_warning("Error resolving enum:",herror(h_errno));
116                 return -1;
117         }
118         ns_initparse(dns_answer,DNS_ANSWER_MAX_SIZE,&handle);
119         count=ns_msg_count(handle,ns_s_an);
120         
121         for(i=0;i<count;i++){
122                 ns_rr rr;
123                 memset(&rr,0,sizeof(rr));
124                 ns_parserr(&handle,ns_s_an,i,&rr);
125                 ms_message("data=%s",ns_rr_rdata(rr));
126         }
127         */
128         command=ms_strdup_printf("host -t naptr %s",enum_domain);
129         forkok=lp_spawn_command_line_sync(command,&host_result,&err);
130         ms_free(command);
131         if (forkok){
132                 if (err!=0){
133                         ms_warning("Host exited with %i error status.",err);
134                         return -1;
135                 }
136         }else{
137                 ms_warning("Could not spawn the \'host\' command.");
138                 return -1;
139         }               
140         ms_message("Answer received from dns (err=%i): %s",err,host_result);
141         
142         begin=strstr(host_result,"sip:");
143         if (begin==0) {
144                 ms_warning("No sip address found in dns naptr answer.");
145                 return -1;
146         }
147         *res=ms_malloc0(sizeof(enum_lookup_res_t));
148         err=0;
149         for(i=0;i<MAX_ENUM_LOOKUP_RESULTS;i++){
150                 end=strstr(begin,"!");
151                 if (end==NULL) goto parse_error;
152                 end[0]='\0';
153                 (*res)->sip_address[i]=ms_strdup(begin);
154                 err++;
155                 begin=strstr(end+1,"sip:");
156                 if (begin==NULL) break;
157         }
158         ms_free(host_result);
159         return err;
160
161         parse_error:
162                 ms_free(*res);
163                 ms_free(host_result);
164                 *res=NULL;
165                 ms_warning("Parse error in enum_lookup().");
166                 return -1;
167 }
168
169 void enum_lookup_res_free(enum_lookup_res_t *res){
170         int i;
171         for (i=0;i<MAX_ENUM_LOOKUP_RESULTS;i++){
172                 if (res->sip_address[i]!=NULL) ms_free(res->sip_address[i]);
173         }
174         ms_free(res);
175 }