1 /***************************************************************************
2 * copyright : (C) 2004 by Hendrik Sattler *
3 * mail : post@hendrik-sattler.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 ***************************************************************************/
11
12 #include "pbookphone.h"
13 #include "scmxx.h"
14 #include "helper.h"
15 #include "atcommand.h"
16 #include "gtincl.h"
17
18 #include <ctype.h>
19 #include <string.h>
20 #include <strings.h>
21 #include <unistd.h>
22
struct_pbook_phone_entry_init(struct pbook_phone_entry * p)23 void struct_pbook_phone_entry_init (struct pbook_phone_entry* p) {
24 p->slot = 0;
25 p->number = NULL;
26 p->numtype = numtype(NULL);
27 p->text = NULL;
28 }
struct_pbook_phone_entry_delete(struct pbook_phone_entry * p)29 void struct_pbook_phone_entry_delete (struct pbook_phone_entry* p) {
30 mem_realloc(p->number,0);
31 mem_realloc(p->text,0);
32 }
33
pbook_phone_write_entry(struct pbook_phone_entry * entry)34 int pbook_phone_write_entry (struct pbook_phone_entry* entry) {
35 char* temp;
36 int retval = 1;
37
38 at_gen_phonebook_write(entry->slot,entry->number,
39 entry->numtype,(char*)entry->text);
40 temp = at_read_line();
41 if (at_line_type(temp,NULL,NULL) != AT_RET_OK) retval = 0;
42 mem_realloc(temp,0);
43 return retval;
44 }
45
pbook_phone_write(char * mem,struct pbook_phone_entry ** entries)46 int pbook_phone_write (char* mem, struct pbook_phone_entry** entries) {
47 unsigned int min,max;
48 int nlen,tlen;
49 unsigned long i = 0;
50 unsigned long count = 0;
51 char* text = NULL;
52
53 if (!pbook_get_ranges(mem,1,&min,&max,&nlen,&tlen)) {
54 errexit(_("getting limits of phonebook %s failed.\n"),mem);
55 }
56
57 for (i = 0; entries[i] != NULL; ++i) {
58 if (min > entries[i]->slot || entries[i]->slot > max) {
59 errexit (_("slot %d is out of range %d-%d.\n"),entries[i]->slot,min,max);
60 }
61 }
62 count = i;
63 if (count > max-min+1) {
64 errexit(_("too many entries (max. %d).\n"),max-min+1);
65 }
66
67 if (count > 1) {
68 print_verbose(0,_("Updating entries %s(%d-%d)...\n"),mem,min,max);
69 text = mem_alloc(str_len(mem)+numlen(max)+3,1);
70 for (i = 1; entries[i-1] != NULL; ++i) {
71 if (pbook_phone_write_entry(entries[i-1]) == 0) return 0;
72 sprintf(text,"%s(%u)",(mem)?mem:"",entries[i-1]->slot);
73 console_print_status(STDERR_FILENO,text,str_len(text),&i,&count,1);
74 }
75 mem_realloc(text,0);
76 console_print_status(STDERR_FILENO,_("done"),strlen(_("done")),&i,&count,1);
77 if (count > 1) print_verbose(0,"%c",'\n');
78 } else {
79 print_verbose(0,_("Updating one entry in slot %d of memory %s..."),entries[0]->slot,mem);
80 if (pbook_phone_write_entry(entries[0]) == 0) return 0;
81 }
82 print_verbose(0,"%s\n",_("done"));
83 return 1;
84 }
85
86 /* fill the pbook_phone_entry from a text line
87 */
pbook_phone_str2entry(char * line,struct pbook_phone_entry * entry)88 int pbook_phone_str2entry (char* line,
89 struct pbook_phone_entry* entry)
90 {
91 //pointers in line
92 char* slot;
93 char* number;
94 char* numtype;
95 char* text;
96
97 if (line == NULL || entry == NULL) return -1;
98
99 /* Policy is to not trust in what the phone delivers
100 * Thus, full checking must be done.
101 * Format: slot,"number",numtype,"text"
102 */
103 slot = line;
104 while(isdigit((int)*line) && *line != 0) ++line;
105 if (*line != ',' || *line == 0) return 0;
106 ++line;
107 if (*line != '"' || *line == 0) return 0;
108 number = ++line;
109 while (*line != '"' && *line != 0) ++line;
110 if (*line != '"' || *line == 0) return 0;
111 ++line;
112 if (*line != ',' || *line == 0) return 0;
113 numtype = ++line;
114 while(isdigit((int)*line) && *line != 0) ++line;
115 if (*line != ',' || *line == 0) return 0;
116 ++line;
117 if (*line != '"' || *line == 0) return 0;
118 text = ++line;
119 if ((line=strrchr(text-1,'"')) <= text-1) return 0;
120 ++line;
121 if (*line != 0) return 0;
122
123 entry->slot = atoi(slot);
124 entry->number = strn_dup(number,strchr(number,'"')-number);
125 entry->numtype = atoi(numtype);
126 entry->text = (unsigned char*)strn_dup(text,strrchr(text,'"')-text);
127 return 1;
128 }
129
130 /* slot_max-slot_min can be used to loop over a limited range
131 * The returned pointer is malloc'd, NULL-terminated list,
132 * each list enty is malloc'd, too.
133 */
134 #include <unistd.h>
135 struct pbook_phone_entry**
pbook_phone_get_range(char * mem,unsigned int slot_min,unsigned int slot_max,int print_counter)136 pbook_phone_get_range (char* mem,
137 unsigned int slot_min,
138 unsigned int slot_max,
139 int print_counter)
140 {
141 unsigned int i = 0;
142 unsigned range = slot_max-slot_min+1;
143 struct pbook_phone_entry** retval;
144 struct pbook_phone_entry* buffer;
145 struct pbook_phone_entry** vcfbuf;
146 char* command;
147 char* ausgabe;
148 char* temp;
149 enum return_code linestatus;
150 int status;
151 int enable_slot_range_test = 1;
152 unsigned int j,k = 0;
153
154 if (strcasecmp(mem,VCARD_PHONEBOOK_NAME) == 0)
155 if (slot_min != slot_max) {
156 retval = mem_alloc(((range*4)+1)*sizeof(*retval),0);
157 for (i = slot_min; i <= slot_max; ++i) {
158 //call this function recursively (one level)
159 vcfbuf = pbook_phone_get_range(mem,i,i,print_counter);
160 for (j = 0; vcfbuf[j] != NULL; ++j) {
161 retval[k++] = vcfbuf[j];
162 }
163 vcfbuf = mem_realloc(vcfbuf,0);
164 }
165 retval[k] = NULL;
166 return retval;
167 } else {
168 command = at_sie_phonebook_vcf_read(slot_min, -1);
169 enable_slot_range_test = 0;
170 range = 4;
171 }
172 else
173 if (strcasecmp(mem,"RD") == 0 || strcasecmp(mem,"CS") == 0)
174 command = at_sie_phonebook_read_sorted(slot_min,slot_max); /* Get sorted pb */
175 else
176 command = at_gen_phonebook_read(slot_min,slot_max); /* Get pb */
177
178 if (command != NULL) {
179 ausgabe = at_read_line();
180 linestatus = at_line_type(ausgabe,command,&temp);
181 }
182 if (command == NULL || linestatus&AT_RET_ERROR)
183 errexit(_("reading from phonebook %s failed: %s\n"),mem,temp);
184
185 retval = mem_alloc((range+1)*sizeof(*retval),0);
186 while ((linestatus == AT_RET_ANSWER ||
187 linestatus == AT_RET_OTHER) &&
188 i <= i+range-1) {
189 buffer = mem_alloc(sizeof(**retval),0);
190 struct_pbook_phone_entry_init(buffer);
191 status = pbook_phone_str2entry(temp,buffer);
192 if (status <= 0) errexit(_("parsing entry failed: %s\n"), temp);
193
194 if (enable_slot_range_test) {
195 if (buffer->slot > slot_max) errexit(_("phone returned unexpected entry %u\n"),buffer->slot);
196 for (; i+slot_min < buffer->slot; ++i) {
197 retval[i] = mem_alloc(sizeof(**retval),0);
198 struct_pbook_phone_entry_init(retval[i]);
199 retval[i]->slot = i+slot_min;
200 if (verbosity_get() < VERBOSE_LEVEL_NOTICE && print_counter)
201 print_verbose(0," %d",retval[i]->slot);
202 }
203 }
204 retval[i] = buffer;
205 if (strcasecmp(mem,VCARD_PHONEBOOK_NAME) == 0) retval[i]->slot = slot_min;
206 if (verbosity_get() < VERBOSE_LEVEL_NOTICE && print_counter)
207 print_verbose(0," %d",retval[i]->slot);
208
209 mem_realloc(ausgabe,0);
210 ausgabe = at_read_line();
211 linestatus = at_line_type(ausgabe,command,&temp);
212 if (linestatus&AT_RET_ERROR) errexit(_("reading from phonebook %s failed: %s\n"),mem,temp);
213 ++i;
214 }
215 if (enable_slot_range_test) {
216 for (; i+slot_min <= slot_max; ++i) {
217 retval[i] = mem_alloc(sizeof(**retval),0);
218 struct_pbook_phone_entry_init(retval[i]);
219 retval[i]->slot = i+slot_min;
220 if (verbosity_get() < VERBOSE_LEVEL_NOTICE && print_counter)
221 print_verbose(0," %d",retval[i]->slot);
222 }
223 }
224 retval[i] = NULL; //termination of list
225 return retval;
226 }
227
228 // number of requested number during a search
229 #define search_delta 5
230
pbook_phone_find_empty(char * mem,unsigned int startslot)231 int pbook_phone_find_empty (char* mem, unsigned int startslot) {
232 unsigned int min = -1, max = -1;
233 unsigned int tempmax;
234 int retval = -1;
235 unsigned int i;
236 struct pbook_phone_entry** temp;
237
238 //reading available indexes
239 if (!pbook_get_ranges(mem,0,&min,&max,NULL,NULL)) {
240 errexit(_("getting limits of phonebook %s failed.\n"),mem);
241 }
242 if ((min == (unsigned int)0 && max == (unsigned int)0) ||
243 startslot > max)
244 {
245 //emty phonebook
246 return -1;
247 }
248
249 print_verbose(0,"%s\n",_("Trying to find an empty slot..."));
250 if (startslot < min) startslot = min;
251 for (;startslot <= max && retval < 0; startslot += search_delta ) {
252 tempmax = startslot+search_delta-1;
253 if (tempmax > max) tempmax = max;
254 temp = pbook_phone_get_range(mem,startslot,tempmax,0);
255 for (i=0; temp[i] != NULL; ++i) {
256 if (str_len(temp[i]->number) == 0 &&
257 str_len((char*)temp[i]->text) == 0 &&
258 retval < 0) {
259 retval = temp[i]->slot;
260 print_verbose(0,_("Detected empty slot %d\n"),retval);
261 }
262 struct_pbook_phone_entry_delete(temp[i]);
263 }
264 mem_realloc(temp,0);
265 }
266 return retval;
267 }
268
269 /* number of requesting numbers
270 * higher means a little bit more speed
271 * lower helps slow phones/SIM-cards to not time out
272 */
273 #define delta 5
274
275 struct pbook_phone_entry**
pbook_phone_get(char * mem)276 pbook_phone_get (char* mem) {
277 unsigned cur_min, cur_max;
278 unsigned int min = -1, max = -1;
279 struct pbook_phone_entry** retval;
280 struct pbook_phone_entry** temp;
281 unsigned long i,j; //index in temp
282 unsigned int k = 0; //index in retval
283 char* text = NULL;
284
285 //reading available indexes
286 if (!pbook_get_ranges(mem,0,&min,&max,NULL,NULL)) {
287 errexit(_("getting limits of phonebook %s failed.\n"),mem);
288 }
289 if (min == 0 && max == 0) {
290 //emty phonebook
291 return NULL;
292 }
293 text = mem_alloc(str_len(mem)+numlen(min)+numlen(max)+4,1);
294 sprintf(text,"%s(%d-%d)",mem,min,max);
295 print_verbose(0,"%s\n",_("Receiving phonebook entries..."));
296 //4 times as big due to phonebook vcf
297 retval = mem_alloc(((4*(max-min+1))+1)*sizeof(*retval),0);
298 retval[0] = NULL;
299 for (cur_min = min; cur_min <= (unsigned int)max; cur_min += delta) {
300 cur_max = cur_min+delta-1;
301 if (cur_max > (unsigned int)max) cur_max = max;
302 i = cur_min-min;
303 j = max-min+1;
304 console_print_status(STDERR_FILENO,text,str_len(text),&i,&j,1);
305 temp = pbook_phone_get_range(mem,cur_min,cur_max,0);
306 i = 0;
307 while (temp[i] != NULL) retval[k++] = temp[i++];
308 retval[k] = NULL;
309 }
310 i = max;
311 console_print_status(STDERR_FILENO,text,str_len(text),&i,&i,1);
312 mem_realloc(text,0);
313 print_verbose(0,"%c",'\n');
314 return retval;
315 }
316