/*************************************************************************** * copyright : (C) 2004 by Hendrik Sattler * * mail : post@hendrik-sattler.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "pbookphone.h" #include "scmxx.h" #include "helper.h" #include "atcommand.h" #include "gtincl.h" #include #include #include #include void struct_pbook_phone_entry_init (struct pbook_phone_entry* p) { p->slot = 0; p->number = NULL; p->numtype = numtype(NULL); p->text = NULL; } void struct_pbook_phone_entry_delete (struct pbook_phone_entry* p) { mem_realloc(p->number,0); mem_realloc(p->text,0); } int pbook_phone_write_entry (struct pbook_phone_entry* entry) { char* temp; int retval = 1; at_gen_phonebook_write(entry->slot,entry->number, entry->numtype,(char*)entry->text); temp = at_read_line(); if (at_line_type(temp,NULL,NULL) != AT_RET_OK) retval = 0; mem_realloc(temp,0); return retval; } int pbook_phone_write (char* mem, struct pbook_phone_entry** entries) { unsigned int min,max; int nlen,tlen; unsigned long i = 0; unsigned long count = 0; char* text = NULL; if (!pbook_get_ranges(mem,1,&min,&max,&nlen,&tlen)) { errexit(_("getting limits of phonebook %s failed.\n"),mem); } for (i = 0; entries[i] != NULL; ++i) { if (min > entries[i]->slot || entries[i]->slot > max) { errexit (_("slot %d is out of range %d-%d.\n"),entries[i]->slot,min,max); } } count = i; if (count > max-min+1) { errexit(_("too many entries (max. %d).\n"),max-min+1); } if (count > 1) { print_verbose(0,_("Updating entries %s(%d-%d)...\n"),mem,min,max); text = mem_alloc(str_len(mem)+numlen(max)+3,1); for (i = 1; entries[i-1] != NULL; ++i) { if (pbook_phone_write_entry(entries[i-1]) == 0) return 0; sprintf(text,"%s(%u)",(mem)?mem:"",entries[i-1]->slot); console_print_status(STDERR_FILENO,text,str_len(text),&i,&count,1); } mem_realloc(text,0); console_print_status(STDERR_FILENO,_("done"),strlen(_("done")),&i,&count,1); if (count > 1) print_verbose(0,"%c",'\n'); } else { print_verbose(0,_("Updating one entry in slot %d of memory %s..."),entries[0]->slot,mem); if (pbook_phone_write_entry(entries[0]) == 0) return 0; } print_verbose(0,"%s\n",_("done")); return 1; } /* fill the pbook_phone_entry from a text line */ int pbook_phone_str2entry (char* line, struct pbook_phone_entry* entry) { //pointers in line char* slot; char* number; char* numtype; char* text; if (line == NULL || entry == NULL) return -1; /* Policy is to not trust in what the phone delivers * Thus, full checking must be done. * Format: slot,"number",numtype,"text" */ slot = line; while(isdigit((int)*line) && *line != 0) ++line; if (*line != ',' || *line == 0) return 0; ++line; if (*line != '"' || *line == 0) return 0; number = ++line; while (*line != '"' && *line != 0) ++line; if (*line != '"' || *line == 0) return 0; ++line; if (*line != ',' || *line == 0) return 0; numtype = ++line; while(isdigit((int)*line) && *line != 0) ++line; if (*line != ',' || *line == 0) return 0; ++line; if (*line != '"' || *line == 0) return 0; text = ++line; if ((line=strrchr(text-1,'"')) <= text-1) return 0; ++line; if (*line != 0) return 0; entry->slot = atoi(slot); entry->number = strn_dup(number,strchr(number,'"')-number); entry->numtype = atoi(numtype); entry->text = (unsigned char*)strn_dup(text,strrchr(text,'"')-text); return 1; } /* slot_max-slot_min can be used to loop over a limited range * The returned pointer is malloc'd, NULL-terminated list, * each list enty is malloc'd, too. */ #include struct pbook_phone_entry** pbook_phone_get_range (char* mem, unsigned int slot_min, unsigned int slot_max, int print_counter) { unsigned int i = 0; unsigned range = slot_max-slot_min+1; struct pbook_phone_entry** retval; struct pbook_phone_entry* buffer; struct pbook_phone_entry** vcfbuf; char* command; char* ausgabe; char* temp; enum return_code linestatus; int status; int enable_slot_range_test = 1; unsigned int j,k = 0; if (strcasecmp(mem,VCARD_PHONEBOOK_NAME) == 0) if (slot_min != slot_max) { retval = mem_alloc(((range*4)+1)*sizeof(*retval),0); for (i = slot_min; i <= slot_max; ++i) { //call this function recursively (one level) vcfbuf = pbook_phone_get_range(mem,i,i,print_counter); for (j = 0; vcfbuf[j] != NULL; ++j) { retval[k++] = vcfbuf[j]; } vcfbuf = mem_realloc(vcfbuf,0); } retval[k] = NULL; return retval; } else { command = at_sie_phonebook_vcf_read(slot_min, -1); enable_slot_range_test = 0; range = 4; } else if (strcasecmp(mem,"RD") == 0 || strcasecmp(mem,"CS") == 0) command = at_sie_phonebook_read_sorted(slot_min,slot_max); /* Get sorted pb */ else command = at_gen_phonebook_read(slot_min,slot_max); /* Get pb */ if (command != NULL) { ausgabe = at_read_line(); linestatus = at_line_type(ausgabe,command,&temp); } if (command == NULL || linestatus&AT_RET_ERROR) errexit(_("reading from phonebook %s failed: %s\n"),mem,temp); retval = mem_alloc((range+1)*sizeof(*retval),0); while ((linestatus == AT_RET_ANSWER || linestatus == AT_RET_OTHER) && i <= i+range-1) { buffer = mem_alloc(sizeof(**retval),0); struct_pbook_phone_entry_init(buffer); status = pbook_phone_str2entry(temp,buffer); if (status <= 0) errexit(_("parsing entry failed: %s\n"), temp); if (enable_slot_range_test) { if (buffer->slot > slot_max) errexit(_("phone returned unexpected entry %u\n"),buffer->slot); for (; i+slot_min < buffer->slot; ++i) { retval[i] = mem_alloc(sizeof(**retval),0); struct_pbook_phone_entry_init(retval[i]); retval[i]->slot = i+slot_min; if (verbosity_get() < VERBOSE_LEVEL_NOTICE && print_counter) print_verbose(0," %d",retval[i]->slot); } } retval[i] = buffer; if (strcasecmp(mem,VCARD_PHONEBOOK_NAME) == 0) retval[i]->slot = slot_min; if (verbosity_get() < VERBOSE_LEVEL_NOTICE && print_counter) print_verbose(0," %d",retval[i]->slot); mem_realloc(ausgabe,0); ausgabe = at_read_line(); linestatus = at_line_type(ausgabe,command,&temp); if (linestatus&AT_RET_ERROR) errexit(_("reading from phonebook %s failed: %s\n"),mem,temp); ++i; } if (enable_slot_range_test) { for (; i+slot_min <= slot_max; ++i) { retval[i] = mem_alloc(sizeof(**retval),0); struct_pbook_phone_entry_init(retval[i]); retval[i]->slot = i+slot_min; if (verbosity_get() < VERBOSE_LEVEL_NOTICE && print_counter) print_verbose(0," %d",retval[i]->slot); } } retval[i] = NULL; //termination of list return retval; } // number of requested number during a search #define search_delta 5 int pbook_phone_find_empty (char* mem, unsigned int startslot) { unsigned int min = -1, max = -1; unsigned int tempmax; int retval = -1; unsigned int i; struct pbook_phone_entry** temp; //reading available indexes if (!pbook_get_ranges(mem,0,&min,&max,NULL,NULL)) { errexit(_("getting limits of phonebook %s failed.\n"),mem); } if ((min == (unsigned int)0 && max == (unsigned int)0) || startslot > max) { //emty phonebook return -1; } print_verbose(0,"%s\n",_("Trying to find an empty slot...")); if (startslot < min) startslot = min; for (;startslot <= max && retval < 0; startslot += search_delta ) { tempmax = startslot+search_delta-1; if (tempmax > max) tempmax = max; temp = pbook_phone_get_range(mem,startslot,tempmax,0); for (i=0; temp[i] != NULL; ++i) { if (str_len(temp[i]->number) == 0 && str_len((char*)temp[i]->text) == 0 && retval < 0) { retval = temp[i]->slot; print_verbose(0,_("Detected empty slot %d\n"),retval); } struct_pbook_phone_entry_delete(temp[i]); } mem_realloc(temp,0); } return retval; } /* number of requesting numbers * higher means a little bit more speed * lower helps slow phones/SIM-cards to not time out */ #define delta 5 struct pbook_phone_entry** pbook_phone_get (char* mem) { unsigned cur_min, cur_max; unsigned int min = -1, max = -1; struct pbook_phone_entry** retval; struct pbook_phone_entry** temp; unsigned long i,j; //index in temp unsigned int k = 0; //index in retval char* text = NULL; //reading available indexes if (!pbook_get_ranges(mem,0,&min,&max,NULL,NULL)) { errexit(_("getting limits of phonebook %s failed.\n"),mem); } if (min == 0 && max == 0) { //emty phonebook return NULL; } text = mem_alloc(str_len(mem)+numlen(min)+numlen(max)+4,1); sprintf(text,"%s(%d-%d)",mem,min,max); print_verbose(0,"%s\n",_("Receiving phonebook entries...")); //4 times as big due to phonebook vcf retval = mem_alloc(((4*(max-min+1))+1)*sizeof(*retval),0); retval[0] = NULL; for (cur_min = min; cur_min <= (unsigned int)max; cur_min += delta) { cur_max = cur_min+delta-1; if (cur_max > (unsigned int)max) cur_max = max; i = cur_min-min; j = max-min+1; console_print_status(STDERR_FILENO,text,str_len(text),&i,&j,1); temp = pbook_phone_get_range(mem,cur_min,cur_max,0); i = 0; while (temp[i] != NULL) retval[k++] = temp[i++]; retval[k] = NULL; } i = max; console_print_status(STDERR_FILENO,text,str_len(text),&i,&i,1); mem_realloc(text,0); print_verbose(0,"%c",'\n'); return retval; }