1 /***************************************************************************
2  *   copyright           : (C) 2002,2003,2004,2005 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 "scmxx.h"
13 #include "helper.h"
14 #include "memtypes.h"
15 #include "atcommand.h"
16 #include "gtincl.h"
17 #include "w32compat.h"
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <strings.h>
23 
get_revision(void)24 inline char* get_revision (void) {
25   at_command_send(AT_GEN_REVISION,NULL);
26   return at_get_value(AT_GEN_REVISION);
27 }
28 
get_phoneserial(void)29 inline char* get_phoneserial (void) {
30   at_command_send(AT_GEN_IMSI,NULL);
31   return at_get_value(AT_GEN_IMSI);
32 }
33 
get_simserial(void)34 inline char* get_simserial (void) {
35   at_command_send(AT_GEN_IMEI,NULL);
36   return at_get_value(AT_GEN_IMEI);
37 }
38 
pbook_select_mem(char * mem)39 int pbook_select_mem (char* mem) {
40   char* command;
41   char* temp;
42   enum return_code status;
43 
44   if (strcasecmp(mem,VCARD_PHONEBOOK_NAME) == 0) return 1;
45 
46   command = at_sie_phonebook_select(mem);
47   temp = at_read_line();
48   status = at_line_type(temp,NULL,NULL);
49   mem_realloc(temp,0);
50   if (status == AT_RET_OK) return 1;
51   else return 0;
52 }
53 
sms_select_mem(char * mem,struct slot_range * r,int * current_fill)54 int sms_select_mem (char* mem, struct slot_range* r,
55 		    int* current_fill)
56 {
57   char* temp;
58   char* ausgabe;
59   int retval = 0;
60 
61   if (str_len(mem) == 0) {
62     return 0;
63   }
64 
65   at_gen_sms_mem(mem,mem,NULL);
66   ausgabe = at_get_value(AT_GEN_SMS_MEM);
67   //example: +CPMS: 10,112,10,112,8,12
68   if (str_len(ausgabe) != 0) {
69     if (r != NULL) {
70       strncpy(r->name,mem,sizeof(r->name));
71       temp = strchr(ausgabe,',');
72       if (str_len(temp)) {
73 	r->min = 1;
74 	r->max = atoi(temp+1);
75       }
76     }
77     if (current_fill != NULL && str_len(ausgabe)) {
78       *current_fill = atoi(ausgabe);
79     }
80     retval = 1;
81   }
82   mem_realloc(ausgabe,0);
83   return retval;
84 }
85 
86 #include "ttyaccess.h"
87 #include <unistd.h>
88 
phone_reset(struct tty_access * hw)89 void phone_reset (struct tty_access* hw) {
90   print_verbose(0,"%s...",_("Sending reset frame"));
91   /* sending a sync frame
92    * the phone may not respond without it because it thinks that all
93    * send commands are still data from a previous run
94    */
95   hw->write("\x1a\r",2);
96   /* it might also happen that some phones are
97    * in "transparent/OBEX mode" and must be switched to "RCCP/GIPSY mode"
98    */
99   usleep(1010*1000);
100   hw->write("+++",3);
101   usleep(1010*1000);
102   hw->write("\r",1);
103   usleep(1000*1000);
104 
105   /* flush all data because we are not interested in it */
106   hw->flush();
107   print_verbose(0,"%s\n",_("done"));
108 }
109 
phone_init(int reset,struct tty_access * hw)110 int phone_init (int reset, struct tty_access* hw) {
111   int retval = 1;
112   char* ack;
113 
114   if (reset) { /* big reset */
115     phone_reset(hw);
116   } else { /* small reset */
117     hw->write("\r",1);
118     usleep(1000*1000);
119     hw->flush();
120   }
121   at_command_send(AT_GEN_INIT,NULL);
122   ack = at_read_line();
123   if (at_line_type(ack,NULL,NULL) != AT_RET_OK) {
124     mem_realloc(ack,0);
125     ack = at_read_line();
126     if (at_line_type(ack,NULL,NULL) != AT_RET_OK) {
127       retval = 0;
128     }
129   }
130   mem_realloc(ack,0);
131   return retval;;
132 }
133 
command_echo(int enable)134 int command_echo (int enable) {
135   char* command;
136   char* ack;
137   enum return_code status;
138   if (enable) {
139     command = AT_GEN_ECHO_ENABLE;
140   } else {
141     command = AT_GEN_ECHO_DISABLE;
142   }
143   at_command_send(command,NULL);
144   ack = at_read_line();
145   status = at_line_type(ack,NULL,NULL);
146   mem_realloc(ack,0);
147   return (status == AT_RET_OK);
148 }
149 
verbose_errors(int enable)150 int verbose_errors (int enable) {
151   char* parmlist;
152   char* ack;
153   enum return_code status;
154   if (enable) {
155     parmlist = "2";
156   } else {
157     parmlist = "0";
158   }
159   at_command_send(AT_GEN_ERROR,parmlist);
160   ack = at_read_line();
161   status = at_line_type(ack,NULL,NULL);
162   mem_realloc(ack,0);
163   return (status == AT_RET_OK);
164 }
165 
get_charset(void)166 char* get_charset (void) {
167   char* ausgabe;
168   char* temp;
169 
170   at_syntax_request(AT_GEN_CHARSET);
171   ausgabe = at_get_value(AT_GEN_CHARSET);
172   if (ausgabe != NULL) {
173     if (*ausgabe == '"' &&
174 	(temp = strchr(ausgabe,'"')) != NULL) {
175       temp = strn_dup(ausgabe+1,temp-ausgabe-1);
176       mem_realloc(ausgabe,0);
177       return temp;
178     }
179   }
180   return NULL;
181 }
182 
get_charsets(void)183 char** get_charsets (void) {
184   char* ausgabe;
185 
186   at_command_send(AT_GEN_CHARSET,"?");
187   ausgabe = at_get_value(AT_GEN_CHARSET);
188   //example: +CSCS: ("GSM","UCS2")
189   return at_parse_stringlist(ausgabe);
190 }
191 
set_charset(char * charset)192 int set_charset(char *charset) {
193   char *temp;
194   int  retval = 0;
195 
196   if (str_len(charset) == 0) {
197     errexit("%s\n",_("no charset specified."));
198   }
199   at_gen_charset(charset);
200   temp = at_read_line();
201   if (at_line_type(temp,NULL,NULL) == AT_RET_OK) {
202     retval = 1;
203   }
204   mem_realloc(temp,0);
205   return retval;
206 }
207 
set_smsc(char * number)208 void set_smsc (char* number) {
209   char* temp;
210   char* error;
211   enum return_code status;
212 
213   if (str_len(number) == 0) {
214     errexit("%s\n",_("no number specified."));
215   } else if (is_telephone_number(number) == 0) {
216     errexit("%s\n",_("no valid number specified."));
217   }
218   at_gen_smsc(number);
219   temp = at_read_line();
220   status = at_line_type(temp,AT_GEN_SMSC,&error);
221   if (status == AT_RET_OK) {
222     print_verbose(0,_("SMS server number was set to %s\n"),number);
223   } else {
224     errexit("%s\n", (status == AT_RET_ERROR) ? _("unknown cause") : error);
225   }
226   mem_realloc(temp,0);
227 }
228 
get_smsc(void)229 char* get_smsc (void) {
230   char* ausgabe;
231   char* temp;
232 
233   at_syntax_request(AT_GEN_SMSC);
234   ausgabe = at_get_value(AT_GEN_SMSC);
235   if (ausgabe != NULL && *ausgabe == '"') {
236     if ((temp=strstr(ausgabe,"\",")) != NULL) {
237       temp = strn_dup(ausgabe+1,temp-ausgabe-1);
238       mem_realloc(ausgabe,0);
239       return temp;
240     }
241   }
242   return NULL;
243 }
244 
245 #include "timeincl.h"
246 
set_time(void)247 void set_time (void) {
248   char* ack;
249   time_t seconds;
250   char timestr[20]; //6*2 + 7 + 1
251 
252   memset(timestr,0,sizeof(timestr));
253 
254   time(&seconds); //seconds since Unix
255   //string formatting with conversion to local time
256   strftime(timestr,sizeof(timestr),"\"%y/%m/%d,%H:%M:%S\"",localtime(&seconds));
257   at_command_send(AT_GEN_TIME,timestr);
258   ack = at_read_line();
259   if (at_line_type(ack,NULL,NULL) == AT_RET_OK) {
260     print_verbose(0,"%s\n",_("Time was synchronized"));
261   } else {
262     errexit("%s\n",_("Time could not be synchronized"));
263   }
264   mem_realloc(ack,0);
265 }
266 
get_timezone_offset_quarters()267 static int get_timezone_offset_quarters () {
268   int h = 0;
269   int m = 0;
270   time_t temp = 0;
271   struct tm* p = NULL;
272 
273   time(&temp);
274   p = localtime(&temp);
275   if (p != NULL) {
276     h = p->tm_hour;
277     m = p->tm_min;
278     p = gmtime(&temp);
279     if (p != NULL) {
280       h -= p->tm_hour;
281       m -= p->tm_min;
282     } else h = m = 0;
283   }
284   return (h*4)+(m/15);
285 }
286 
287 #include "smspdu.h"
get_time(void)288 struct tm* get_time (void) {
289   char* ausgabe;
290   struct sms_pdu_time t;
291   struct tm* p = NULL;
292   struct tm* ptemp = NULL;
293 
294   at_syntax_request(AT_GEN_TIME);
295   ausgabe = at_get_value(AT_GEN_TIME);
296   if (ausgabe != NULL) {
297     //example: +CCLK: "04/06/10,02:30:37"
298     sms_pdu_time_init(&t);
299     sms_pdu_time_fill(&t,ausgabe,get_timezone_offset_quarters());
300     p = mem_alloc(sizeof(*p),1);
301     ptemp = localtime(&t.value);
302     if (ptemp != NULL) memcpy(p,ptemp,sizeof(*p));
303     return p;
304   }
305   return NULL;
306 }
307 
get_simid(void)308 char* get_simid (void) {
309   char* ausgabe;
310 
311   ausgabe = at_get_vendor();
312   if(ausgabe != NULL &&
313      strcasecmp(ausgabe,"SIEMENS") == 0) {
314     at_command_send(AT_SIE_CARD_ID,NULL);
315     return at_get_value(AT_SIE_CARD_ID);
316   }
317   return NULL;
318 }
319 
get_operator(void)320 char* get_operator (void) {
321   char* ausgabe;
322   char* temp;
323 
324   at_syntax_request(AT_GEN_OPERATOR);
325   ausgabe = at_get_value(AT_GEN_OPERATOR);
326   if (ausgabe != NULL) {
327     //example: +COPS: 0,0,"E-Plus"
328     if ((temp=strchr(ausgabe,'"')) != NULL) {
329       temp = strn_dup(temp+1,strlen(temp+1)-1);
330       mem_realloc(ausgabe,0);
331       return temp;
332     }
333     mem_realloc(ausgabe,0);
334   }
335   return NULL;
336 }
337 
get_battery(void)338 char* get_battery (void) {
339   char* ausgabe;
340   char* temp;
341 
342   at_command_send(AT_GEN_BATTERY,NULL);
343   ausgabe = at_get_value(AT_GEN_BATTERY);
344   if (ausgabe != NULL) {
345     //example: +CBC: 0,80
346     if ((temp=strchr(ausgabe+6,',')) != NULL) {
347       temp=strn_dup(temp+1,strlen(temp+1));
348       mem_realloc(ausgabe,0);
349       return temp;
350     }
351     mem_realloc(ausgabe,0);
352   }
353   return NULL;
354 }
355 
get_signal(int * ber_p)356 int get_signal (int* ber_p) {
357   char* ausgabe;
358   char* temp;
359   int signal = -1;
360   int b;
361 
362 
363   if (ber_p != NULL) {
364     *ber_p = -1;
365   }
366   at_command_send(AT_GEN_SIGNAL,NULL);
367   ausgabe = at_get_value(AT_GEN_SIGNAL);
368   if (ausgabe != NULL) {
369     //example: +CSQ: 28,99
370     signal = atoi(ausgabe+6);
371     if (signal == 99) {
372       signal = -1;
373     } else {
374       if ((signal=111-((signal-1)*2)) < 0) {
375 	signal = -1;
376       }
377     }
378     if (ber_p != NULL) {
379       if ((temp=strchr(ausgabe,',')) != NULL) {
380 	b = atoi(temp+1);
381 	if (b == 7) {
382 	  *ber_p = 255;
383 	} else if (b >= 0 && b < 7) {
384 	  *ber_p = 2<<b;
385 	}
386       }
387     }
388     mem_realloc(ausgabe,0);
389   }
390   return signal;
391 }
392 
get_netstatus(unsigned int * areacode_p,unsigned int * cellid_p)393 char* get_netstatus (unsigned int* areacode_p, unsigned int* cellid_p) {
394   char* ausgabe;
395   char* index1;
396   char* index2;
397   char buffer;
398 
399   if (areacode_p != NULL) *areacode_p=0;
400   if (cellid_p != NULL) *cellid_p=0;
401 
402   at_command_send(AT_GEN_CSD_STATUS,"?");
403   ausgabe = at_get_value(AT_GEN_CSD_STATUS);
404   //example: +CREG: (0-2)
405   if (ausgabe != NULL && strchr(ausgabe,'2') == NULL) {
406     mem_realloc(ausgabe,0);
407     at_syntax_request(AT_GEN_CSD_STATUS);
408     ausgabe = at_get_value(AT_GEN_CSD_STATUS);
409   } else {
410     mem_realloc(ausgabe,0);
411     /* Fix: firmware may forget to send LAC/IC (e.g. ME45 v23,S55)
412      * Original was provided by Dominik Neubauer
413      */
414     at_command_send(AT_GEN_CSD_STATUS,"2");
415     ausgabe = at_read_line();
416     if (at_line_type(ausgabe,NULL,NULL) == AT_RET_OK) {
417       mem_realloc(ausgabe,0);
418       at_syntax_request(AT_GEN_CSD_STATUS);
419       ausgabe = at_get_value(AT_GEN_CSD_STATUS);
420       if (ausgabe != NULL) {
421 	at_command_send(AT_GEN_CSD_STATUS,"0");
422 	mem_realloc(at_read_line(),0);
423       }
424     } else {
425       ausgabe = mem_realloc(ausgabe,0);
426     }
427   }
428   //example: +CREG: 2,1,"0044","6E30"
429   if (ausgabe != NULL) {
430     index1 = strchr(ausgabe,'"');
431     if (index1 != NULL) {
432       index2 = strchr(++index1,'"');
433       if (index2 != NULL) {
434 	if (areacode_p != NULL) {
435 	  *areacode_p = hexstr2int(index1,index2-index1);
436 	}
437 	index1 = strchr(index2+1,'"');
438 	if (index1 != NULL) {
439 	  index2 = strchr(++index1,'"');
440 	  if (index2 != NULL && cellid_p != NULL) {
441 	    *cellid_p=hexstr2int(index1,index2-index1);
442 	  }
443 	}
444       }
445     }
446     if ((index1=strchr(ausgabe,',')) != NULL) {
447       buffer = index1[1];
448       mem_realloc(ausgabe,0);
449       switch (buffer) {
450       case '0':	return _("not checked in, not seeking");
451       case '1':	return _("checked in");
452       case '2':	return _("not checked in, but seeking a network");
453       case '3':	return _("check-in denied by network");
454       case '5':	return _("registered, roaming");
455       default:	return _("unknown status");
456       }
457     }
458   }
459   return NULL;
460 }
461 
get_gprs_status(unsigned int * areacode_p,unsigned int * cellid_p)462 char* get_gprs_status (unsigned int* areacode_p, unsigned int* cellid_p) {
463   char* ausgabe;
464   char* index1;
465   char* index2;
466   char buffer;
467 
468   if (areacode_p != NULL) *areacode_p=0;
469   if (cellid_p != NULL) *cellid_p=0;
470 
471   at_syntax_request(AT_GEN_GPRS_STATUS);
472   ausgabe = at_get_value(AT_GEN_GPRS_STATUS);
473   if (ausgabe != NULL) {
474     index1 = strchr(ausgabe,'"');
475     if (index1 != NULL) {
476       index2 = strchr(++index1,'"');
477       if (index2!=NULL) {
478 	if (areacode_p!=NULL) {
479 	  *areacode_p = hexstr2int(index1,index2-index1);
480 	}
481 	index1 = strchr(index2+1,'"');
482 	if (index1 != NULL) {
483 	  index2 = strchr(++index1,'"');
484 	  if (index2 != NULL && cellid_p != NULL) {
485 	    *cellid_p = hexstr2int(index1,index2-index1);
486 	  }
487 	}
488       }
489     }
490     if ((index1=strchr(ausgabe,',')) != NULL) {
491       buffer = index1[1];
492       mem_realloc(ausgabe,0);
493       switch (buffer) {
494       case '0':	return _("not registered, not searching");
495       case '1':	return _("registered, home network");
496       case '2':	return _("not registered, searching");
497       case '3':	return _("registration denied by network");
498       case '5':	return _("registered, roaming");
499       default:	return _("unknown status");
500       }
501     }
502   }
503   return NULL;
504 }
505 
get_gprs_attach(void)506 int get_gprs_attach (void) {
507   char* ausgabe;
508   char buffer;
509 
510   at_syntax_request(AT_GEN_GPRS_ATTACH);
511   ausgabe = at_get_value(AT_GEN_GPRS_ATTACH);
512   if (ausgabe != NULL) {
513     buffer = ausgabe[0];
514     mem_realloc(ausgabe,0);
515     switch (buffer) {
516     case '0': return 0;
517     case '1': return 1;
518     }
519   }
520   return -1;
521 }
522 
get_gprs_class(void)523 char* get_gprs_class (void) {
524   char* ausgabe;
525   char* temp;
526 
527   at_syntax_request(AT_GEN_GPRS_CLASS);
528   ausgabe = at_get_value(AT_GEN_GPRS_CLASS);
529   if (ausgabe != NULL) {
530     //example: +CGCLASS: "B"
531     if (ausgabe[0] == '"') {
532       memmove(ausgabe,ausgabe+1,strlen(ausgabe)+1);
533     }
534     if ((temp=strchr(ausgabe,'"')) != NULL) {
535       *temp = 0;
536     }
537     return ausgabe;
538   }
539   return NULL;
540 }
541 
info_misc(FILE * fd)542 void info_misc (FILE* fd) {
543   char *temp;
544   int i = 0, j;
545   unsigned int area = 0, cell = 0;
546   struct tm* ltime;
547   char** memlist;
548   unsigned int fieldsize = 0;
549   char* fields[19];
550   fields[0] = _("Vendor");
551   fields[1] = _("Model");
552   fields[2] = _("Revision");
553   fields[3] = "IMEI";
554   fields[4] = _("Battery");
555   fields[5] = _("Charsets");
556   fields[6] = _("Time");
557   fields[7] = "IMSI";
558   fields[8] = _("card ID");
559   fields[9] = _("Status");
560   fields[10] = _("Area code");
561   fields[11] = _("Cell ID");
562   fields[12] = _("Operator");
563   fields[13] = _("SMS server");
564   fields[14] = _("Signal");
565   fields[15] = "BER";
566   fields[16] = _("GPRS class");
567   fields[17] = _("GRPS status");
568   fields[18] = NULL;
569 
570   while (fields[i] != NULL) {
571     if (fieldsize < (size_t)str_width(fields[i])) fieldsize = str_width(fields[i]);
572     ++i;
573   }
574   fieldsize += 2;
575 
576   fprintf(fd,"%s:\n",_("Phone related information"));
577   fprintf(fd,"%s:%*s%s\n",fields[0],(int)(fieldsize-str_width(fields[0])),"",
578 	  temp=at_get_vendor());
579   mem_realloc(temp,0);
580   fflush(stdout);
581 
582   fprintf(fd,"%s:%*s%s\n",fields[1],(int)(fieldsize-str_width(fields[1])),"",
583 	  temp=at_get_model());
584   mem_realloc(temp,0);
585   fflush(stdout);
586 
587   fprintf(fd,"%s:%*s%s\n",fields[2],(int)(fieldsize-str_width(fields[2])),"",
588 	  temp=get_revision());
589   mem_realloc(temp,0);
590   fflush(stdout);
591 
592   fprintf(fd,"%s:%*s%s\n",fields[3],(int)(fieldsize-str_width(fields[3])),"",
593 	  temp=get_phoneserial());
594   mem_realloc(temp,0);
595   fflush(stdout);
596 
597   fprintf(fd,"%s:%*s%s%%\n",fields[4],(int)(fieldsize-str_width(fields[4])),"",
598 	  temp=get_battery());
599   mem_realloc(temp,0);
600   fflush(stdout);
601 
602   memlist=get_charsets();
603   fprintf(fd,"%s:%*s",fields[5],(int)(fieldsize-str_width(fields[5])),"");
604   if (memlist == NULL) {
605     fprintf(fd,_("none"));
606   } else {
607     for (i = 0; memlist[i] != NULL; ++i) {
608       if (i != 0) {
609         fprintf(fd,", ");
610       }
611       fprintf(fd,"%s",memlist[i]);
612     }
613   }
614   fprintf(fd,"\n");
615   mem_realloc(*memlist,0);
616   mem_realloc(memlist,0);
617   fflush(stdout);
618 
619   temp=mem_alloc(81,1);
620   ltime=get_time();
621   if (ltime!=NULL && strftime(temp,80,"%c",ltime)) {
622     fprintf(fd,"%s:%*s%s\n",fields[6],(int)(fieldsize-str_width(fields[6])),"",temp);
623     mem_realloc(ltime,0);
624   }
625   mem_realloc(temp,0);
626   fflush(stdout);
627 
628 
629 
630   fprintf(fd,"\n%s:\n",_("SIM card related information"));
631   fprintf(fd,"%s:%*s%s\n",fields[7],(int)(fieldsize-str_width(fields[7])),"",
632 	  temp=get_simserial());
633   mem_realloc(temp,0);
634   fflush(stdout);
635 
636   if ((temp=get_simid()) != NULL) {
637     fprintf(fd,"%s:%*s%s\n",fields[8],(int)(fieldsize-str_width(fields[8])),"",
638 	    temp);
639   }
640   mem_realloc(temp,0);
641   fflush(stdout);
642 
643 
644 
645   fprintf(fd,"\n%s:\n",_("Network related information"));
646   temp=get_netstatus(&area,&cell);
647   if (temp!=NULL) {
648     fprintf(fd,"%s:%*s%s\n",fields[9],(int)(fieldsize-str_width(fields[9])),"",
649 	    temp);
650     if (area) {
651       fprintf(fd,"%s:%*s%04X\n",fields[10],(int)(fieldsize-str_width(fields[10])),"",area);
652       if (cell) fprintf(fd,"%s:%*s%04X\n",fields[11],(int)(fieldsize-str_width(fields[11])),"",cell);
653     }
654   }
655   fflush(stdout);
656 
657   temp=get_operator();
658   if (temp!=NULL) {
659     fprintf(fd,"%s:%*s%s\n",fields[12],(int)(fieldsize-str_width(fields[12])),"",
660 	    temp);
661   }
662   mem_realloc(temp,0);
663   fflush(stdout);
664 
665   temp=get_smsc();
666   if (temp!=NULL) {
667     fprintf(fd,"%s:%*s%s\n",fields[13],(int)(fieldsize-str_width(fields[13])),"",
668 	    temp);
669   }
670   mem_realloc(temp,0);
671   fflush(stdout);
672 
673   if ((i=get_signal(&j)) >= 0) {
674     fprintf(fd,"%s:%*s%d dBm\n",fields[14],(int)(fieldsize-str_width(fields[14])),"",-i);
675     if (j >= 0) {
676       if (j <= 128) {
677 	      fprintf(fd,"%s:%*s<=%d,%d%%\n",fields[15],(int)(fieldsize-str_width(fields[15])),"",j/10,j%10);
678       } else {
679 	      fprintf(fd,"%s:%*s>12,8%%\n",fields[15],(int)(fieldsize-str_width(fields[15])),"");
680       }
681     }
682   }
683   fflush(stdout);
684 
685   temp=get_gprs_class();
686   if (temp!=NULL) {
687     fprintf(fd,"%s:%*s",fields[16],(int)(fieldsize-str_width(fields[16])),"");
688     temp=(char *)strtok(temp,"()\",");
689     while (temp!=0) {
690       fprintf(fd,"%s",temp);
691       temp=(char *)strtok(NULL,"()\",");
692       if (temp!=0) {
693 	      fprintf(fd,", ");
694       }
695     }
696     fprintf(fd,"\n");
697   }
698   mem_realloc(temp,0);
699   fflush(stdout);
700 
701   temp=get_gprs_status(NULL,NULL);
702   if (temp!=NULL) {
703     fprintf(fd,"%s:%*s%s",fields[17],(int)(fieldsize-str_width(fields[17])),"",
704 	    temp);
705     i=get_gprs_attach();
706     if (i==0) {
707       fprintf(fd,", %s\n",_("detached"));
708     } else if (i==1) {
709       fprintf(fd,", %s\n",_("attached"));
710     }
711   }
712   fflush(stdout);
713 }
714 
info_mem(FILE * fd,int full)715 void info_mem (FILE* fd, int full) {
716   unsigned int i = 0;
717   unsigned int fieldsize = 0;
718   char* fields[4];
719   fields[0] = _("Binary files");
720   fields[1] = _("Phonebooks");
721   fields[2] = _("SMS storages");
722   fields[3] = NULL;
723 
724   while (fields[i] != NULL) {
725     if (fieldsize < (size_t)str_width(fields[i])) fieldsize = str_width(fields[i]);
726     ++i;
727   }
728   fieldsize += 2;
729 
730   fprintf(fd,"%s:%*s",fields[0],(int)(fieldsize-str_width(fields[0])),"");
731   file_print_memlist(fd,full);
732   fprintf(fd,"%s:%*s",fields[1],(int)(fieldsize-str_width(fields[1])),"");
733   pbook_print_memlist(fd,full);
734   fprintf(fd,"%s:%*s",fields[2],(int)(fieldsize-str_width(fields[2])),"");
735   sms_print_memlist(fd,full);
736 }
737 
info(char * file,int misc,int mem,int lock)738 void info (char* file, int misc, int mem, int lock) {
739   if (misc || mem || lock) {
740     FILE* fd;
741     if (!str_len(file) || !strcmp(file,"-")) {
742       fd=stdout;
743     } else {
744       fd=fdopen(file_open_output(file),"w+");
745     }
746     if (misc) {
747       info_misc(fd);
748     }
749 
750     if (mem || misc) {
751       if (misc || lock) fprintf(fd,"\n%s:\n",_("Available memories"));
752       info_mem(fd,mem);
753     }
754 
755     if (lock || misc) {
756       if (misc || mem) fprintf(fd,"\n%s:\n",_("Settings"));
757       lock_print_list(fd,lock);
758     }
759 
760     if (str_len(file) && strcmp(file,"-")) {
761       fclose(fd);
762     }
763   }
764 }
765 
766