http://marcin-wiacek.fkn.pl/english/zips/mygnokii.tar.gz
[gnokii.git] / gnokii / gnokii.c
1 /*
2
3   G N O K I I
4
5   A Linux/Unix toolset and driver for Nokia mobile phones.
6
7   Released under the terms of the GNU GPL, see file COPYING for more details.
8         
9   Mainline code for gnokii utility.  Handles command line parsing and
10   reading/writing phonebook entries and other stuff.
11
12 */
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <signal.h>
17 #include <string.h>
18 #include <ctype.h>
19 #include <time.h>
20 #include <sys/stat.h>
21
22 #ifndef VC6
23   #if defined(__svr4__) || defined(__FreeBSD__)
24   #  include <strings.h>        /* for bzero */
25   #endif
26 #else
27   /* for VC6 make scripts save VERSION constant in mversion.h file */
28   #include "mversion.h"
29 #endif
30
31 #ifdef WIN32
32
33   #include <windows.h>
34
35   #include "misc_win32.h"
36   #include "getopt.h"
37
38   #define DEV_CONSOLE "CON:"
39
40 #else
41
42   #include <unistd.h>
43   #include <termios.h>
44   #include <fcntl.h>
45   #include <sys/types.h>
46   #include <sys/time.h>
47   #include <getopt.h>
48
49   #define DEV_CONSOLE "/dev/tty"
50 #endif
51
52 #include "misc.h"
53 #include "gsm-common.h"
54 #include "gsm-api.h"
55 #include "gsm-networks.h"
56 #include "gsm-ringtones.h"
57 #include "gsm-bitmaps.h"
58 #include "gsm-wap.h"
59 #include "gsm-sms.h"
60 #include "gsm-datetime.h"
61 #include "gsm-phonebook.h"
62 #include "gsm-calendar.h"
63 #include "gsm-coding.h"
64 #include "newmodules/n6110.h"
65 #include "files/cfgreader.h"
66 #include "files/gsm-filetypes.h"
67 #include "gnokii.h"
68
69 #ifdef USE_NLS
70   #include <locale.h>
71 #endif
72
73 char *model;           /* Model from .gnokiirc file. */
74 char *Port;            /* Port from .gnokiirc file */
75 char *Initlength;      /* Init length from .gnokiirc file */
76 char *Connection;      /* Connection type from .gnokiirc file */
77 char *SynchronizeTime; /* If we set date and time from computer to phone (from .gnokiirc file) */
78 char *BinDir;          /* Binaries directory from .gnokiirc file - not used here yet */
79
80 GSM_SMSMessage SMS[4];
81   
82 char *GetProfileCallAlertString(int code) {
83
84   switch (code) {
85     case PROFILE_CALLALERT_RINGING     : return "Ringing";
86     case PROFILE_CALLALERT_ASCENDING   : return "Ascending";
87     case PROFILE_CALLALERT_RINGONCE    : return "Ring once";
88     case PROFILE_CALLALERT_BEEPONCE    : return "Beep once";
89     case PROFILE_CALLALERT_CALLERGROUPS: return "Caller groups";
90     case PROFILE_CALLALERT_OFF         : return "Off";
91     default                            : return "Unknown";
92   }
93 }
94
95 char *GetProfileVolumeString(int code) {
96
97   switch (code) {
98     case PROFILE_VOLUME_LEVEL1 : return "Level 1";
99     case PROFILE_VOLUME_LEVEL2 : return "Level 2";
100     case PROFILE_VOLUME_LEVEL3 : return "Level 3";
101     case PROFILE_VOLUME_LEVEL4 : return "Level 4";
102     case PROFILE_VOLUME_LEVEL5 : return "Level 5";
103     default                    : return "Unknown";
104   }
105 }
106
107 char *GetProfileKeypadToneString(int code) {
108
109   switch (code) {
110     case PROFILE_KEYPAD_OFF    : return "Off";
111     case PROFILE_KEYPAD_LEVEL1 : return "Level 1";
112     case PROFILE_KEYPAD_LEVEL2 : return "Level 2";
113     case PROFILE_KEYPAD_LEVEL3 : return "Level 3";
114     default                    : return "Unknown";
115   }
116 }
117
118 char *GetProfileMessageToneString(int code) {
119
120   switch (code) {
121     case PROFILE_MESSAGE_NOTONE    : return "No tone";
122     case PROFILE_MESSAGE_STANDARD  : return "Standard";
123     case PROFILE_MESSAGE_SPECIAL   : return "Special";
124     case PROFILE_MESSAGE_BEEPONCE  : return "Beep once";
125     case PROFILE_MESSAGE_ASCENDING : return "Ascending";
126     default                        : return "Unknown";
127   }
128 }
129
130 char *GetProfileWarningToneString(int code) {
131
132   switch (code) {
133     case PROFILE_WARNING_OFF : return "Off";
134     case PROFILE_WARNING_ON  : return "On";
135     default                  : return "Unknown";
136   }
137 }
138
139 char *GetProfileOnOffString(int code) {
140
141   switch (code) {
142     case 0x00 : return "Off";
143     case 0x01 : return "On";
144     default   : return "Unknown";
145   }
146 }
147
148 static char *GetProfileVibrationString(int code)
149 {
150         switch (code) {
151         case PROFILE_VIBRATION_OFF:     return "Off";
152         case PROFILE_VIBRATION_ON:      return "On";
153         case PROFILE_VIBRATION_FIRST:   return "Vibrate first";
154         default:                        return "Unknown";
155         }
156 }
157
158 char BufferProfileGroups[90];
159
160 char *GetProfileCallerGroups(int code) 
161 {
162   static char az_group_name[5][MAX_BITMAP_TEXT_LENGTH];
163   static bool enteronce=false;
164   register int i;
165   GSM_Bitmap bitmap;
166
167   if( code == PROFILE_CALLERGROUPS_ALL )
168        return _("All calls alert");
169
170   if( !enteronce ) {
171     for(i=0;i<5;i++) az_group_name[i][0]='\0';
172     enteronce=true;
173   }
174
175   BufferProfileGroups[0]=0;
176     
177   for(i=0;i<5;i++)
178   {
179     int code2test;
180     char z_gtype[12];
181
182     code2test=(i==0) ? 1 : 2<<(i-1);
183
184     if( code & code2test )
185     {
186       if (!strcmp(az_group_name[i],"")) 
187       {
188         if (GetModelFeature (FN_CALLERGROUPS)!=0) {
189           bitmap.type=GSM_CallerLogo;
190           bitmap.number=i;
191           strcpy(z_gtype,_("unknown"));
192           if (GSM->GetBitmap(&bitmap)==GE_NONE)
193             strcpy( az_group_name[i], bitmap.text );
194         }
195         if ((!strcmp(az_group_name[i],""))) {
196             switch(i) {
197             case 0:strcpy(az_group_name[i],_("Family"));break;
198             case 1:strcpy(az_group_name[i],_("VIP"));break;
199             case 2:strcpy(az_group_name[i],_("Friends"));break;
200             case 3:strcpy(az_group_name[i],_("Colleagues"));break;
201             case 4:strcpy(az_group_name[i],_("Other"));break;
202             default:break;
203           }
204         }
205       }
206       strcpy(z_gtype,az_group_name[i]);
207
208       if( strlen(BufferProfileGroups) ) strcat(BufferProfileGroups,"+");
209       strcat(BufferProfileGroups, z_gtype);
210     }
211     
212   }
213
214   return BufferProfileGroups;
215 }
216
217 char *print_error(GSM_Error e)
218 {
219
220 //      case GE_DEVICEOPENFAILED:         return "Couldn't open specified serial device.";
221 //      case GE_UNKNOWNMODEL:             return "Model specified isn't known/supported.";
222 //      case GE_NOLINK:                   return "Couldn't establish link with phone.";
223 //      case GE_TRYAGAIN:                 return "Try again.";
224 //      case GE_INVALIDSMSLOCATION:       return "Invalid SMS location.";
225 //      case GE_INVALIDPHBOOKLOCATION:    return "Invalid phonebook location.";
226 //      case GE_INVALIDMEMORYTYPE:        return "Invalid type of memory.";
227 //      case GE_INVALIDSPEEDDIALLOCATION: return "Invalid speed dial location.";
228 //      case GE_INVALIDCALNOTELOCATION:   return "Invalid calendar note location.";
229 //      case GE_INVALIDDATETIME:          return "Invalid date, time or alarm specification.";
230 //      case GE_EMPTYSMSLOCATION:         return "SMS location is empty.";
231 //      case GE_PHBOOKNAMETOOLONG:        return "Phonebook name is too long.";
232 //      case GE_PHBOOKNUMBERTOOLONG:      return "Phonebook number is too long.";
233 //      case GE_PHBOOKWRITEFAILED:        return "Phonebook write failed.";
234 //      case GE_SMSSENDOK:                return "SMS was send correctly.";
235 //      case GE_SMSSENDFAILED:            return "SMS send fail.";
236 //      case GE_SMSTOOLONG:               return "SMS message too long.";
237 //      case GE_NONEWCBRECEIVED:          return "Attempt to read CB when no new CB received";
238 //      case GE_INTERNALERROR:            return "Problem occured internal to model specific code.";
239 //      case GE_NOTSUPPORTED:             return "Function not supported by the phone";
240 //      case GE_BUSY:                     return "Command is still being executed.";
241 //      case GE_USERCANCELED:             return "User has cancelled the action.";   
242 //      case GE_UNKNOWN:                  return "Unknown error - well better than nothing!!";
243 //      case GE_MEMORYFULL:               return "Memory is full";
244 //      case GE_LINEBUSY:                 return "Outgoing call requested reported line busy";
245 //      case GE_NOCARRIER:                return "No Carrier error during data call setup ?";
246
247         switch (e) {
248         case GE_NONE:                     return "No error, done OK";
249         case GE_INVALIDSECURITYCODE:      return "Invalid Security code.";
250         case GE_NOTIMPLEMENTED:           return "Called command is not implemented for the used model. Please contact marcin-wiacek@topnet.pl, if you want to help in implementing it";
251         case GE_TIMEOUT:                  return "Command timed out.";
252         case GE_CANTOPENFILE:             return "Can't open file with bitmap/ringtone";
253         case GE_SUBFORMATNOTSUPPORTED:    return "Subformat of file not supported";
254         case GE_WRONGNUMBEROFCOLORS:      return "Wrong number of colors in specified bitmap file (only 2 colors files supported)";
255         case GE_WRONGCOLORS:              return "Wrong colors in bitmap file";
256         case GE_INVALIDIMAGESIZE:         return "Invalid size of bitmap (in file, sms etc.)";
257         case GE_INVALIDFILEFORMAT:        return "Invalid format of file";
258         case GE_TOOSHORT:                 return "File too short";
259         case GE_INSIDEBOOKMARKSMENU:      return "Inside WAP Bookmarks menu. Please leave it and try again";
260         case GE_INVALIDBOOKMARKLOCATION:  return "Invalid or empty WAP bookmark location";
261         case GE_INSIDESETTINGSMENU:       return "Inside WAP Settings menu. Please leave it and try again";
262         case GE_INVALIDSETTINGSLOCATION:  return "Invalid or empty WAP settings location";
263         default:                          return "Unknown error.";
264         }
265 }
266
267
268 GSM_Error GSM_ReadRingtoneFileOnConsole(char *FileName, GSM_Ringtone *ringtone)
269 {
270   GSM_Error error;
271   
272   error=GSM_ReadRingtoneFile(FileName, ringtone);
273   
274   switch (error) {
275     case GE_CANTOPENFILE:
276     case GE_SUBFORMATNOTSUPPORTED:
277       fprintf(stderr, _("File \"%s\"\nError: %s\n"),FileName,print_error(error));
278       break;
279     default:
280       break;
281   }
282   
283   return error;
284 }
285
286 GSM_Error GSM_SaveRingtoneFileOnConsole(char *FileName, GSM_Ringtone *ringtone)
287 {
288   int confirm,confirm2;
289   char ans[4];
290   struct stat buf;
291   GSM_Error error;
292
293   /* Ask before overwriting */
294   while (stat(FileName, &buf) == 0) {
295   
296     confirm=-1;
297     confirm2=-1;
298     
299     while (confirm < 0) {
300       fprintf(stderr, _("Saving ringtone. File \"%s\" exists. (O)verwrite, create (n)ew or (s)kip ? "),FileName);
301       GetLine(stdin, ans, 4);
302       if (!strcmp(ans, "O") || !strcmp(ans, "o")) confirm = 1;
303       if (!strcmp(ans, "N") || !strcmp(ans, "n")) confirm = 2;
304       if (!strcmp(ans, "S") || !strcmp(ans, "s")) return GE_USERCANCELED;
305     }  
306     if (confirm==1) break;
307     if (confirm==2) {
308       while (confirm2 < 0) {
309         fprintf(stderr, _("Enter name of new file: "));
310         GetLine(stdin, FileName, 50);
311         if (&FileName[0]==0) return GE_USERCANCELED;
312         confirm2=1;
313       }  
314     }
315   }
316   
317   error=GSM_SaveRingtoneFile(FileName,ringtone);
318   
319   switch (error) {
320     case GE_CANTOPENFILE:        fprintf(stderr, _("Failed to write file \"%s\"\n"),FileName);
321                                  break;
322     default:                     break;
323   }
324   
325   return error;
326 }
327
328 GSM_Error GSM_ReadBitmapFileOnConsole(char *FileName, GSM_Bitmap *bitmap)
329 {
330   GSM_Error error;
331   
332   error=GSM_ReadBitmapFile(FileName, bitmap);
333
334   switch (error) {
335     case GE_CANTOPENFILE:
336     case GE_WRONGNUMBEROFCOLORS:
337     case GE_WRONGCOLORS:        
338     case GE_INVALIDFILEFORMAT:  
339     case GE_SUBFORMATNOTSUPPORTED:
340     case GE_TOOSHORT:
341     case GE_INVALIDIMAGESIZE:
342       fprintf(stderr, _("File \"%s\"\nError: %s\n"),FileName,print_error(error));
343       break;
344     default: 
345       break;
346   }
347   
348   return error;
349 }
350
351 GSM_Error GSM_SaveBitmapFileOnConsole(char *FileName, GSM_Bitmap *bitmap)
352 {
353   int confirm,confirm2;
354   char ans[4];
355   struct stat buf;
356   GSM_Error error;
357
358   /* Ask before overwriting */
359   while (stat(FileName, &buf) == 0) {
360   
361     confirm=-1;
362     confirm2=-1;
363     
364     while (confirm < 0) {
365       fprintf(stderr, _("Saving logo. File \"%s\" exists. (O)verwrite, create (n)ew or (s)kip ? "),FileName);
366       GetLine(stdin, ans, 4);
367       if (!strcmp(ans, "O") || !strcmp(ans, "o")) confirm = 1;
368       if (!strcmp(ans, "N") || !strcmp(ans, "n")) confirm = 2;
369       if (!strcmp(ans, "S") || !strcmp(ans, "s")) return GE_USERCANCELED;
370     }  
371     if (confirm==1) break;
372     if (confirm==2) {
373       while (confirm2 < 0) {
374         fprintf(stderr, _("Enter name of new file: "));
375         GetLine(stdin, FileName, 50);
376         if (&FileName[0]==0) return GE_USERCANCELED;
377         confirm2=1;
378       }  
379     }
380   }
381   
382   error=GSM_SaveBitmapFile(FileName,bitmap);
383   
384   switch (error) {
385     case GE_CANTOPENFILE:        fprintf(stderr, _("Failed to write file \"%s\"\n"),FileName);
386                                  break;
387     default:                     break;
388   }
389   
390   return error;
391 }
392
393 /* mode == 0 -> overwrite
394  * mode == 1 -> ask
395  * mode == 2 -> append
396  */
397 int GSM_SaveTextFileOnConsole(char *FileName, char *text, int mode)
398 {
399   int confirm, confirm2;
400   char ans[4];
401   struct stat buf;
402   int error;
403
404   /* Ask before overwriting */
405   if (mode==1) {
406     while (stat(FileName, &buf) == 0 && mode==1) {
407       
408       confirm=-1;
409       confirm2=-1;
410       
411       while (confirm < 0) {
412         fprintf(stderr, _("File \"%s\" exists. (O)verwrite, (a)ppend, create (n)ew or (s)kip ? "),FileName);
413         GetLine(stdin, ans, 4);
414         if (!strcmp(ans, "O") || !strcmp(ans, "o")) {
415           mode = 0;
416           confirm = 1;
417         }
418         if (!strcmp(ans, "A") || !strcmp(ans, "a")) {
419           mode = 2;
420           confirm = 1;
421         }
422         if (!strcmp(ans, "N") || !strcmp(ans, "n")) confirm=2;
423         if (!strcmp(ans, "S") || !strcmp(ans, "s")) return -1;
424       }
425       
426       if (confirm==2) {
427         while (confirm2 < 0) {
428           fprintf(stderr, _("Enter name of new file: "));
429           GetLine(stdin, FileName, 50);
430           if (&FileName[0]==0) return -1;
431           mode=1;
432           confirm2=1;
433         }  
434       }
435       
436     }  
437   }
438   
439   error=GSM_SaveTextFile(FileName, text, mode);
440   
441   switch (error) {
442     case -1: fprintf(stderr, _("Failed to write file \"%s\"\n"),  FileName);
443              break;
444     default: break;
445   }
446
447   return error;
448 }
449
450 int GSM_SendMultiPartSMSOnConsole(GSM_MultiSMSMessage *MultiSMS, int argnum, int argc, char *argv[],
451                                   bool unicode, bool profile, bool scale) {
452
453   int w,i;
454   
455   struct option options[] = {
456              { "smscno",       required_argument, NULL, '1'},
457              { "smsc",         required_argument, NULL, '2'},
458              { "name",         required_argument, NULL, '3'},
459              { "unicode",      no_argument,       NULL, '4'},
460              { "profilestyle", no_argument,       NULL, '5'},
461              { "scale",        no_argument,       NULL, '6'},
462              { NULL,           0,                 NULL,  0 }
463   };
464
465   GSM_Error error;  
466
467   for (w=0;w<MultiSMS->number;w++) {
468
469     if (argnum!=0) {
470       optarg = NULL;
471   
472       /* We check optional parameters from ... */
473       optind = argnum;
474
475       while ((i = getopt_long(argc, argv, "v:ds", options, NULL)) != -1) {
476         switch (i) {
477
478           case '1': /* SMSC number */
479             MultiSMS->SMS[w].MessageCenter.No = 0;
480             strcpy(MultiSMS->SMS[w].MessageCenter.Number,optarg);
481             break;
482
483           case '2': /* SMSC number index in phone memory */
484             MultiSMS->SMS[w].MessageCenter.No = atoi(optarg);
485
486             if (MultiSMS->SMS[w].MessageCenter.No < 1 || MultiSMS->SMS[w].MessageCenter.No > 5) {
487               fprintf(stderr, _("Incorrect SMSC number with \"smscno\" option (can't be <1 and >5) !\n"));
488               GSM->Terminate();
489               return -1;
490             }
491             break;
492
493           case '3': /* Receiver/recipient */
494             strncpy(MultiSMS->SMS[w].Destination,optarg,11); break;
495
496           case '4': /* Unicode */
497             if (unicode) break;
498
499           case '5': /* Profile */
500             if (profile) break;
501
502           case '6': /* Scale */
503             if (scale) break;
504
505           case 'v': /* Set validaty of SMS */
506             MultiSMS->SMS[w].Validity = atoi(optarg);
507             break;
508
509           case 'd': /* delivery report */
510             MultiSMS->SMS[w].Type=GST_DR;
511             break;      
512
513           case 's': /* Set replying via the same SMSC */
514             MultiSMS->SMS[w].ReplyViaSameSMSC = true; break;
515
516         default:
517           fprintf(stderr,_("Unknown option number %i\n"),argc);
518           GSM->Terminate();    
519           return -1;
520
521         }
522       }
523     }
524
525     error=GSM->SendSMSMessage(&MultiSMS->SMS[w]);
526
527     if (error == GE_SMSSENDOK) {
528       fprintf(stdout, _("SMS %i/%i sent OK !\n"),w+1,MultiSMS->number);
529     } else {
530       fprintf(stdout, _("SMS %i/%i, sending failed (error=%d)\n"),w+1,MultiSMS->number, error);
531     }
532
533   }
534
535   GSM->Terminate();  
536
537   return 0;
538 }
539
540 int GSM_SaveMultiPartSMSOnConsole(GSM_MultiSMSMessage *MultiSMS, int argnum, int argc, char *argv[],
541                                   bool inter, bool unicode, bool profile, bool scale) {
542
543   int w,i;
544   
545   GSM_SMSMessage SMSold;
546
547   struct option options[] = {
548              { "smscno",       required_argument, NULL, '1'},
549              { "smsc",         required_argument, NULL, '2'},
550              { "name",         required_argument, NULL, '3'},
551              { "unicode",      no_argument,       NULL, '4'},
552              { "profilestyle", no_argument,       NULL, '5'},
553              { "scale",        no_argument,       NULL, '6'},
554              { NULL,           0,                 NULL,  0 }
555   };
556
557   int interactive;
558   int confirm = -1;
559   char ans[8];
560
561   GSM_Error error;  
562
563   interactive = inter;
564
565   for (w=0;w<MultiSMS->number;w++) {
566
567     if (argnum!=0) {
568       optarg = NULL;
569   
570       /* We check optional parameters from ... */
571       optind = argnum;
572
573       while ((i = getopt_long(argc, argv, "risal:", options, NULL)) != -1) {
574         switch (i) {
575
576           case '1': /* SMSC number */
577             MultiSMS->SMS[w].MessageCenter.No = 0;
578             strcpy(MultiSMS->SMS[w].MessageCenter.Number,optarg);
579             break;
580
581           case '2': /* SMSC number index in phone memory */
582             MultiSMS->SMS[w].MessageCenter.No = atoi(optarg);
583
584             if (MultiSMS->SMS[w].MessageCenter.No < 1 || MultiSMS->SMS[w].MessageCenter.No > 5) {
585               fprintf(stderr, _("Incorrect SMSC number with \"smscno\" option (can't be <1 and >5) !\n"));
586               GSM->Terminate();
587               return -1;
588             }
589             break;
590
591           case '3': /* Receiver/recipient */
592             strncpy(MultiSMS->SMS[w].Destination,optarg,11); break;
593
594           case '4': /* Unicode */
595             if (unicode) break;
596
597           case '5': /* Profile */
598             if (profile) break;
599
600           case '6': /* Scale */
601             if (scale) break;
602
603           case 'r': /* mark as read */
604             MultiSMS->SMS[w].Status = GSS_SENTREAD; break;
605
606           case 'i': /* Save into Inbox */
607             MultiSMS->SMS[w].folder = GST_INBOX; break;
608           
609           case 's': /* Set replying via the same SMSC */
610             MultiSMS->SMS[w].ReplyViaSameSMSC = true; break;
611
612           case 'a': /* Ask before overwriting */
613             interactive=true;break;     
614         
615           case 'l': /* Specify location */
616             MultiSMS->SMS[0].Location = atoi(optarg); break;     
617
618         default:
619           fprintf(stderr,_("Unknown option number %i\n"),argc);
620           GSM->Terminate();    
621           return -1;
622         }
623       }
624     }
625
626     if (interactive && MultiSMS->SMS[0].Location!=0 && w==0) {
627       SMSold.Location=MultiSMS->SMS[0].Location;
628       error = GSM->GetSMSMessage(&SMSold);
629       switch (error) {
630         case GE_NONE:
631           fprintf(stderr, _("Message at specified location exists. "));
632           while (confirm < 0) {
633             fprintf(stderr, _("Overwrite? (yes/no) "));
634             GetLine(stdin, ans, 7);
635             if (!strcmp(ans, "yes")) confirm = 1;
636             if (!strcmp(ans, "no")) confirm = 0;
637           }  
638           if (!confirm) { GSM->Terminate(); return 0; }
639           else break;
640         case GE_INVALIDSMSLOCATION:
641           fprintf(stderr, _("Invalid location\n"));
642           GSM->Terminate();
643           return -1;
644         default:
645 /* FIXME: Remove this fprintf when the function is thoroughly tested */
646 #ifdef DEBUG
647             fprintf(stderr, _("Location %d empty. Saving\n"), SMS[w].Location);
648 #endif
649           break;
650       }
651     }
652
653     error=GSM->SaveSMSMessage(&MultiSMS->SMS[w]);
654
655     if (error == GE_NONE)
656       fprintf(stdout, _("SMS %i/%i saved at location %i !\n"),w+1,MultiSMS->number,MultiSMS->SMS[w].MessageNumber);
657     else
658       fprintf(stdout, _("SMS %i/%i saving failed (error=%d, location=%i)\n"), w+1, MultiSMS->number, error,MultiSMS->SMS[w].Location);
659   }
660
661   GSM->Terminate();  
662
663   return 0;
664 }
665
666 void GSM_PlayRingtoneOnConsole(GSM_Ringtone *ringtone)
667 {
668   int i;
669 #ifdef VC6
670   char mychar;
671 #endif
672
673   for (i=0;i<ringtone->NrNotes;i++) {
674 #ifdef VC6
675     if (_kbhit()) {
676       mychar=_getch();
677       break;
678     }
679 #endif
680     GSM_PlayOneNote (ringtone->notes[i]);
681   }
682   GSM->PlayTone(255*255,0);
683 }
684
685 /* This function shows the copyright and some informations usefull for
686    debugging. */
687 int version(void)
688 {
689
690   fprintf(stdout, _("GNOKII Version %s\n"
691 "Copyright (C) Hugh Blemings <hugh@linuxcare.com>, 1999, 2000\n"
692 "Copyright (C) Pavel Janík ml. <Pavel.Janik@linux.cz>, 1999, 2000\n"
693 "Built %s %s for %s on %s \n"), VERSION, __TIME__, __DATE__, model, Port);
694
695   return 0;
696 }
697
698 /* The function usage is only informative - it prints this program's usage and
699    command-line options. */
700
701 int usage(void)
702 {
703
704   fprintf(stdout, _("   usage: gnokii [--help|--monitor [-noloop|-nl]|--version]\n"
705 "          gnokii --getmemory memory_type [start [end]] [-short|-v30|-v21|-v]\n"
706 "          gnokii --writephonebook [-i]\n"
707 "          gnokii --sendphonebookentry destination memory_type location\n"
708 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
709 "                 [-s] [-v n] [-d]\n"
710 "          gnokii --savephonebookentry memory_type location\n"
711 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
712 "                 [-r] [-i] [-s] [-a] [--name name]\n"
713 "          gnokii --getvoicemailbox\n"
714 "          gnokii --getspeeddial number\n"
715 "          gnokii --setspeeddial number memory_type location\n\n"
716
717 "          gnokii --getsms memory_type start [end] [-f file]\n"
718 "          gnokii --getsmsstatus\n"
719 "          gnokii --getsmsfolders\n"
720 "          gnokii --deletesms memory_type start [end]\n"
721 "          gnokii --sendsms destination [--smsc message_center_number |\n"
722 "                 --smscno message_center_index] [--long n] [-s] [-C n]\n"
723 "                 [--enablevoice|--disablevoice|--enablefax|--disablefax|\n"
724 "                  --enableemail|--disableemail|--void][--unicode][-v n][-d]\n"
725 "          gnokii --savesms destination|\"\" [--smsc \n"
726 "                 message_center_number] [--smscno message_center_index]\n"
727 "                 [--long n] [-r] [-i] [-s][-C n][-a][-l][F n][--smsname name]\n"
728 "                 [--enablevoice|--disablevoice|--enablefax|--disablefax|\n"
729 "                  --enableemail|--disableemail|--void|--hang|--bug][--unicode]\n"
730 "          gnokii --receivesms\n"
731 "          gnokii --getsmsc message_center_number\n"
732 "          gnokii --renamesmsc number new_name\n\n"
733
734 "          gnokii --setdatetime [YYYY [MM [DD [HH [MM]]]]]\n"
735 "          gnokii --getdatetime\n"
736 "          gnokii --setalarm HH MM\n"
737 "          gnokii --getalarm\n\n"
738
739 "          gnokii --getcalendarnote { start end [-v30|-v10] | --short|-s }\n"
740 "          gnokii --writecalendarnote vcardfile number\n"
741 "          gnokii --deletecalendarnote index\n"
742 "          gnokii --sendcalendarnote destination vcardfile number\n"
743 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
744 "                 [-s] [-v n] [-d]\n"
745 "          gnokii --savecalendarnote vcardfile number\n"
746 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
747 "                 [-r] [-i] [-s] [-a] [--name name]\n\n"
748
749 "          gnokii --netmonitor {reset|off|field|devel|next|nr}\n"
750 "          gnokii --nm_collect screen1|-d [screen2|-d]...\n"
751 "          gnokii --netmonitordata [-S file] [-I file] [-h] [-n n] [-ts n][-tm n]\n"
752 "                 [-fs str] [-ls str] FLD1:FLD2:FLDn:... \n"
753 "                 (see files netmonitordata_????_??? for details)\n\n"
754
755 "          gnokii --bitmapconvert source destination\n"
756 "          gnokii --bitmapconvert source destination op|7110op [network code]\n"
757 "          gnokii --bitmapconvert source destination caller [caller group number]\n"
758 "          gnokii --bitmapconvert source destination\n"
759 "                   startup|7110startup|6210startup\n"
760 "          gnokii --bitmapconvert source destination picture\n"
761 "          gnokii --showbitmap logofile\n"
762 "          gnokii --sendlogo op destination logofile network_code\n"
763 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
764 "                 [-s] [-v n] [-d]\n"
765 "          gnokii --sendlogo picture destination logofile text\n"
766 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
767 "                 [-s] [-v n] [-d] [--unicode]\n"
768 "          gnokii --sendlogo screensaver destination logofile\n"
769 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
770 "                 [-s] [-v n] [-d]\n"
771 "          gnokii --sendlogo caller destination logofile\n"
772 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
773 "                 [-s] [-v n] [-d]\n"
774 "          gnokii --savelogo op logofile network_code\n"
775 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
776 "                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
777 "          gnokii --savelogo picture logofile text\n"
778 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
779 "                 [-r] [-i] [-s] [-a] [-l] [--name name] [--unicode]\n"
780 "          gnokii --savelogo screensaver logofile\n"
781 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
782 "                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
783 "          gnokii --savelogo caller logofile\n"
784 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
785 "                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
786 "          gnokii --setlogo op|7110op [logofile] [network code]\n"
787 "          gnokii --setlogo startup|7110startup|6210startup [logofile]\n"
788 "          gnokii --setlogo startup 1|2|3\n"
789 "          gnokii --setlogo caller [logofile] [caller group number] [group name]\n"
790 "          gnokii --setlogo picture [logofile] [number] [text] [sender]\n"
791 "          gnokii --setlogo {dealer|text} [text]\n"
792 "          gnokii --getlogo op|7110op [logofile] [network code]\n"
793 "          gnokii --getlogo startup|7110startup|6210startup [logofile]\n"
794 "          gnokii --getlogo caller [logofile][caller group number]\n"
795 "          gnokii --getlogo picture [logofile][number]\n"
796 "          gnokii --getlogo {dealer|text}\n\n"
797
798 "          gnokii --sendringtone destination ringtonefile\n"
799 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
800 "                 [-s] [-v n] [-d] [--scale] [--profilestyle]\n"
801 "          gnokii --saveringtone ringtonefile\n"
802 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
803 "                 [-r] [-i] [-s] [-a] [--name name] [--scale] [--profilestyle]\n"
804 "          gnokii --setringtone ringtonefile [location]\n"
805 "          gnokii --getringtone ringtonefile [location]\n"
806 "          gnokii --ringtoneconvert source destination\n"
807 "          gnokii --binringtoneconvert source destination\n"
808 "          gnokii --playringtone ringtonefile\n"
809 "          gnokii --composer ringtonefile\n"
810 "          gnokii --allringtones\n\n"
811
812 "          gnokii --getprofile [number]\n"
813 "          gnokii --setprofile number feature value\n"
814 "          gnokii --sendprofile destination profile_name ringtonefile\n"
815 "                 picturefile [--smsc message_center_number]\n"
816 "                 [--smscno message_center_index] [-s] [-v n] [-d] [--scale]\n\n"
817
818 "          gnokii --reset [soft|hard]\n"
819 "          gnokii --dialvoice number\n"
820 "          gnokii --cancelcall\n"
821 "          gnokii --displayoutput\n"
822 "          gnokii --presskeysequence sequence\n"
823 "          gnokii --backupsettings file\n"
824 "          gnokii --restoresettings file\n"
825 "          gnokii --getphoneprofile\n"
826 "          gnokii --setphoneprofile feature value\n"
827 "          gnokii --getoperatorname\n"
828 "          gnokii --setoperatorname code name\n"
829 "          gnokii --senddtmf string\n"
830 "          gnokii --divert register|enable|query|disable|erasure\n"
831 "                 all|busy|noans|outofreach all|voice|fax|data\n"
832 "                 [number timeout]\n\n"
833
834 "          gnokii --phonetests\n"
835 "          gnokii --simlock\n"
836 "          gnokii --getdisplaystatus\n"
837 "          gnokii --identify\n\n"
838
839 "          gnokii --getwapbookmark location\n"
840 "          gnokii --setwapbookmark title url [location]\n"
841 "          gnokii --sendwapbookmark location destination\n"
842 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
843 "                 [-s] [-v n] [-d]\n"
844 "          gnokii --savewapbookmark location\n"
845 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
846 "                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
847 "          gnokii --getwapsettings location\n"
848 "          gnokii --savewapsettings location\n"
849 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
850 "                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
851 "          gnokii --sendwapsettings location destination\n"
852 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
853 "                 [-s] [-v n] [-d]\n"
854   ));
855
856 #ifdef SECURITY
857   fprintf(stdout, _(
858 "\n          gnokii --entersecuritycode PIN|PIN2|PUK|PUK2\n"
859 "          gnokii --getsecuritycodestatus\n"
860 "          gnokii --getsecuritycode PIN|PIN2|PUK|PUK2|SecurityCode\n"
861 "          gnokii --geteeprom\n"
862 "          gnokii --resetphonesettings\n"
863   ));
864 #endif
865
866 #ifdef DEBUG
867   fprintf(stdout, _(
868 "          gnokii --sniff [port]\n"
869 "          gnokii --decodefile file\n"
870   ));
871 #endif
872
873   return 0;
874 }
875
876 /* fbusinit is the generic function which waits for the FBUS link. The limit
877    is 10 seconds. After 10 seconds we quit. */
878
879 void fbusinit(void (*rlp_handler)(RLP_F96Frame *frame))
880 {
881
882   int count=0;
883   GSM_Error error;
884
885 #ifndef WIN32
886   if (strcmp(GetMygnokiiVersion(),VERSION)!=0)
887     fprintf(stderr,_("WARNING: version of installed libmygnokii.so (%s) is different to version of gnokii (%s)\n"),GetMygnokiiVersion(),VERSION);
888 #endif
889
890   /* Initialise the code for the GSM interface. */     
891   error = GSM_Initialise(model, Port, Initlength, GetConnectionTypeFromString(Connection), rlp_handler, SynchronizeTime);
892
893   if (error != GE_NONE) {
894     fprintf(stderr, _("GSM/FBUS init failed! (Unknown model ?). Quitting.\n"));
895     exit(-1);
896   }
897
898   /* First (and important!) wait for GSM link to be active. We allow 10
899      seconds... */
900   while (count++ < 200 && *GSM_LinkOK == false)
901     usleep(50000);
902
903   if (*GSM_LinkOK == false) {
904     fprintf (stderr, _("Hmmm... GSM_LinkOK never went true. Quitting.\n"));
905     exit(-1);
906   }  
907 }
908
909 /* This function checks that the argument count for a given options is withing
910    an allowed range. */
911
912 int checkargs(int opt, struct gnokii_arg_len gals[], int argc)
913 {
914
915   int i;
916
917   /* Walk through the whole array with options requiring arguments. */
918
919   for(i = 0;!(gals[i].gal_min == 0 && gals[i].gal_max == 0); i++) {
920
921     /* Current option. */
922
923     if(gals[i].gal_opt == opt) {
924
925       /* Argument count checking. */
926
927       if(gals[i].gal_flags == GAL_XOR) {
928         if(gals[i].gal_min == argc || gals[i].gal_max == argc) return 0;
929       }
930       else {
931         if(gals[i].gal_min <= argc && gals[i].gal_max >= argc) return 0;
932       }
933
934       return 1;
935
936     }
937
938   }
939
940   /* We do not have options without arguments in the array, so check them. */
941
942   if (argc==0) return 0;
943           else return 1;
944 }
945
946 /* Main function - handles command line arguments, passes them to separate
947    functions accordingly. */
948
949 int main(int argc, char *argv[])
950 {
951
952   int c, i, rc = -1;
953   int nargc = argc-2;
954   char **nargv;
955
956   /* Every option should be in this array. */
957
958   static struct option long_options[] =
959   {
960
961     { "help",               no_argument,       NULL, OPT_HELP             },// Display usage.
962     { "version",            no_argument,       NULL, OPT_VERSION          },// Display version and build information.
963     { "getsmsfolders",      no_argument,       NULL, OPT_GETSMSFOLDERS    },// Gets SMS folders
964     { "getsmsstatus",       no_argument,       NULL, OPT_GETSMSSTATUS     },// Get SMS Folder Status
965     { "identify",           no_argument,       NULL, OPT_IDENTIFY         },// Identify
966     { "pmon",               no_argument,       NULL, OPT_PMON             },// For development purposes: run in passive monitoring mode
967     { "foogle",             no_argument,       NULL, OPT_FOOGLE           },// For development purposes: insert you function calls here
968     { "getdatetime",        no_argument,       NULL, OPT_GETDATETIME      },// Get date and time mode    
969     { "getalarm",           no_argument,       NULL, OPT_GETALARM         },// Get alarm    
970     { "cancelcall",         no_argument,       NULL, OPT_CANCELCALL       },// Cancel Call    
971     { "getdisplaystatus",   no_argument,       NULL, OPT_GETDISPLAYSTATUS },// Get display status mode    
972     { "allringtones",       no_argument,       NULL, OPT_ALLRINGTONES     },/* Displays names of available ringtones */    
973     { "displayoutput",      no_argument,       NULL, OPT_DISPLAYOUTPUT    },/* Show texts from phone's display */
974     { "getphoneprofile",    no_argument,       NULL, OPT_GETPHONEPROFILE  },/* Get/Set phone profile settings */
975     { "getoperatorname",    no_argument,       NULL, OPT_GETOPERATORNAME  },/* Get downloaded operator name */    
976     { "getvoicemailbox",    no_argument,       NULL, OPT_GETVOICEMAILBOX  },/* Gets voice mailbox number */    
977     { "phonetests",         no_argument,       NULL, OPT_PHONETESTS       },
978     { "simlockinfo",        no_argument,       NULL, OPT_SIMLOCKINFO      },    
979     { "receivesms",         no_argument,       NULL, OPT_RECEIVESMS       },    
980     { "setoperatorname",    optional_argument, NULL, OPT_SETOPERATORNAME  },/* Set downloaded operator name */    
981     { "setdatetime",        optional_argument, NULL, OPT_SETDATETIME      },// Set date and time    
982     { "writephonebook",     optional_argument, NULL, OPT_WRITEPHONEBOOK   },// Write phonebook (memory) mode
983     { "reset",              optional_argument, NULL, OPT_RESET            },// Resets the phone
984     { "monitor",            optional_argument, NULL, OPT_MONITOR          },// Monitor mode
985     { "setlogo",            optional_argument, NULL, OPT_SETLOGO          },// Set logo
986     { "getprofile",         optional_argument, NULL, OPT_GETPROFILE       },// Show profile
987     { "setalarm",           required_argument, NULL, OPT_SETALARM         },// Set alarm
988     { "dialvoice",          required_argument, NULL, OPT_DIALVOICE        },// Voice call mode
989     { "getcalendarnote",    required_argument, NULL, OPT_GETCALENDARNOTE  },// Get calendar note mode    
990     { "writecalendarnote",  required_argument, NULL, OPT_WRITECALENDARNOTE},// Write calendar note mode
991     { "sendcalendarnote",   required_argument, NULL, OPT_SENDCALENDARNOTE },
992     { "savecalendarnote",   required_argument, NULL, OPT_SAVECALENDARNOTE },
993     { "sendphonebookentry", required_argument, NULL, OPT_SENDPHONEBOOKENTRY},
994     { "savephonebookentry", required_argument, NULL, OPT_SAVEPHONEBOOKENTRY},
995     { "deletecalendarnote", required_argument, NULL, OPT_DELCALENDARNOTE  },// Delete calendar note mode    
996     { "getmemory",          required_argument, NULL, OPT_GETMEMORY        },// Get memory mode
997     { "getspeeddial",       required_argument, NULL, OPT_GETSPEEDDIAL     },// Get speed dial mode
998     { "setspeeddial",       required_argument, NULL, OPT_SETSPEEDDIAL     },// Set speed dial mode
999     { "getsms",             required_argument, NULL, OPT_GETSMS           },// Get SMS message mode
1000     { "deletesms",          required_argument, NULL, OPT_DELETESMS        },// Delete SMS message mode
1001     { "sendsms",            required_argument, NULL, OPT_SENDSMS          },// Send SMS message mode
1002     { "savesms",            required_argument, NULL, OPT_SAVESMS          },// Save SMS message mode
1003     { "sendlogo",           required_argument, NULL, OPT_SENDLOGO         },// Send logo as SMS message mode
1004     { "savelogo",           required_argument, NULL, OPT_SAVELOGO         },// Save logo on SIM
1005     { "sendringtone",       required_argument, NULL, OPT_SENDRINGTONE     },// Send ringtone as SMS message
1006     { "saveringtone",       required_argument, NULL, OPT_SAVERINGTONE     },// Saves ringtone on SIM
1007     { "setringtone",        required_argument, NULL, OPT_SETRINGTONE      },// Set ringtone    
1008     { "getringtone",        required_argument, NULL, OPT_GETRINGTONE      },// Get bin/normal ringtone    
1009     { "presskeysequence",   required_argument, NULL, OPT_PRESSKEYSEQUENCE },/* Presses keys in phone's display */
1010     { "getsmsc",            required_argument, NULL, OPT_GETSMSC          },// Get SMS center number mode
1011     { "renamesmsc",         required_argument, NULL, OPT_RENAMESMSC       },// Rename SMSC
1012     { "netmonitor",         required_argument, NULL, OPT_NETMONITOR       },// NetMonitor mode
1013     { "senddtmf",           required_argument, NULL, OPT_SENDDTMF         },// Send DTMF sequence
1014     { "getlogo",            required_argument, NULL, OPT_GETLOGO          },// Get logo
1015     { "setprofile",         required_argument, NULL, OPT_SETPROFILE       },// Set profile feature
1016     { "sendprofile",        required_argument, NULL, OPT_SENDPROFILE      },// Send profile via SMS
1017     { "setphoneprofile",    required_argument, NULL, OPT_SETPHONEPROFILE  },/* Get/Set phone profile settings */
1018     { "restoresettings",    required_argument, NULL, OPT_RESTORESETTINGS  },//Restore various settings from one file
1019     { "backupsettings",     required_argument, NULL, OPT_BACKUPSETTINGS   },//Backup various settings to one file
1020     { "playringtone",       required_argument, NULL, OPT_PLAYRINGTONE     },/* Plays ringtones */    
1021     { "composer",           required_argument, NULL, OPT_COMPOSER         },/* Shows ringtone like in Nokia Composer */    
1022     { "ringtoneconvert",    required_argument, NULL, OPT_RINGTONECONVERT  },/* Convert ringtone files */    
1023     { "binringtoneconvert", required_argument, NULL, OPT_BINRINGTONECONVERT},/* Convert binary ringtone files */    
1024     { "bitmapconvert",      required_argument, NULL, OPT_BITMAPCONVERT    },/* Convert bitmap files */    
1025     { "showbitmap",         required_argument, NULL, OPT_SHOWBITMAP       },    
1026     { "nm_collect",         required_argument, NULL, OPT_NM_COLLECT       },// NetMonitor periodical data collection mode (newbiee)
1027     { "netmonitordata",     required_argument, NULL, OPT_NETMONITORDATA   },// NetMonitor periodical data collection mode (advanced)
1028     { "getwapbookmark",     required_argument, NULL, OPT_GETWAPBOOKMARK   },    
1029     { "setwapbookmark",     required_argument, NULL, OPT_SETWAPBOOKMARK   },    
1030     { "savewapbookmark",    required_argument, NULL, OPT_SAVEWAPBOOKMARK  },    
1031     { "savewapsettings",    required_argument, NULL, OPT_SAVEWAPSETTINGS  },    
1032     { "sendwapsettings",    required_argument, NULL, OPT_SENDWAPSETTINGS  },    
1033     { "sendwapbookmark",    required_argument, NULL, OPT_SENDWAPBOOKMARK  },    
1034     { "getwapsettings",     required_argument, NULL, OPT_GETWAPSETTINGS   },    
1035     { "divert",             required_argument, NULL, OPT_DIVERT           },
1036
1037 #ifdef SECURITY
1038     { "entersecuritycode",  required_argument, NULL, OPT_ENTERSECURITYCODE    },// Enter Security Code mode
1039     { "getsecuritycode",    required_argument, NULL, OPT_GETSECURITYCODE      },// Get Security Code
1040   { "getsecuritycodestatus",no_argument,       NULL, OPT_GETSECURITYCODESTATUS},// Get Security Code status
1041     { "geteeprom",          no_argument,       NULL, OPT_GETEEPROM            },// Gets EEPROM
1042     { "resetphonesettings", no_argument,       NULL, OPT_RESETPHONESETTINGS   },// Reset phone settings
1043     { "setsimlock",         no_argument,       NULL, OPT_SETSIMLOCK           },// Sets simlock
1044 #endif
1045
1046 #ifdef DEBUG
1047     { "sniff",              optional_argument, NULL, OPT_SNIFFER    },// Will show datas from port
1048     { "decodefile",         required_argument, NULL, OPT_DECODEFILE },//decode input file
1049 #endif
1050
1051     { 0, 0, 0, 0},
1052   };
1053
1054   /* Every command which requires arguments should have an appropriate entry
1055      in this array. */
1056         
1057   struct gnokii_arg_len gals[] =
1058   {
1059
1060     { OPT_MONITOR,           0, 1, 0 },
1061
1062 #ifdef SECURITY
1063     { OPT_ENTERSECURITYCODE, 1, 1, 0 },
1064     { OPT_GETSECURITYCODE,   1, 1, 0 },
1065 #endif
1066
1067 #ifdef DEBUG
1068     { OPT_SNIFFER,           0, 1, 0 },
1069     { OPT_DECODEFILE,        1, 1, 0 },
1070 #endif
1071
1072     { OPT_SETDATETIME,       0, 5, 0 },
1073     { OPT_BACKUPSETTINGS,    1, 1, 0 },
1074     { OPT_RESTORESETTINGS,   1, 1, 0 },
1075     { OPT_SETALARM,          2, 2, 0 },
1076     { OPT_DIALVOICE,         1, 1, 0 },
1077     { OPT_GETCALENDARNOTE,   1, 3, 0 },
1078     { OPT_WRITECALENDARNOTE, 2, 2, 0 },
1079     { OPT_SAVECALENDARNOTE,  2, 9, 0 },
1080     { OPT_SENDCALENDARNOTE,  3, 9, 0 },
1081     { OPT_SAVEPHONEBOOKENTRY,2, 9, 0 },
1082     { OPT_SENDPHONEBOOKENTRY,3, 9, 0 },
1083     { OPT_DELCALENDARNOTE,   1, 1, 0 },
1084     { OPT_GETMEMORY,         2, 4, 0 },
1085     { OPT_GETSPEEDDIAL,      1, 1, 0 },
1086     { OPT_SETSPEEDDIAL,      3, 3, 0 },
1087     { OPT_GETSMS,            2, 5, 0 },
1088     { OPT_DELETESMS,         2, 3, 0 },
1089     { OPT_SENDSMS,           1,10, 0 },
1090     { OPT_SAVESMS,           1,11, 0 },
1091     { OPT_SENDLOGO,          3, 9, 0 },
1092     { OPT_SAVELOGO,          2,10, 0 },
1093     { OPT_SENDRINGTONE,      2, 7, 0 },
1094     { OPT_SAVERINGTONE,      1, 9, 0 },
1095     { OPT_GETSMSC,           1, 1, 0 },
1096     { OPT_RENAMESMSC,        2, 2, 0 },
1097     { OPT_NETMONITOR,        1, 1, 0 },
1098     { OPT_SENDDTMF,          1, 1, 0 },
1099     { OPT_SETLOGO,           1, 5, 0 },
1100     { OPT_GETLOGO,           1, 4, 0 },
1101     { OPT_SETRINGTONE,       1, 3, 0 },
1102     { OPT_GETRINGTONE,       1, 2, 0 },
1103     { OPT_PRESSKEYSEQUENCE,  1, 1, 0 },
1104     { OPT_RESET,             0, 1, 0 },
1105     { OPT_GETPROFILE,        0, 1, 0 },
1106     { OPT_SETPROFILE,        3, 3, 0 },
1107     { OPT_SENDPROFILE,       4,10, 0 },
1108     { OPT_WRITEPHONEBOOK,    0, 1, 0 },
1109     { OPT_PLAYRINGTONE,      1, 1, 0 },
1110     { OPT_COMPOSER,          1, 1, 0 },
1111     { OPT_RINGTONECONVERT,   2, 2, 0 },
1112     { OPT_BINRINGTONECONVERT,2, 2, 0 },
1113     { OPT_BITMAPCONVERT,     2, 4, 0 },
1114     { OPT_SHOWBITMAP,        1, 1, 0 },
1115     { OPT_SETOPERATORNAME,   0, 2, 0 },    
1116     { OPT_SETPHONEPROFILE,   2, 2, 0 },        
1117     { OPT_NM_COLLECT,        1, MAX_NM_COLLECT, 0 },
1118     { OPT_NETMONITORDATA,    0,99, 0 },
1119     { OPT_GETWAPBOOKMARK,    1, 1, 0 },
1120     { OPT_SETWAPBOOKMARK,    2, 3, 0 },
1121     { OPT_SAVEWAPBOOKMARK,   1, 9, 0 },
1122     { OPT_SENDWAPBOOKMARK,   2, 9, 0 },
1123     { OPT_GETWAPSETTINGS,    1, 1, 0 },
1124     { OPT_SAVEWAPSETTINGS,   1, 9, 0 },
1125     { OPT_SENDWAPSETTINGS,   2, 9, 0 },
1126     { OPT_DIVERT,            3, 5, 0 },    
1127
1128     { 0, 0, 0, 0 },
1129   };
1130
1131   opterr = 0;
1132
1133   /* For GNU gettext */
1134
1135 #ifdef USE_NLS
1136 #ifndef VC6
1137   textdomain("gnokii");
1138   setlocale(LC_ALL, "pl_PL"); //here is string for Polish localisation
1139 #else
1140   setlocale(LC_ALL, ".852"); //Polish codepage for console, not "real" WIN CP
1141 #endif
1142
1143 #endif
1144
1145     /* Read config file */
1146     if (CFG_ReadConfig(&model, &Port, &Initlength, &Connection, &BinDir, &SynchronizeTime,false) < 0) {
1147         exit(-1);
1148     }
1149
1150   /* Handle command line arguments. */
1151
1152   c = getopt_long(argc, argv, "", long_options, NULL);
1153
1154   if (c == -1) {
1155
1156     /* No argument given - we should display usage. */
1157     usage();
1158     exit(-1);
1159   }
1160
1161   /* We have to build an array of the arguments which will be passed to the
1162      functions.  Please note that every text after the --command will be
1163      passed as arguments.  A syntax like gnokii --cmd1 args --cmd2 args will
1164      not work as expected; instead args --cmd2 args is passed as a
1165      parameter. */
1166
1167   if((nargv = malloc(sizeof(char *) * argc)) != NULL) {
1168
1169     for(i = 2; i < argc; i++)
1170       nargv[i-2] = argv[i];
1171         
1172     if(checkargs(c, gals, nargc)) {
1173
1174       free(nargv);
1175
1176       /* Wrong number of arguments - we should display usage. */
1177       usage();
1178       exit(-1);
1179     }
1180
1181 #ifndef VC6
1182 #if defined(__svr4__)
1183     /* have to ignore SIGALARM */
1184     sigignore(SIGALRM);
1185 #endif
1186 #endif
1187
1188     switch(c) {
1189
1190     // First, error conditions  
1191     case '?':
1192       fprintf(stderr, _("Use '%s --help' for usage informations.\n"), argv[0]);
1193       break;
1194         
1195     // Then, options with no arguments
1196     case OPT_HELP:                  rc = usage();                   break;
1197     case OPT_VERSION:               rc = version();                 break;
1198     case OPT_MONITOR:               rc = monitormode(nargc, nargv); break;
1199     case OPT_GETSMSFOLDERS:         rc = getsmsfolders();           break;
1200     case OPT_GETDATETIME:           rc = getdatetime();             break;
1201     case OPT_GETALARM:              rc = getalarm();                break;
1202     case OPT_GETDISPLAYSTATUS:      rc = getdisplaystatus();        break;
1203     case OPT_PMON:                  rc = pmon();                    break;
1204     case OPT_WRITEPHONEBOOK:        rc = writephonebook(nargc, nargv);break;
1205
1206 #ifdef SECURITY
1207     case OPT_ENTERSECURITYCODE:     rc = entersecuritycode(optarg); break;
1208     case OPT_GETSECURITYCODESTATUS: rc = getsecuritycodestatus();   break;
1209     case OPT_GETSECURITYCODE:       rc = getsecuritycode(optarg);   break;
1210     case OPT_GETEEPROM:             rc = geteeprom();               break;
1211     case OPT_RESETPHONESETTINGS:    rc = resetphonesettings();      break;
1212     case OPT_SETSIMLOCK:            rc = setsimlock();              break;
1213 #endif
1214
1215 #ifdef DEBUG
1216     case OPT_SNIFFER:               rc = sniff(nargc, nargv);       break;
1217     case OPT_DECODEFILE:            rc = decodefile(nargc, nargv);  break;
1218 #endif                                  
1219         
1220     // Now, options with arguments
1221     case OPT_SETDATETIME:           rc = setdatetime(nargc, nargv); break;
1222     case OPT_SETALARM:              rc = setalarm(nargv);           break;
1223     case OPT_DIALVOICE:             rc = dialvoice(optarg);         break;
1224     case OPT_CANCELCALL:            rc = cancelcall();              break;
1225     case OPT_GETCALENDARNOTE:       rc = getcalendarnote(nargc, nargv);break;
1226     case OPT_DELCALENDARNOTE:       rc = deletecalendarnote(optarg);break;
1227     case OPT_SAVECALENDARNOTE:      rc = savecalendarnote(nargc, nargv);break;
1228     case OPT_SENDCALENDARNOTE:      rc = sendcalendarnote(nargc, nargv);break;
1229     case OPT_SAVEPHONEBOOKENTRY:    rc = savephonebookentry(nargc, nargv);break;
1230     case OPT_SENDPHONEBOOKENTRY:    rc = sendphonebookentry(nargc, nargv);break;
1231     case OPT_WRITECALENDARNOTE:     rc = writecalendarnote(nargv);  break;
1232     case OPT_GETMEMORY:             rc = getmemory(nargc, nargv);   break;
1233     case OPT_GETSPEEDDIAL:          rc = getspeeddial(optarg);      break;
1234     case OPT_SETSPEEDDIAL:          rc = setspeeddial(nargv);       break;
1235     case OPT_GETSMS:                rc = getsms(argc, argv);        break;
1236     case OPT_GETSMSSTATUS:          rc = getsmsstatus(argc, argv);  break;
1237     case OPT_DELETESMS:             rc = deletesms(nargc, nargv);   break;
1238     case OPT_SENDSMS:               rc = sendsms(nargc, nargv);     break;
1239     case OPT_SAVESMS:               rc = savesms(nargc, nargv);     break;
1240     case OPT_DIVERT:                rc = divert(nargc, nargv);      break;
1241     case OPT_SENDLOGO:              rc = sendlogo(nargc, nargv);    break;
1242     case OPT_SAVELOGO:              rc = savelogo(nargc, nargv);    break;
1243     case OPT_GETSMSC:               rc = getsmsc(optarg);           break;
1244     case OPT_RENAMESMSC:            rc = renamesmsc(nargc,nargv);   break;
1245     case OPT_NETMONITOR:            rc = netmonitor(optarg);        break;
1246     case OPT_IDENTIFY:              rc = identify();                break;
1247     case OPT_SETLOGO:               rc = setlogo(nargc, nargv);     break;
1248     case OPT_GETLOGO:               rc = getlogo(nargc, nargv);     break;
1249     case OPT_RECEIVESMS:            rc = receivesms(nargc, nargv);  break;
1250     case OPT_SETRINGTONE:           rc = setringtone(nargc, nargv); break;
1251     case OPT_GETRINGTONE:           rc = getringtone(nargc, nargv); break;
1252     case OPT_PRESSKEYSEQUENCE:      rc = presskeysequence(nargv);   break;
1253     case OPT_SENDRINGTONE:          rc = sendringtone(nargc, nargv);break;
1254     case OPT_SAVERINGTONE:          rc = saveringtone(nargc, nargv);break;
1255     case OPT_GETPROFILE:            rc = getprofile(nargc, nargv);  break;
1256     case OPT_SETPROFILE:            rc = setprofile(nargc, nargv);  break;
1257     case OPT_SENDPROFILE:           rc = sendprofile(nargc, nargv); break;
1258     case OPT_DISPLAYOUTPUT:         rc = displayoutput();           break;
1259     case OPT_RESTORESETTINGS:       rc = restoresettings(nargv);    break;
1260     case OPT_BACKUPSETTINGS:        rc = backupsettings(nargv);     break;
1261     case OPT_RINGTONECONVERT:       rc = ringtoneconvert(nargc, nargv);break;
1262     case OPT_BINRINGTONECONVERT:    rc = binringtoneconvert(nargc, nargv);break;
1263     case OPT_BITMAPCONVERT:         rc = bitmapconvert(nargc, nargv);break;
1264     case OPT_SHOWBITMAP:            rc = showbitmap(nargc, nargv);  break;
1265     case OPT_PLAYRINGTONE:          rc = playringtone(nargc, nargv);break;
1266     case OPT_COMPOSER:              rc = composer(nargc, nargv);    break;
1267     case OPT_FOOGLE:                rc = foogle(nargv);             break;
1268     case OPT_PHONETESTS:            rc = phonetests();              break;
1269     case OPT_SIMLOCKINFO:           rc = simlockinfo();             break;
1270     case OPT_SENDDTMF:              rc = senddtmf(optarg);          break;
1271     case OPT_RESET:                 rc = reset(nargc,nargv);        break;
1272     case OPT_GETOPERATORNAME:       rc = getoperatorname();         break;
1273     case OPT_SETOPERATORNAME:       rc = setoperatorname(nargc,nargv);break;
1274     case OPT_GETWAPBOOKMARK:        rc = getwapbookmark(nargc,nargv);break;
1275     case OPT_SETWAPBOOKMARK:        rc = setwapbookmark(nargc,nargv);break;
1276     case OPT_SAVEWAPBOOKMARK:       rc = savewapbookmark(nargc,nargv);break;
1277     case OPT_SENDWAPBOOKMARK:       rc = sendwapbookmark(nargc,nargv);break;
1278     case OPT_GETWAPSETTINGS:        rc = getwapsettings(nargc,nargv);break;
1279     case OPT_SAVEWAPSETTINGS:       rc = savewapsettings(nargc,nargv);break;
1280     case OPT_SENDWAPSETTINGS:       rc = sendwapsettings(nargc,nargv);break;
1281     case OPT_ALLRINGTONES:          rc = allringtones();            break;
1282     case OPT_GETPHONEPROFILE:       rc = getphoneprofile();         break;
1283     case OPT_SETPHONEPROFILE:       rc = setphoneprofile(nargc,nargv);break;
1284     case OPT_GETVOICEMAILBOX:       rc = getvoicemailbox();         break;
1285     case OPT_NM_COLLECT:            rc = nm_collect(nargc, nargv);  break;
1286     case OPT_NETMONITORDATA:        rc = netmonitordata(nargc, nargv);break;
1287
1288     default:         fprintf(stderr, _("Unknown option: %d\n"), c); break;
1289
1290     }
1291
1292     free(nargv);
1293
1294     return(rc);
1295   }
1296
1297   fprintf(stderr, _("Wrong number of arguments\n"));
1298
1299   exit(-1);
1300 }
1301
1302 /* Restores various phone settings from one file */
1303 int restoresettings(char *argv[])
1304 {
1305   fprintf(stdout,_("Work in progress. Not usefull now. Sorry\n"));
1306   return 0;
1307 }
1308
1309 /* Backup various phone settings from one file */
1310 int backupsettings(char *argv[])
1311 {
1312   GSM_PhonebookEntry PbkEntry;
1313   GSM_Error error;
1314   GSM_Backup Backup;
1315   int i;
1316
1317   GSM_MemoryStatus SIMMemoryStatus = {GMT_SM, 0, 0};
1318   GSM_MemoryStatus PhoneMemoryStatus = {GMT_ME, 0, 0};
1319
1320   fbusinit(NULL);
1321
1322   fprintf(stderr,_("Backup phonebook from SIM..."));
1323   Backup.SIMPhonebookUsed=0;
1324   if (GSM->GetMemoryStatus(&SIMMemoryStatus) == GE_NONE) {//FIXME
1325     Backup.SIMPhonebookSize=SIMMemoryStatus.Used+SIMMemoryStatus.Free;
1326
1327     PbkEntry.MemoryType=GMT_SM;
1328
1329     for (i=0;i<Backup.SIMPhonebookSize;i++)
1330     {
1331       if (SIMMemoryStatus.Used==Backup.SIMPhonebookUsed) break;
1332
1333       PbkEntry.Location=i;
1334     
1335       error=GSM->GetMemoryLocation(&PbkEntry);
1336       switch (error) {
1337         case GE_NONE:
1338           Backup.SIMPhonebook[Backup.SIMPhonebookUsed]=PbkEntry;
1339           Backup.SIMPhonebookUsed++;
1340           fprintf(stderr,_("."));
1341           break;
1342         default:
1343           break;
1344       }
1345     }
1346     fprintf(stderr,_("Done\n"));
1347   } else fprintf(stderr,_("ERROR\n"));
1348
1349   fprintf(stderr,_("Backup phonebook from phone..."));
1350   Backup.PhonePhonebookUsed=0;
1351   if (GSM->GetMemoryStatus(&PhoneMemoryStatus) == GE_NONE) {
1352     Backup.PhonePhonebookSize=PhoneMemoryStatus.Used+PhoneMemoryStatus.Free;
1353
1354     PbkEntry.MemoryType=GMT_ME;
1355
1356     for (i=0;i<Backup.PhonePhonebookSize;i++)
1357     {
1358       if (PhoneMemoryStatus.Used==Backup.PhonePhonebookUsed) break;
1359
1360       PbkEntry.Location=i;
1361     
1362       error=GSM->GetMemoryLocation(&PbkEntry);
1363       switch (error) {
1364         case GE_NONE:
1365           Backup.PhonePhonebook[Backup.PhonePhonebookUsed]=PbkEntry;
1366           Backup.PhonePhonebookUsed++;
1367           fprintf(stderr,_("."));
1368           break;
1369         default:
1370           break;
1371       }
1372     }
1373     fprintf(stderr,_("Done\n"));
1374   } else fprintf(stderr,_("ERROR\n"));
1375
1376   if( GetModelFeature (FN_CALLERGROUPS)!=0) {
1377     fprintf(stderr,_("Backup caller logos..."));
1378     Backup.CallerAvailable=true;
1379     for (i=0;i<5;i++) {
1380       Backup.CallerGroups[i].number=i;
1381       Backup.CallerGroups[i].type=GSM_CallerLogo;
1382       if (GSM->GetBitmap(&Backup.CallerGroups[i])!=GE_NONE) return 1;
1383     }
1384     fprintf(stderr,_("Done\n"));
1385   } else Backup.CallerAvailable=false;
1386
1387 //  fprintf(stderr,_("Backup speed dials..."));
1388   Backup.SpeedAvailable=false;
1389 //  for (i=0;i<8;i++) {
1390 //    Backup.SpeedDials[i].Number=i+1;
1391 //    if (GSM->GetSpeedDial(&Backup.SpeedDials[i])!=GE_NONE) return 1;
1392 //  }
1393 //  fprintf(stderr,_("Done\n"));
1394
1395   fprintf(stderr,_("Backup operator logo..."));
1396   Backup.OperatorLogoAvailable=true;
1397   Backup.OperatorLogo.type=GSM_7110OperatorLogo;
1398   if (GSM->GetBitmap(&Backup.OperatorLogo)!=GE_NONE) {
1399     Backup.OperatorLogoAvailable=true;
1400     Backup.OperatorLogo.type=GSM_OperatorLogo;
1401     if (GSM->GetBitmap(&Backup.OperatorLogo)!=GE_NONE) {
1402       Backup.OperatorLogoAvailable=false;
1403       fprintf(stderr,_("Error\n"));
1404     } else fprintf(stderr,_("Done\n"));
1405   } else fprintf(stderr,_("Done\n"));
1406
1407   Backup.StartupLogoAvailable=false;
1408   if( GetModelFeature (FN_STARTUP)!=0) {
1409     fprintf(stderr,_("Backup startup logo..."));
1410     Backup.StartupLogoAvailable=true;
1411     switch (GetModelFeature (FN_STARTUP)) {
1412       case F_STA62: Backup.StartupLogo.type=GSM_6210StartupLogo;break;
1413       case F_STA71: Backup.StartupLogo.type=GSM_7110StartupLogo;break;
1414       default     : Backup.StartupLogo.type=GSM_StartupLogo;break;
1415     }
1416     if (GSM->GetBitmap(&Backup.StartupLogo)!=GE_NONE) {
1417       Backup.StartupLogoAvailable=false;
1418       fprintf(stderr,_("Error\n"));
1419     } else fprintf(stderr,_("Done\n"));
1420   }
1421
1422   fprintf(stderr,_("Backup welcome note..."));
1423   Backup.StartupText.type=GSM_WelcomeNoteText;
1424   if (GSM->GetBitmap(&Backup.StartupText)!=GE_NONE) {
1425     fprintf(stderr,_("Error\n"));
1426   } else fprintf(stderr,_("Done\n"));
1427
1428   GSM->Terminate();
1429
1430   GSM_SaveBackupFile(argv[0], &Backup);
1431
1432   return 0;
1433 }
1434
1435 /* Presses keys on phone's keyboard */
1436
1437 int presskeysequence(char *argv[])
1438 {
1439   int i,j;
1440   int keycode;
1441   char key;
1442   
1443   sleep(1);
1444
1445   /* We need to make sure that the init is finished to avoid interrupted */
1446   /* multiframe packets... */
1447
1448   fbusinit(NULL);
1449   
1450   for (i=0;i<strlen(argv[0]);i++)
1451   {
1452     key=argv[0][i];
1453     keycode=0;
1454     j=0;
1455     
1456     if (key!='w' && key!='W')
1457     {
1458       while (Keys[j].whatchar!=' ') {
1459         if (Keys[j].whatchar==key) {    
1460           keycode=Keys[j].whatcode;
1461           break;
1462         }
1463         j++;
1464       }
1465     
1466       if (keycode==0) {
1467         fprintf(stderr,_("Unknown key: %c !\n"),key);
1468         GSM->Terminate();
1469         return -1;
1470       }
1471     
1472       if (GSM->PressKey(keycode,PRESSPHONEKEY)!=GE_NONE)
1473       {
1474         fprintf(stderr,_("Can't press key !\n"));
1475         GSM->Terminate();
1476         return -1;
1477       }
1478       if (GSM->PressKey(keycode,RELEASEPHONEKEY)!=GE_NONE)
1479       {
1480         fprintf(stderr,_("Can't release key !\n"));
1481         GSM->Terminate();
1482         return -1;
1483       }
1484     } else
1485     {
1486       sleep(2);
1487     }
1488   }
1489   
1490   GSM->Terminate();
1491
1492   return 0;
1493 }
1494
1495 /* Send  SMS messages. */
1496 int sendsms(int argc, char *argv[])
1497 {
1498   GSM_MultiSMSMessage MultiSMS;
1499   char message_buffer[GSM_MAX_CONCATENATED_SMS_LENGTH];
1500   int input_len, chars_read,i,msgnum;
1501
1502   GSM_SMSMessageType SMSType=GST_SMS;
1503   int SMSValidity= 4320; /* 4320 minutes == 72 hours */
1504   bool SMSReply=false;
1505   int SMSClass=-1,SMSCenter=1;
1506   char SMSCNumber[100];
1507   GSM_Coding_Type SMSCoding=GSM_Coding_Default;
1508   GSM_UDH SMSUDHType=GSM_NoUDH;
1509
1510   struct option options[] = {
1511              { "smscno",       required_argument, NULL, '1'},
1512              { "smsc",         required_argument, NULL, '2'},
1513              { "long",         required_argument, NULL, '3'},
1514              { "enablevoice",  no_argument,       NULL, '4'},
1515              { "disablevoice", no_argument,       NULL, '5'},
1516              { "enableemail",  no_argument,       NULL, '6'},
1517              { "disableemail", no_argument,       NULL, '7'},
1518              { "enablefax",    no_argument,       NULL, '8'},
1519              { "disablefax",   no_argument,       NULL, '9'},
1520              { "unicode",      no_argument,       NULL, '-'},
1521              { "void",         no_argument,       NULL, '+'},
1522              { "hang",         no_argument,       NULL, '('},
1523              { "bug",          no_argument,       NULL, ')'},
1524              { NULL,           0,                 NULL, 0}
1525   };
1526   
1527   input_len = GSM_MAX_SMS_LENGTH;
1528
1529   if (argc!=0) {
1530
1531     optarg = NULL;
1532     optind = 0;
1533
1534     while ((i = getopt_long(argc, argv, "v:dsC:", options, NULL)) != -1) {
1535       switch (i) {
1536
1537         case '1': /* SMSC number */
1538           SMSCenter = 0;
1539           strcpy(SMSCNumber,optarg);
1540           break;
1541
1542         case '2': /* SMSC number index in phone memory */
1543           SMSCenter = atoi(optarg);
1544
1545           if (SMSCenter < 1 || SMSCenter > 5) {
1546             fprintf(stderr, _("Incorrect SMSC number with \"smscno\" option (can't be <1 and >5) !\n"));
1547             GSM->Terminate();
1548             return -1;
1549           }
1550           break;
1551
1552         case '3': /* we send long message */
1553           SMSUDHType=GSM_ConcatenatedMessages;
1554           input_len = atoi(optarg);
1555           if (input_len > GSM_MAX_CONCATENATED_SMS_LENGTH) {
1556             fprintf(stderr, _("Input too long, max %i!\n"),GSM_MAX_CONCATENATED_SMS_LENGTH);
1557             exit(-1);
1558           }
1559           break;
1560
1561         case '4': /* SMS enables voice indicator */
1562           SMSUDHType=GSM_EnableVoice;    break;
1563
1564         case '5': /* SMS disables voice indicator */
1565           SMSUDHType=GSM_DisableVoice;   break;   
1566
1567         case '6': /* SMS enables email indicator */
1568           SMSUDHType=GSM_EnableEmail;    break;   
1569
1570         case '7': /* SMS disables email indicator */
1571           SMSUDHType=GSM_DisableEmail;   break;   
1572
1573         case '8': /* SMS enables fax indicator */
1574           SMSUDHType=GSM_EnableFax;      break;   
1575
1576         case '9': /* SMS disables fax indicator */
1577           SMSUDHType=GSM_DisableFax;     break;   
1578
1579         case '-': /* SMS coding type */
1580           SMSCoding=GSM_Coding_Unicode;  break;
1581
1582         case '+': /* SMS ghost */
1583           SMSUDHType=GSM_VoidSMS;        break;
1584
1585         case '(': /* SMS hanging phone, when saved to Outbox */
1586           SMSUDHType=GSM_HangSMS;        break;
1587
1588         case ')': /* SMS showed incorrectly in phone */
1589           SMSUDHType=GSM_BugSMS;         break;
1590
1591         case 'v': /* Set validaty of SMS */
1592           SMSValidity = atoi(optarg);    break;
1593
1594         case 'd': /* delivery report */
1595           SMSType=GST_DR;                break; 
1596
1597         case 's': /* Set replying via the same SMSC */
1598           SMSReply = true;               break;
1599
1600         case 'C': /* class Message */
1601           
1602           if (SMSUDHType!=GSM_NoUDH) {
1603             fprintf(stderr, _("Can't specify SMS Class with --enablevoice, --disablevoice, --enableemail, --disableemail, --enablefax, --disablefax options !\n"));         
1604             return -1;
1605           }
1606           
1607           switch (*optarg) {
1608             case '0': SMSClass = 0; break;
1609             case '1': SMSClass = 1; break;
1610             case '2': SMSClass = 2; break;
1611             case '3': SMSClass = 3; break; 
1612             default:
1613               fprintf(stderr, _("SMS Class (\"C\" option) can be 0, 1, 2 or 3 only !\n"));
1614               return -1;
1615           }
1616           break;
1617           
1618         default:
1619           fprintf(stderr,_("Unknown option number %i\n"),argc);
1620           return -1;
1621       }
1622     }
1623   }
1624   
1625   /* Get message text from stdin. */
1626   chars_read = fread(message_buffer, 1, input_len, stdin);
1627
1628   if (chars_read == 0) {
1629     fprintf(stderr, _("Couldn't read from stdin!\n"));  
1630     return -1;
1631   }
1632   if (chars_read > input_len) {
1633     fprintf(stderr, _("Input too long!\n"));    
1634     return -1;
1635   }
1636   
1637   /*  Null terminate. */
1638   message_buffer[chars_read] = 0x00;    
1639
1640   GSM_MakeMultiPartSMS2(&MultiSMS,message_buffer,chars_read,SMSUDHType,SMSCoding);
1641   msgnum=MultiSMS.number;
1642
1643   switch (SMSUDHType) {
1644     case GSM_NoUDH:
1645     case GSM_BugSMS:
1646     case GSM_VoidSMS:
1647     case GSM_HangSMS:
1648     case GSM_EnableVoice:
1649     case GSM_DisableVoice:
1650     case GSM_EnableFax:
1651     case GSM_DisableFax:
1652     case GSM_EnableEmail:
1653     case GSM_DisableEmail:
1654       fprintf(stdout,_("Warning: saving %i chars\n"),strlen(MultiSMS.SMS[0].MessageText));
1655       msgnum=1;
1656       break;
1657     default:
1658       break;
1659   }
1660
1661   for (i=0;i<msgnum;i++) {
1662     strcpy(MultiSMS.SMS[i].Destination,argv[0]);
1663
1664     MultiSMS.SMS[i].Class=SMSClass;
1665     MultiSMS.SMS[i].ReplyViaSameSMSC=SMSReply;
1666     MultiSMS.SMS[i].Type=SMSType;
1667     MultiSMS.SMS[i].Validity=SMSValidity;
1668   }
1669
1670   /* Initialise the GSM interface. */     
1671   fbusinit(NULL);
1672
1673   MultiSMS.number=msgnum;
1674   GSM_SendMultiPartSMSOnConsole(&MultiSMS, 0,0,NULL,false,false,false);
1675   
1676   return 0;
1677 }
1678
1679 int savesms(int argc, char *argv[])
1680 {
1681   GSM_MultiSMSMessage MultiSMS;
1682   char message_buffer[GSM_MAX_CONCATENATED_SMS_LENGTH];
1683   int input_len, chars_read,i,msgnum;
1684
1685   int SMSClass=-1,SMSCenter=1;
1686   char SMSName[25+1];
1687   char SMSCNumber[100];
1688   GSM_Coding_Type SMSCoding=GSM_Coding_Default;
1689   GSM_UDH SMSUDHType=GSM_NoUDH;
1690   GSM_SMSMessageStatus SMSStatus;
1691   int SMSFolder;
1692   bool SMSReply=false;
1693   int SMSLocation=0;
1694   bool interactive=false;
1695
1696   struct option options[] = {
1697              { "smscno",       required_argument, NULL, '1'},
1698              { "smsc",         required_argument, NULL, '2'},
1699              { "long",         required_argument, NULL, '3'},
1700              { "enablevoice",  no_argument,       NULL, '4'},
1701              { "disablevoice", no_argument,       NULL, '5'},
1702              { "enableemail",  no_argument,       NULL, '6'},
1703              { "disableemail", no_argument,       NULL, '7'},
1704              { "enablefax",    no_argument,       NULL, '8'},
1705              { "disablefax",   no_argument,       NULL, '9'},
1706              { "unicode",      no_argument,       NULL, '-'},
1707              { "void",         no_argument,       NULL, '+'},
1708              { "hang",         no_argument,       NULL, '('},
1709              { "bug",          no_argument,       NULL, ')'},
1710              { "smsname",      required_argument, NULL, '/'},
1711              { NULL,           0,                 NULL, 0}
1712   };
1713
1714   SMSCNumber[0]=0;
1715   SMSName[0]=0;
1716   SMSStatus=GSS_NOTSENTREAD;
1717   SMSFolder=GST_OUTBOX;
1718   
1719   input_len = GSM_MAX_SMS_LENGTH;
1720
1721   if (argc!=0) {
1722
1723     optarg = NULL;
1724     optind = 0;
1725
1726     while ((i = getopt_long(argc, argv, "risal:C:F:", options, NULL)) != -1) {
1727       switch (i) {
1728
1729         case '1': /* SMSC number */
1730           SMSCenter = 0;
1731           strcpy(SMSCNumber,optarg);
1732           break;
1733
1734         case '2': /* SMSC number index in phone memory */
1735           SMSCenter = atoi(optarg);
1736
1737           if (SMSCenter < 1 || SMSCenter > 5) {
1738             fprintf(stderr, _("Incorrect SMSC number with \"smscno\" option (can't be <1 and >5) !\n"));
1739             GSM->Terminate();
1740             return -1;
1741           }
1742           break;
1743
1744         case '3': /* we send long message */
1745           SMSUDHType=GSM_ConcatenatedMessages;
1746           input_len = atoi(optarg);
1747           if (input_len > GSM_MAX_CONCATENATED_SMS_LENGTH) {
1748             fprintf(stderr, _("Input too long, max %i!\n"),GSM_MAX_CONCATENATED_SMS_LENGTH);
1749             exit(-1);
1750           }
1751           break;
1752
1753         case '4': /* SMS enables voice indicator */
1754           SMSUDHType=GSM_EnableVoice;    break;
1755
1756         case '5': /* SMS disables voice indicator */
1757           SMSUDHType=GSM_DisableVoice;   break;   
1758
1759         case '6': /* SMS enables email indicator */
1760           SMSUDHType=GSM_EnableEmail;    break;   
1761
1762         case '7': /* SMS disables email indicator */
1763           SMSUDHType=GSM_DisableEmail;   break;   
1764
1765         case '8': /* SMS enables fax indicator */
1766           SMSUDHType=GSM_EnableFax;      break;   
1767
1768         case '9': /* SMS disables fax indicator */
1769           SMSUDHType=GSM_DisableFax;     break;   
1770
1771         case '-': /* SMS coding type */
1772           SMSCoding=GSM_Coding_Unicode;  break;
1773
1774         case '+': /* SMS ghost */
1775           SMSUDHType=GSM_VoidSMS;        break;
1776
1777         case '(': /* SMS hanging phone, when saved to Outbox */
1778           SMSUDHType=GSM_HangSMS;        break;
1779
1780         case ')': /* SMS showed incorrectly in phone */
1781           SMSUDHType=GSM_BugSMS;         break;
1782
1783         case 'r': /* mark as read */
1784           SMSStatus = GSS_SENTREAD; break;
1785  
1786         case 'i': /* Save into Inbox */
1787           SMSFolder = GST_INBOX; break;
1788           
1789         case 's': /* Set replying via the same SMSC */
1790           SMSReply = true; break;
1791
1792         case 'a': /* Ask before overwriting */
1793           interactive=true;break;     
1794         
1795         case 'l': /* Specify location */
1796           SMSLocation = atoi(optarg); break;     
1797
1798         case '/': /* Name */
1799           strncpy(SMSName,optarg,25);break;
1800
1801         case 'C': /* class Message */
1802           
1803           if (SMSUDHType!=GSM_NoUDH) {
1804             fprintf(stderr, _("Can't specify SMS Class with --enablevoice, --disablevoice, --enableemail, --disableemail, --enablefax, --disablefax options !\n"));         
1805             return -1;
1806           }
1807           
1808           switch (*optarg) {
1809             case '0': SMSClass = 0; break;
1810             case '1': SMSClass = 1; break;
1811             case '2': SMSClass = 2; break;
1812             case '3': SMSClass = 3; break; 
1813             default:
1814               fprintf(stderr, _("SMS Class (\"C\" option) can be 0, 1, 2 or 3 only !\n"));
1815               return -1;
1816           }
1817           break;
1818
1819         case 'F': /* save into folder n */
1820           SMSFolder = atoi(optarg);
1821           break;
1822
1823         default:
1824           fprintf(stderr,_("Unknown option number %i\n"),argc);
1825           return -1;
1826       }
1827     }
1828   }
1829   
1830   /* Get message text from stdin. */
1831   chars_read = fread(message_buffer, 1, input_len, stdin);
1832
1833   if (chars_read == 0) {
1834     fprintf(stderr, _("Couldn't read from stdin!\n"));  
1835     return -1;
1836   }
1837   if (chars_read > input_len) {
1838     fprintf(stderr, _("Input too long!\n"));    
1839     return -1;
1840   }
1841   
1842   /*  Null terminate. */
1843   message_buffer[chars_read] = 0x00;    
1844
1845   GSM_MakeMultiPartSMS2(&MultiSMS,message_buffer,chars_read,SMSUDHType,SMSCoding);
1846   msgnum=MultiSMS.number;
1847
1848   switch (SMSUDHType) {
1849     case GSM_NoUDH:
1850     case GSM_BugSMS:
1851     case GSM_VoidSMS:
1852     case GSM_HangSMS:
1853     case GSM_EnableVoice:
1854     case GSM_DisableVoice:
1855     case GSM_EnableFax:
1856     case GSM_DisableFax:
1857     case GSM_EnableEmail:
1858     case GSM_DisableEmail:
1859       fprintf(stdout,_("Warning: saving %i chars\n"),strlen(MultiSMS.SMS[0].MessageText));
1860       msgnum=1;
1861       break;
1862     default:
1863       break;
1864   }
1865
1866   for (i=0;i<msgnum;i++) {
1867     MultiSMS.SMS[i].Destination[0]=0;
1868     if (argc!=0) strcpy(MultiSMS.SMS[i].Destination,argv[0]);
1869
1870     MultiSMS.SMS[i].Location=0;
1871     MultiSMS.SMS[i].Class=SMSClass;
1872     MultiSMS.SMS[i].MessageCenter.No=SMSCenter;
1873     strcpy(MultiSMS.SMS[i].MessageCenter.Number,SMSCNumber);
1874     MultiSMS.SMS[i].Status=SMSStatus;
1875     strcpy(MultiSMS.SMS[i].Name,SMSName);
1876     MultiSMS.SMS[i].folder=SMSFolder;
1877     MultiSMS.SMS[i].ReplyViaSameSMSC=SMSReply;
1878   }
1879
1880   MultiSMS.SMS[0].Location=SMSLocation;
1881
1882   /* Initialise the GSM interface. */     
1883   fbusinit(NULL);
1884
1885   MultiSMS.number=msgnum;
1886   GSM_SaveMultiPartSMSOnConsole(&MultiSMS, 0,0,NULL,interactive,false,false,false);
1887   
1888   return 0;
1889 }
1890
1891 /* Get SMSC number */
1892
1893 int getsmsc(char *MessageCenterNumber)
1894 {
1895
1896   GSM_MessageCenter MessageCenter;
1897
1898   MessageCenter.No=atoi(MessageCenterNumber);
1899
1900   fbusinit(NULL);
1901
1902   if (GSM->GetSMSCenter(&MessageCenter) == GE_NONE) {
1903
1904     fprintf(stdout, _("%d. SMS center ("),MessageCenter.No);
1905     
1906     if (!strcmp(MessageCenter.Name,""))
1907       fprintf(stdout,_("Set %d"),MessageCenter.No);
1908     else fprintf(stdout,_("%s"),MessageCenter.Name);
1909       
1910     fprintf(stdout,_(") number is "));
1911
1912     if (!strcmp(MessageCenter.Number,"")) fprintf(stdout,_("not set\n"));
1913     else fprintf(stdout,_("%s\n"),MessageCenter.Number);
1914
1915     fprintf(stdout,_("Default recipient number is "));
1916
1917     if (!strcmp(MessageCenter.DefaultRecipient,""))
1918       fprintf(stdout,_("not set\n"));
1919     else fprintf(stdout,_("%s\n"),MessageCenter.DefaultRecipient);
1920
1921     fprintf(stdout, _("Messages sent as "));
1922
1923     switch (MessageCenter.Format) {
1924       case GSMF_Text  :fprintf(stdout, _("Text"));break;
1925       case GSMF_Paging:fprintf(stdout, _("Paging"));break;
1926       case GSMF_Fax   :fprintf(stdout, _("Fax"));break;
1927       case GSMF_Email :
1928       case GSMF_UCI   :fprintf(stdout, _("Email"));break;
1929       case GSMF_ERMES :fprintf(stdout, _("ERMES"));break;
1930       case GSMF_X400  :fprintf(stdout, _("X.400"));break;
1931       default         :fprintf(stdout, _("Unknown"));
1932     }
1933
1934     printf("\n");
1935
1936     fprintf(stdout, _("Message validity is "));
1937
1938     switch (MessageCenter.Validity) {
1939       case GSMV_1_Hour  :fprintf(stdout, _("1 hour"));break;
1940       case GSMV_6_Hours :fprintf(stdout, _("6 hours"));break;
1941       case GSMV_24_Hours:fprintf(stdout, _("24 hours"));break;
1942       case GSMV_72_Hours:fprintf(stdout, _("72 hours"));break;
1943       case GSMV_1_Week  :fprintf(stdout, _("1 week"));break;
1944       case GSMV_Max_Time:fprintf(stdout, _("Maximum time"));break;
1945       default           :fprintf(stdout, _("Unknown"));
1946     }
1947
1948     fprintf(stdout, "\n");
1949
1950   }
1951   else
1952     fprintf(stdout, _("SMS center can not be found :-(\n"));
1953
1954   GSM->Terminate();
1955
1956   return 0;
1957 }
1958
1959 /* Get SMS messages. */
1960 int getsms(int argc, char *argv[])
1961 {
1962
1963   GSM_SMSMessage message;
1964   GSM_WAPBookmark bookmark;
1965   char memory_type_string[20];
1966   int start_message, end_message, count, mode = 1;
1967   char filename[64];
1968   GSM_Error error;
1969   GSM_Bitmap bitmap;
1970   GSM_Ringtone ringtone;
1971   GSM_SMSFolders folders;
1972   
1973   int confirm = -1, i;
1974   char ans[8];
1975
1976   /* Handle command line args that set type, start and end locations. */
1977   if (!GetMemoryTypeID(argv[2], &message.MemoryType))
1978   {
1979     fprintf(stderr, _("Unknown memory type %s!\n"), argv[2]);
1980     return (-1);
1981   }
1982   GetMemoryTypeString(memory_type_string, &message.MemoryType);
1983
1984   for (i=0;i<64;i++) filename[i]=0;
1985
1986   start_message = atoi(argv[3]);
1987   if (argc > 4) {
1988      int i;
1989      
1990      /* [end] can be only argv[4] */
1991      if (argv[4][0] == '-') {
1992         end_message = start_message;
1993      } else {
1994         end_message = atoi(argv[4]);
1995      }
1996
1997      /* parse all options (beginning with '-' */
1998      while ((i = getopt(argc, argv, "f:")) != -1) {
1999         switch (i) {
2000           case 'f':
2001             if (optarg) {
2002 #ifdef DEBUG
2003           fprintf(stderr, _("Saving into file \"%s\"\n"), optarg);
2004 #endif /* DEBUG */
2005               strncpy(filename, optarg, 64);
2006               if (strlen(optarg) > 63) {
2007                 fprintf(stderr, _("Filename too long - will be truncated to 63 characters.\n"));
2008                 filename[63] = 0;
2009               } else {
2010                 filename[strlen(optarg)] = 0;
2011               }
2012             } else {
2013               usage();
2014               exit(1);
2015             }
2016             break;
2017           default:
2018             usage();
2019             exit(1);
2020         }
2021       }
2022   } else {
2023     end_message = start_message;
2024   }
2025
2026   /* Initialise the code for the GSM interface. */     
2027
2028   fbusinit(NULL);
2029
2030   GSM->GetSMSFolders(&folders);
2031
2032   
2033   /* Now retrieve the requested entries. */
2034
2035   for (count = start_message; count <= end_message; count ++) {
2036
2037     message.Location = count;
2038
2039     error = GSM->GetSMSMessage(&message);
2040
2041     switch (error) {
2042
2043     case GE_NONE:
2044
2045       switch (message.Type) {
2046
2047         case GST_DR:
2048
2049           /* RTH FIXME: Test that out ! */
2050           fprintf(stdout, _("%d. Delivery Report "), message.MessageNumber);
2051           switch (message.Status)
2052            {
2053             case  GSS_SENTREAD:
2054                 if (message.folder==0) //GST_INBOX
2055                   fprintf(stdout, _("(read)\n"));
2056                 else
2057                   fprintf(stdout, _("(sent)\n"));
2058                 break;
2059             case  GSS_NOTSENTREAD:
2060                 if (message.folder==0) //GST_INBOX
2061                   fprintf(stdout, _("(unread)\n"));
2062                 else
2063                   fprintf(stdout, _("(not sent)\n"));
2064                 break;
2065             case  GSS_UNKNOWN:
2066                 fprintf(stdout, _("(not known :-()\n"));
2067                 break;
2068             case  GSS_TEMPLATE:
2069                 fprintf(stdout, _("(template)\n"));
2070                 break;
2071             default:
2072                 fprintf(stdout, _("(unknown: %d)\n"),message.Status);
2073                 break;
2074            }
2075
2076           fprintf(stdout, _("Sending date/time : %s %02d/%02d/%02d %d:%02d:%02d "), \
2077                   DayOfWeek(message.Time.Year, message.Time.Month, message.Time.Day), \
2078                   message.Time.Day, message.Time.Month, message.Time.Year, \
2079                   message.Time.Hour, message.Time.Minute, message.Time.Second);
2080
2081           if (message.Time.Timezone) {
2082             if (message.Time.Timezone > 0)
2083               fprintf(stdout,_("+%02d00"), message.Time.Timezone);
2084             else
2085               fprintf(stdout,_("%02d00"), message.Time.Timezone);
2086           }
2087
2088           fprintf(stdout, "\n");
2089
2090           fprintf(stdout, _("Response date/time: %s %02d/%02d/%02d %d:%02d:%02d "), \
2091                   DayOfWeek(message.SMSCTime.Year, message.SMSCTime.Month, message.SMSCTime.Day), \
2092                   message.SMSCTime.Day, message.SMSCTime.Month, message.SMSCTime.Year, \
2093                   message.SMSCTime.Hour, message.SMSCTime.Minute, message.SMSCTime.Second);
2094
2095           if (message.SMSCTime.Timezone) {
2096             if (message.SMSCTime.Timezone > 0)
2097               fprintf(stdout,_("+%02d00"),message.SMSCTime.Timezone);
2098             else
2099               fprintf(stdout,_("%02d00"),message.SMSCTime.Timezone);
2100           }
2101
2102           fprintf(stdout, "\n");
2103
2104           fprintf(stdout, _("Receiver: %s Msg Center: %s\n"), message.Sender, message.MessageCenter.Number);
2105           fprintf(stdout, _("Text: %s\n\n"), message.MessageText); 
2106
2107           break;
2108
2109         case GST_SMS:
2110           fprintf(stdout, _("%d. %s Message "), message.MessageNumber,
2111                           folders.Folder[message.folder].Name);
2112
2113           switch (message.Status)
2114            {
2115             case  GSS_SENTREAD:
2116                 if (message.folder==0) //GST_INBOX
2117                   fprintf(stdout, _("(read)\n"));
2118                 else
2119                   fprintf(stdout, _("(sent)\n"));
2120                 break;
2121             case  GSS_NOTSENTREAD:
2122                 if (message.folder==0) //GST_INBOX
2123                   fprintf(stdout, _("(unread)\n"));
2124                 else
2125                   fprintf(stdout, _("(not sent)\n"));
2126                 break;
2127             case  GSS_UNKNOWN:
2128                 fprintf(stdout, _("(not known :-()\n"));
2129                 break;
2130             case  GSS_TEMPLATE:
2131                 fprintf(stdout, _("(template)\n"));
2132                 break;
2133             default:
2134                 fprintf(stdout, _("(unknown: %d)\n"),message.Status);
2135                 break;
2136            }
2137          
2138           /* RTH FIXME: date for other status ok ? */ 
2139           if (message.SMSData) {
2140
2141             fprintf(stdout, _("Date/time: %s %02d/%02d/%02d %d:%02d:%02d "), \
2142                     DayOfWeek(message.Time.Year, message.Time.Month, message.Time.Day), \
2143                     message.Time.Day, message.Time.Month, message.Time.Year, \
2144                     message.Time.Hour, message.Time.Minute, message.Time.Second);
2145
2146             if (message.Time.Timezone) {
2147               if (message.Time.Timezone > 0)
2148                 fprintf(stdout,_("+%02d00"),message.Time.Timezone);
2149               else
2150                 fprintf(stdout,_("%02d00"),message.Time.Timezone);
2151             }
2152
2153             fprintf(stdout, "\n");
2154
2155             fprintf(stdout, _("Msg Center: %s "), message.MessageCenter.Number);
2156             
2157             if (message.ReplyViaSameSMSC)
2158               fprintf(stdout, _("(centre set for reply) "));
2159           }
2160
2161           if (strcmp(message.Sender,"")) {
2162             if (message.folder==1) { //GST_OUTBOX
2163               fprintf(stdout, _("Recipient: %s"),message.Sender);
2164             } else {
2165               fprintf(stdout, _("Sender: %s"),message.Sender);
2166             }
2167           }
2168
2169           if (strcmp(message.Sender,"") || message.folder==0)
2170             fprintf(stdout, "\n");
2171             
2172           switch (message.UDHType) {
2173
2174           case GSM_OpLogo:
2175
2176             /* put bitmap into bitmap structure */
2177             switch (GSM_ReadBitmap(&message, &bitmap)) {
2178               case GE_INVALIDIMAGESIZE:
2179                 fprintf(stdout,_("Image size not supported\n"));
2180                 break;
2181               case GE_NONE:
2182                 fprintf(stdout, _("GSM operator logo for %s (%s) network.\n"), bitmap.netcode, GSM_GetNetworkName(bitmap.netcode));         
2183             
2184                 GSM_PrintBitmap(&bitmap);
2185
2186                 if (filename[0]!=0) {
2187                   GSM_SaveBitmapFileOnConsole(filename, &bitmap);
2188                 }
2189
2190                 break;
2191               default:
2192                 fprintf(stdout,_("Error reading image\n"));  
2193                 break;
2194             }
2195
2196 #ifdef DEBUG
2197             if (message.folder==0) { //GST_INBOX
2198               if (!strcmp(message.Sender, "+998000005") &&
2199                   !strcmp(message.MessageCenter.Number, "+886935074443") &&
2200                   message.Time.Day==27 &&
2201                   message.Time.Month==7 &&
2202                   message.Time.Year==99 &&
2203                   message.Time.Hour==0 &&
2204                   message.Time.Minute==10 &&
2205                   message.Time.Second==48) fprintf(stdout, _("Saved by Logo Express\n"));
2206
2207               /* Is it changed in next versions ? Or what ? */
2208               if (!strcmp(message.Sender, "+998000002") ||
2209                   !strcmp(message.Sender, "+998000003") ||
2210                   !strcmp(message.Sender, "+998000004")) fprintf(stdout, _("Saved by Operator Logo Uploader by Thomas Kessler\n"));
2211             } else {
2212               if (!strcmp(message.Sender, "+8861234567890") &&
2213                   !strcmp(message.MessageCenter.Number, "+886935074443")) fprintf(stdout, _("Saved by Logo Express\n"));
2214             }
2215             if (!strncmp(message.Sender, "OpLogo",6) &&
2216                 strlen(message.Sender)==11)
2217               fprintf(stdout, _("Saved by gnokii\n"));          
2218 #endif
2219
2220             break;
2221
2222           case GSM_WAPBookmarkUDH:
2223
2224             /* put bookmark into bookmark structure */
2225             switch (GSM_ReadWAPBookmark(&message, &bookmark)) {
2226               case GE_NONE:
2227                 fprintf(stdout, ("WAP Bookmark\n"));
2228
2229                 fprintf(stdout,_("Address: \"%s\"\n"),bookmark.address);
2230
2231                 if (bookmark.title[0]==0)
2232                   fprintf(stdout,_("Title: \"%s\"\n"),bookmark.address);
2233                 else
2234                   fprintf(stdout,_("Title: \"%s\"\n"),bookmark.title);
2235
2236                 break;
2237               default:
2238                 fprintf(stdout,_("Error reading WAP Bookmark\n"));  
2239                 break;
2240             }
2241
2242 #ifdef DEBUG
2243             if (!strcmp(message.Sender, "WAPBookmark"))
2244               fprintf(stdout, _("Saved by gnokii\n"));          
2245 #endif
2246
2247             break;
2248
2249           case GSM_CallerIDLogo:
2250
2251             /* put bitmap into bitmap structure */
2252             switch (GSM_ReadBitmap(&message, &bitmap)) {
2253               case GE_INVALIDIMAGESIZE:
2254                 fprintf(stdout,_("Image size not supported\n"));
2255                 break;
2256               case GE_NONE:
2257                 fprintf(stdout, ("Caller Logo\n"));
2258             
2259                 GSM_PrintBitmap(&bitmap);
2260
2261                 if (filename[0]!=0) {
2262                   GSM_SaveBitmapFileOnConsole(filename, &bitmap);
2263                 }
2264
2265                 break;
2266               default:
2267                 fprintf(stdout,_("Error reading image\n"));  
2268                 break;
2269             }
2270
2271 #ifdef DEBUG
2272             if (message.folder==0) { //GST_INBOX
2273               if (!strcmp(message.Sender, "+998000005") &&
2274                   !strcmp(message.MessageCenter.Number, "+886935074443") &&
2275                   message.Time.Day==27 &&
2276                   message.Time.Month==7 &&
2277                   message.Time.Year==99 &&
2278                   message.Time.Hour==0 &&
2279                   message.Time.Minute==10 &&
2280                   message.Time.Second==48) fprintf(stdout, _("Saved by Logo Express\n"));
2281             } else {
2282               if (!strcmp(message.Sender, "+8861234567890") &&
2283                   !strcmp(message.MessageCenter.Number, "+886935074443")) fprintf(stdout, _("Saved by Logo Express\n"));
2284             }
2285             if (!strcmp(message.Sender, "GroupLogo"))
2286               fprintf(stdout, _("Saved by gnokii\n"));          
2287 #endif
2288
2289             break;
2290
2291           case GSM_ProfileUDH:
2292                 fprintf(stdout, ("Profile SMS, part %i/%i\n"),message.UDH[11],message.UDH[10]);
2293                 break;
2294
2295           case GSM_WAPBookmarkUDHLong:
2296                 fprintf(stdout, ("WAP Bookmark, part %i/%i\n"),message.UDH[11],message.UDH[10]);
2297                 break;
2298
2299           case GSM_WAPSettingsUDH:
2300                 fprintf(stdout, ("WAP Settings, part %i/%i\n"),message.UDH[11],message.UDH[10]);
2301                 break;
2302           
2303           case GSM_RingtoneUDH:
2304
2305             /* put ringtone into ringtone structure */
2306             switch (GSM_ReadRingtone(&message, &ringtone)) {
2307               case GE_NONE:
2308
2309                 fprintf(stdout, ("Ringtone \"%s\"\n"),ringtone.name);
2310
2311                 while (confirm < 0) {
2312                   fprintf(stderr, _("Do you want to play it ? (yes/no) "));
2313                   GetLine(stdin, ans, 7);
2314                   if (!strcmp(ans, "yes")) confirm = 1;
2315                   if (!strcmp(ans, "no")) confirm = 0;
2316                 }  
2317
2318                 if (confirm==1) GSM_PlayRingtoneOnConsole(&ringtone);
2319                 
2320                 if (filename[0]!=0) GSM_SaveRingtoneFileOnConsole(filename, &ringtone);
2321                 
2322                 break;
2323                 
2324               default:
2325                 fprintf(stdout,_("Gnokii can't read this ringtone - there is probably error inside\n"));
2326                 break;
2327             }
2328
2329             break;
2330
2331           case GSM_CalendarNoteUDH:
2332             fprintf(stdout, ("Calendar note SMS, part %i/%i\n"),message.UDH[11],message.UDH[10]);
2333             fprintf(stdout, _("Text:\n%s\n\n"), message.MessageText);
2334             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2335             break;
2336
2337           case GSM_ConcatenatedMessages:
2338             fprintf(stdout, _("Linked (%d/%d)\nText:\n%s\n\n"),message.UDH[5],message.UDH[4], message.MessageText);
2339             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2340             break;
2341
2342           case GSM_EnableVoice:
2343             fprintf(stdout, _("Enables voice indicator\nText:\n%s\n\n"), message.MessageText);
2344             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2345             break;
2346
2347           case GSM_DisableVoice:
2348             fprintf(stdout, _("Disables voice indicator\nText:\n%s\n\n"), message.MessageText);
2349             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2350             break;
2351
2352           case GSM_EnableFax:
2353             fprintf(stdout, _("Enables fax indicator\nText:\n%s\n\n"), message.MessageText);
2354             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2355             break;
2356
2357           case GSM_DisableFax:
2358             fprintf(stdout, _("Disables fax indicator\nText:\n%s\n\n"), message.MessageText);
2359             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2360             break;
2361
2362           case GSM_EnableEmail:
2363             fprintf(stdout, _("Enables email indicator\nText:\n%s\n\n"), message.MessageText);
2364             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2365             break;
2366
2367           case GSM_DisableEmail:
2368             fprintf(stdout, _("Disables email indicator\nText:\n%s\n\n"), message.MessageText);
2369             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2370             break;
2371
2372           case GSM_VoidSMS:
2373             fprintf(stdout, _("Void SMS\nText:\n%s\n\n"), message.MessageText);
2374             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2375             break;
2376
2377           case GSM_NoUDH:
2378             if (message.Coding!=GSM_Coding_8bit) {
2379               fprintf(stdout, _("Text:\n%s\n\n"), message.MessageText);
2380               if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2381             } else {
2382               fprintf(stdout, _("Message cannot be displayed here\n")); // like in phone :-)
2383             }
2384             break;
2385
2386           default:  //GSM_UnknownUDH and other
2387             fprintf(stderr, _("Unknown\n"));
2388           }
2389
2390           break;
2391           
2392         default:
2393           fprintf(stdout,_("Unknown SMS type. Report it\n"));
2394           break;
2395       }
2396
2397       break;
2398
2399     case GE_NOTIMPLEMENTED:
2400
2401       fprintf(stderr, _("Function not implemented in %s model!\n"), model);
2402       GSM->Terminate();
2403       return -1;        
2404
2405     case GE_INVALIDSMSLOCATION:
2406
2407       fprintf(stderr, _("Invalid location: %s %d\n"), memory_type_string, count);
2408
2409       break;
2410
2411     case GE_EMPTYSMSLOCATION:
2412
2413       fprintf(stderr, _("SMS location %s %d empty.\n"), memory_type_string, count);
2414
2415       break;
2416
2417     case GE_NOACCESS:
2418
2419       fprintf(stderr, _("No access to %s memory.\n"), memory_type_string);
2420
2421       break;
2422
2423     default:
2424
2425       fprintf(stderr, _("GetSMS %s %d failed!(%d)\n\n"), memory_type_string, count, error);
2426     }
2427   }
2428
2429   GSM->Terminate();
2430
2431   return 0;
2432 }
2433
2434 int getsmsstatus(int argc, char *argv[])
2435 {
2436   GSM_SMSStatus SMSStatus;
2437   GSM_SMSFolders folders;
2438   GSM_Error error;
2439   GSM_SMSMessage SMS;
2440
2441   int i,j;
2442
2443   /* Initialise the code for the GSM interface. */     
2444   fbusinit(NULL);
2445
2446   error = GSM->GetSMSStatus(&SMSStatus);
2447   if (error!=GE_NONE) return error;
2448
2449   fprintf(stdout, _("SMS Messages: UnRead %d, Number %d\n"),SMSStatus.UnRead, SMSStatus.Number);
2450
2451   error=GSM->GetSMSFolders(&folders);  
2452   if (error!=GE_NONE) return error;
2453
2454   /* For not 7110 compatible phones we have to read all SMS and prepare sms table */
2455   if( GetModelFeature (FN_SMS)!=F_SMS71 )
2456   {
2457     i=1;j=0;
2458     while (true) {
2459       if (j==SMSStatus.Number) break;
2460       SMS.Location=i;
2461       if (GSM->GetSMSMessage(&SMS)==GE_NONE) {
2462         SMSStatus.foldertable[j].smsnum=i;
2463
2464         /* We set such folders ID like in 7110 compatible phones */
2465         if (SMS.Status==GSS_NOTSENTREAD && SMS.folder==0) //GST_INBOX
2466           SMSStatus.foldertable[j].folder=0;
2467         else {
2468           switch (SMS.folder) {
2469             case 0://GST_INBOX
2470               SMSStatus.foldertable[j].folder=GST_7110_INBOX;
2471               break;
2472             case 1://GST_OUTBOX
2473               SMSStatus.foldertable[j].folder=GST_7110_OUTBOX;
2474               break;
2475           }
2476         }
2477         j++;
2478       }
2479       i++;
2480     }
2481   }
2482
2483   printf("0.Unread         : ");
2484   for(j=0; j<SMSStatus.Number; j++)
2485   {
2486     if (SMSStatus.foldertable[j].folder == 0)
2487       printf("%d ",SMSStatus.foldertable[j].smsnum);
2488   }
2489   printf("\n");
2490
2491   for (i=0;i<folders.number;i++) {
2492     fprintf(stdout,_("%d.%-15s: "),i+1,folders.Folder[i].Name);
2493     for(j=0; j<SMSStatus.Number; j++)
2494     {
2495       if ( SMSStatus.foldertable[j].folder / 8 == i+1)
2496         printf("%d ",SMSStatus.foldertable[j].smsnum);
2497     }
2498     printf("\n");
2499   }
2500
2501   GSM->Terminate();
2502
2503   return 0;
2504 }
2505
2506 /* Delete SMS messages. */
2507 int deletesms(int argc, char *argv[])
2508 {
2509
2510   GSM_SMSMessage message;
2511   char memory_type_string[20];
2512   int start_message, end_message, count;
2513   GSM_Error error;
2514
2515   /* Handle command line args that set type, start and end locations. */
2516   if (!GetMemoryTypeID(argv[0], &message.MemoryType))
2517   {
2518     fprintf(stderr, _("Unknown memory type %s!\n"), argv[0]);
2519     return (-1);
2520   }
2521   GetMemoryTypeString(memory_type_string, &message.MemoryType);
2522
2523   start_message = atoi (argv[1]);
2524   if (argc > 2) end_message = atoi (argv[2]);
2525   else end_message = start_message;
2526
2527   /* Initialise the code for the GSM interface. */     
2528
2529   fbusinit(NULL);
2530
2531   /* Now delete the requested entries. */
2532
2533   for (count = start_message; count <= end_message; count ++) {
2534
2535     message.Location = count;
2536
2537     error = GSM->DeleteSMSMessage(&message);
2538
2539     if (error == GE_NONE)
2540       fprintf(stdout, _("Deleted SMS %s %d\n"), memory_type_string, count);
2541     else {
2542       if (error == GE_NOTIMPLEMENTED) {
2543         fprintf(stderr, _("Function not implemented in %s model!\n"), model);
2544         GSM->Terminate();
2545         return -1;      
2546       }
2547       fprintf(stdout, _("DeleteSMS %s %d failed!(%d)\n\n"), memory_type_string, count, error);
2548     }
2549   }
2550
2551   GSM->Terminate();
2552
2553   return 0;
2554 }
2555
2556 static volatile bool bshutdown = false;
2557
2558 /* SIGINT signal handler. */
2559
2560 static void interrupted(int sig)
2561 {
2562
2563   signal(sig, SIG_IGN);
2564   bshutdown = true;
2565
2566 }
2567
2568 #ifdef SECURITY
2569
2570 /* In this mode we get the code from the keyboard and send it to the mobile
2571    phone. */
2572
2573 int entersecuritycode(char *type)
2574 {
2575   GSM_Error test;
2576   GSM_SecurityCode SecurityCode;
2577
2578   if (!strcmp(type,"PIN"))      SecurityCode.Type=GSCT_Pin;
2579   else if (!strcmp(type,"PUK")) SecurityCode.Type=GSCT_Puk;
2580   else if (!strcmp(type,"PIN2"))SecurityCode.Type=GSCT_Pin2;
2581   else if (!strcmp(type,"PUK2"))SecurityCode.Type=GSCT_Puk2;
2582
2583   // FIXME: Entering of SecurityCode does not work :-(
2584   //  else if (!strcmp(type,"SecurityCode"))
2585   //    SecurityCode.Type=GSCT_SecurityCode;
2586
2587   else {
2588     fprintf(stdout, _("Wrong code in second parameter (allowed: PIN,PUK,PIN2,PUK2,SecurityCode)\n"));
2589     return -1;
2590   }
2591
2592 #ifdef WIN32
2593   printf("Enter your code: ");
2594   gets(SecurityCode.Code);
2595 #else
2596   strcpy(SecurityCode.Code,getpass(_("Enter your code: ")));
2597 #endif
2598
2599   fbusinit(NULL);
2600
2601   test = GSM->EnterSecurityCode(SecurityCode);
2602   if (test==GE_NONE)
2603     fprintf(stdout,_("Code OK !\n"));
2604   else
2605     fprintf(stderr,_("%s\n"),print_error(test));
2606
2607   GSM->Terminate();
2608
2609   return 0;
2610 }
2611
2612 int getsecuritycodestatus(void)
2613 {
2614
2615   int Status;
2616
2617   fbusinit(NULL);
2618
2619   if (GSM->GetSecurityCodeStatus(&Status) == GE_NONE) {
2620
2621     fprintf(stdout, _("Security code status: "));
2622
2623       switch(Status) {
2624       case GSCT_SecurityCode:fprintf(stdout, _("waiting for Security Code.\n"));break;
2625       case GSCT_Pin:         fprintf(stdout, _("waiting for PIN.\n"));          break;
2626       case GSCT_Pin2:        fprintf(stdout, _("waiting for PIN2.\n"));         break;
2627       case GSCT_Puk:         fprintf(stdout, _("waiting for PUK.\n"));          break;
2628       case GSCT_Puk2:        fprintf(stdout, _("waiting for PUK2.\n"));         break;
2629       case GSCT_None:        fprintf(stdout, _("nothing to enter.\n"));         break;
2630       default:               fprintf(stdout, _("Unknown!\n"));
2631       }
2632   }
2633
2634   GSM->Terminate();
2635
2636   return 0;
2637 }
2638
2639 int getsecuritycode(char *type)
2640 {
2641
2642   GSM_SecurityCode SecurityCode;
2643   GSM_Error error;
2644
2645   if (!strcmp(type,"PIN"))              SecurityCode.Type=GSCT_Pin;
2646   else if (!strcmp(type,"PUK"))         SecurityCode.Type=GSCT_Puk;
2647   else if (!strcmp(type,"PIN2"))        SecurityCode.Type=GSCT_Pin2;
2648   else if (!strcmp(type,"PUK2"))        SecurityCode.Type=GSCT_Puk2;
2649   else if (!strcmp(type,"SecurityCode"))SecurityCode.Type=GSCT_SecurityCode;
2650   else {
2651     fprintf(stdout, _("Wrong code in second parameter (allowed: PIN,PUK,PIN2,PUK2,SecurityCode)\n"));
2652     return -1;
2653   }
2654     
2655   fbusinit(NULL);
2656
2657   error=GSM->GetSecurityCode(&SecurityCode);
2658   
2659   switch (error) {
2660     case GE_INVALIDSECURITYCODE:
2661       fprintf(stdout, _("Error: getting "));
2662       switch (SecurityCode.Type) {
2663         case GSCT_SecurityCode:fprintf(stdout, _("security code"));break;
2664         case GSCT_Pin :fprintf(stdout, _("PIN"));break;
2665         case GSCT_Pin2:fprintf(stdout, _("PIN2"));break;
2666         case GSCT_Puk :fprintf(stdout, _("PUK"));break;
2667         case GSCT_Puk2:fprintf(stdout, _("PUK2"));break;
2668         default:break;
2669       }
2670       fprintf(stdout, _(" not allowed\n"));
2671       break;
2672     case GE_NONE:
2673       switch (SecurityCode.Type) {
2674         case GSCT_SecurityCode:fprintf(stdout, _("Security code"));break;
2675         case GSCT_Pin :fprintf(stdout, _("PIN"));break;
2676         case GSCT_Pin2:fprintf(stdout, _("PIN2"));break;
2677         case GSCT_Puk :fprintf(stdout, _("PUK"));break;
2678         case GSCT_Puk2:fprintf(stdout, _("PUK2"));break;
2679         default:break;
2680       }
2681       fprintf(stdout, _(" is %s\n"),SecurityCode.Code);
2682       break;
2683     default:
2684       fprintf(stderr, _("%s\n"),print_error(error));
2685       break;
2686   }
2687
2688   GSM->Terminate();
2689
2690   return 0;
2691 }
2692
2693 #endif
2694
2695 /* Voice dialing mode. */
2696
2697 int dialvoice(char *Number)
2698 {
2699   fbusinit(NULL);
2700
2701   if (GSM->DialVoice(Number)!=GE_NONE) fprintf(stdout,_("Error!\n"));
2702
2703   GSM->Terminate();
2704
2705   return 0;
2706 }
2707
2708 /* Cancel a call */
2709 int cancelcall(void)
2710 {
2711   fbusinit(NULL);
2712
2713   if (GSM->CancelCall()!=GE_NONE) fprintf(stdout,_("Error!\n"));
2714
2715   GSM->Terminate();
2716
2717   return 0;
2718 }
2719
2720 int savelogo(int argc, char *argv[])
2721 {
2722   GSM_Bitmap bitmap;
2723   GSM_NetworkInfo NetworkInfo;
2724   GSM_MultiSMSMessage MultiSMS;
2725
2726   /* Operator logos will be saved with this number */  
2727   char oplogonumber[]={'O','p','L','o','g','o',
2728                        '0','0','0','0','0',   /* MMC+MNC */
2729                        '\0'};
2730   int i=0;
2731   
2732   bool UnicodeText=false;
2733
2734   /* The first argument is the type of the logo. */
2735   if (!strcmp(argv[0], "op")) {
2736     fprintf(stdout, _("Saving operator logo.\n"));
2737   } else if (!strcmp(argv[0], "caller")) {
2738     fprintf(stdout, _("Saving caller line identification logo.\n"));
2739   } else if (!strcmp(argv[0], "startup")) {
2740     fprintf(stderr, _("It isn't possible to save startup logo!\n"));
2741     return (-1);
2742   } else if (!strcmp(argv[0], "7110startup")) {
2743     fprintf(stderr, _("It isn't possible to save startup logo!\n"));
2744     return (-1);
2745   } else if (!strcmp(argv[0], "6210startup")) {
2746     fprintf(stderr, _("It isn't possible to save startup logo!\n"));
2747     return (-1);
2748   } else if (!strcmp(argv[0], "7110op")) {
2749     fprintf(stderr, _("It isn't possible to save big operator logos!\n"));
2750     return (-1);
2751   } else if (!strcmp(argv[0], "picture")) {
2752     fprintf(stderr, _("Saving picture image.\n"));
2753   } else if (!strcmp(argv[0], "screensaver")) {
2754     fprintf(stderr, _("Saving screen saver.\n"));
2755   } else {
2756     fprintf(stderr, _("You should specify what kind of logo to save!\n"));
2757     return (-1);
2758   }
2759
2760   /* The second argument is the bitmap file. */
2761   if (GSM_ReadBitmapFileOnConsole(argv[1], &bitmap)!=GE_NONE) return -1;
2762
2763   /* Initialise the GSM interface. */
2764   fbusinit(NULL);
2765
2766   /* We check optional parameters from 2'rd */
2767   optind = 2;
2768
2769   if (!strcmp(argv[0], "op")) {
2770     GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
2771   
2772     /* The third argument, if present, is the Network code of the operator.
2773      * Network code is in this format: "xxx yy" */
2774     if (argc > 2) {
2775       strcpy(bitmap.netcode, argv[2]);
2776 #ifdef DEBUG
2777       fprintf(stdout, _("Operator code: %s\n"), argv[2]);
2778 #endif
2779       if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown")) {
2780         fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
2781         GSM->Terminate();
2782         return -1;
2783       }
2784       optind++;
2785     } else
2786     {
2787       if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
2788     }
2789     bitmap.type=GSM_OperatorLogo;
2790
2791     /* Put bitmap into SMS structure */
2792     GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,false,false);
2793
2794     oplogonumber[6]=bitmap.netcode[0];
2795     oplogonumber[7]=bitmap.netcode[1];
2796     oplogonumber[8]=bitmap.netcode[2];
2797     oplogonumber[9]=bitmap.netcode[4];
2798     oplogonumber[10]=bitmap.netcode[5];
2799     for(i=0;i<MultiSMS.number;i++)
2800       strcpy(MultiSMS.SMS[i].Destination,oplogonumber);
2801   }
2802   if (!strcmp(argv[0], "caller")) {
2803     GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
2804   
2805     bitmap.type=GSM_CallerLogo;
2806
2807     /* Put bitmap into SMS structure */
2808     GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,false,false);
2809
2810     for(i=0;i<MultiSMS.number;i++)
2811       strcpy(MultiSMS.SMS[i].Destination,"GroupLogo");
2812   }
2813   if (!strcmp(argv[0], "screensaver")) {
2814     GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
2815
2816     bitmap.text[0]=0;
2817
2818     for(i=0;i<argc;i++)
2819       if (!strcmp(argv[i],"--unicode")) UnicodeText=true;
2820
2821     /* Put bitmap into SMS structure */
2822     GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,true,UnicodeText);
2823
2824     for(i=0;i<MultiSMS.number;i++)
2825       strcpy(MultiSMS.SMS[i].Destination,"ScreenSaver");
2826   }
2827   if (!strcmp(argv[0], "picture")) {  
2828     GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
2829
2830     for(i=0;i<argc;i++)
2831       if (!strcmp(argv[i],"--unicode")) UnicodeText=true;
2832
2833     bitmap.text[0]=0;
2834     if (argc>2) {
2835       optind++;
2836       if (strlen(argv[2])>121) {
2837         fprintf(stdout,_("Sorry: length of text (parameter \"%s\") can be 121 chars or shorter only !\n"),argv[2]);
2838         return -1;
2839       }
2840       strcpy(bitmap.text,argv[2]);
2841     }
2842     
2843     /* Put bitmap into SMS structure */
2844     GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,false,UnicodeText);
2845
2846     for(i=0;i<MultiSMS.number;i++)
2847       strcpy(MultiSMS.SMS[i].Destination,"Picture");
2848   }
2849
2850   GSM_SaveMultiPartSMSOnConsole(&MultiSMS, optind,argc,argv,false,true,false,false);
2851   
2852   return i;
2853 }
2854
2855 /* The following function allows to send logos using SMS */
2856 int sendlogo(int argc, char *argv[])
2857 {
2858   GSM_Bitmap bitmap;
2859   GSM_NetworkInfo NetworkInfo;
2860   GSM_MultiSMSMessage MultiSMS;
2861
2862   int i;
2863
2864   bool UnicodeText=false;
2865   bool ScreenSaver=false;
2866
2867   /* The first argument is the type of the logo. */
2868   if (!strcmp(argv[0], "op")) {
2869     fprintf(stdout, _("Sending operator logo.\n"));
2870   } else if (!strcmp(argv[0], "caller")) {
2871     fprintf(stdout, _("Sending caller line identification logo.\n"));
2872   } else if (!strcmp(argv[0], "picture")) {
2873     fprintf(stdout, _("Sending picture image.\n"));
2874   } else if (!strcmp(argv[0], "screensaver")) {
2875     fprintf(stdout, _("Sending screen saver.\n"));
2876   } else if (!strcmp(argv[0], "startup")) {
2877     fprintf(stderr, _("It isn't possible to send startup logo!\n"));
2878     return (-1);
2879   } else if (!strcmp(argv[0], "7110startup")) {
2880     fprintf(stderr, _("It isn't possible to send startup logo!\n"));
2881     return (-1);
2882   } else if (!strcmp(argv[0], "6210startup")) {
2883     fprintf(stderr, _("It isn't possible to send startup logo!\n"));
2884     return (-1);
2885   } else if (!strcmp(argv[0], "7110op")) {
2886     fprintf(stderr, _("It isn't possible to send big operator logos!\n"));
2887     return (-1);
2888   } else {
2889     fprintf(stderr, _("You should specify what kind of logo to send!\n"));
2890     return (-1);
2891   }
2892
2893   /* The third argument is the bitmap file. */
2894   if (GSM_ReadBitmapFileOnConsole(argv[2], &bitmap)!=GE_NONE) return -1;
2895
2896   /* Initialise the GSM interface. */
2897   fbusinit(NULL);
2898
2899   optind = 3;
2900
2901   if (!strcmp(argv[0], "op")) {
2902     GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
2903   
2904     /* The third argument, if present, is the Network code of the operator.
2905      * Network code is in this format: "xxx yy" */
2906     if (argc > 3) {
2907       strcpy(bitmap.netcode, argv[3]);
2908 #ifdef DEBUG
2909       fprintf(stdout, _("Operator code: %s\n"), argv[3]);
2910 #endif
2911       if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown")) {
2912         fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
2913         GSM->Terminate();
2914         return -1;
2915       }
2916       optind++;
2917     } else
2918     {
2919       if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
2920     }
2921     bitmap.type=GSM_OperatorLogo;
2922   }
2923   if (!strcmp(argv[0], "caller")) {
2924     GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
2925   
2926     bitmap.type=GSM_CallerLogo;
2927   }
2928   if (!strcmp(argv[0], "screensaver")) {
2929     GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
2930
2931     bitmap.text[0]=0;
2932
2933     for(i=0;i<argc;i++)
2934       if (!strcmp(argv[i],"--unicode")) UnicodeText=true;
2935     
2936     ScreenSaver=true;
2937   }
2938   if (!strcmp(argv[0], "picture")) {  
2939     GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
2940
2941     for(i=0;i<argc;i++)
2942       if (!strcmp(argv[i],"--unicode")) UnicodeText=true;
2943
2944     bitmap.text[0]=0;
2945     if (argc>3) {
2946       optind++;
2947       if (strlen(argv[3])>121) {
2948         fprintf(stdout,_("Sorry: length of text (parameter \"%s\") can be 121 chars or shorter only !\n"),argv[3]);
2949         return -1;
2950       }
2951       strcpy(bitmap.text,argv[3]);
2952     }
2953   }
2954
2955   /* Put bitmap into SMS structure */
2956   GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,ScreenSaver,UnicodeText);
2957
2958   /* The second argument is the destination, ie the phone number of recipient. */
2959   for(i=0;i<MultiSMS.number;i++)
2960     strcpy(MultiSMS.SMS[i].Destination,argv[1]);
2961
2962   GSM_SendMultiPartSMSOnConsole(&MultiSMS, optind,argc,argv,true,false,false);
2963
2964   return i;
2965 }
2966
2967 /* Getting logos. */
2968
2969 int getlogo(int argc, char *argv[])
2970 {
2971   GSM_Bitmap bitmap;
2972   GSM_Error error;
2973   int num;
2974
2975   bitmap.type=GSM_None;
2976
2977   if (!strcmp(argv[0],"7110op"))
2978     bitmap.type=GSM_7110OperatorLogo;
2979     
2980   if (!strcmp(argv[0],"op"))
2981     bitmap.type=GSM_OperatorLogo;
2982     
2983   if (!strcmp(argv[0],"caller")) {
2984     /* There is caller group number missing in argument list. */
2985     if (argc==3) {     
2986       num=argv[2][0]-'0';
2987       if ((num<1)||(num>9)) num=1;
2988       bitmap.number=num;
2989     } else
2990     {
2991       bitmap.number=1;
2992     }
2993     bitmap.number--;
2994     bitmap.type=GSM_CallerLogo;
2995   }
2996
2997   if (!strcmp(argv[0],"picture")) {
2998     /* There is a number missing in argument list. */
2999     if (argc==3) {     
3000       if (strlen(argv[2])==2) {
3001         num=(argv[2][0]-'0')*10+(argv[2][1]-'0');
3002       } else {
3003         num=argv[2][0]-'0';
3004       }
3005       if (num<1) num=1;
3006       bitmap.number=num;
3007     } else
3008     {
3009       bitmap.number=1;
3010     }
3011     bitmap.number--;
3012     bitmap.type=GSM_PictureImage;
3013   }    
3014
3015   if (!strcmp(argv[0],"startup"))
3016     bitmap.type=GSM_StartupLogo;
3017
3018   if (!strcmp(argv[0],"7110startup"))
3019     bitmap.type=GSM_7110StartupLogo;
3020
3021   if (!strcmp(argv[0],"6210startup"))
3022     bitmap.type=GSM_6210StartupLogo;
3023     
3024   if (!strcmp(argv[0],"dealer"))
3025     bitmap.type=GSM_DealerNoteText;  
3026     
3027   if (!strcmp(argv[0],"text"))
3028     bitmap.type=GSM_WelcomeNoteText;  
3029
3030   if (bitmap.type!=GSM_None) {
3031   
3032     fbusinit(NULL);
3033     
3034     fprintf(stdout, _("Getting Logo\n"));
3035         
3036     error=GSM->GetBitmap(&bitmap);
3037
3038     GSM->Terminate();
3039     
3040     switch (error)
3041     {
3042       case GE_NONE:
3043         if (bitmap.type==GSM_DealerNoteText) fprintf(stdout, _("Dealer welcome note "));
3044         if (bitmap.type==GSM_WelcomeNoteText) fprintf(stdout, _("Welcome note "));      
3045         if (bitmap.type==GSM_DealerNoteText || bitmap.type==GSM_WelcomeNoteText)
3046         {
3047           if (bitmap.text[0]!=0)
3048           {
3049             fprintf(stdout, _("currently set to \"%s\"\n"), bitmap.text);
3050           } else {
3051             fprintf(stdout, _("currently empty\n"));
3052           }
3053         } else
3054         {
3055           if (bitmap.width!=0)
3056           {
3057             if (bitmap.type==GSM_OperatorLogo || bitmap.type==GSM_7110OperatorLogo)
3058             {
3059               fprintf(stdout,"Operator logo for %s (%s) network got succesfully\n",bitmap.netcode,GSM_GetNetworkName(bitmap.netcode));
3060             }
3061             if (bitmap.type==GSM_StartupLogo || bitmap.type==GSM_7110StartupLogo || bitmap.type==GSM_6210StartupLogo)
3062             {
3063               fprintf(stdout,"Startup logo got successfully\n");
3064             }
3065             if (bitmap.type==GSM_CallerLogo)
3066             {
3067               fprintf(stdout,"Caller logo got successfully\n");
3068             }
3069             if (bitmap.type==GSM_PictureImage)
3070             {
3071               fprintf(stdout,"Picture Image got successfully");
3072               if (strcmp(bitmap.text,""))
3073                 fprintf(stdout,_(", text \"%s\""),bitmap.text);         
3074               if (strcmp(bitmap.Sender,""))
3075                 fprintf(stdout,_(", sender \"%s\""),bitmap.Sender);             
3076               fprintf(stdout,"\n");
3077             }
3078             if (argc>1)
3079             {
3080               if (GSM_SaveBitmapFileOnConsole(argv[1], &bitmap)!=GE_NONE) return(-1);
3081             }
3082           } else
3083           {
3084             fprintf(stdout,"Your phone doesn't have logo uploaded !\n");
3085             return -1;
3086           }
3087         }
3088         break;
3089       case GE_NOTIMPLEMENTED:
3090         fprintf(stderr, _("Function not implemented !\n"));
3091         return -1;
3092       case GE_NOTSUPPORTED:
3093         fprintf(stderr, _("This kind of logo is not supported !\n"));
3094         return -1;
3095       default:
3096         fprintf(stderr, _("Error getting logo (wrong location ?) !\n"));
3097         return -1;
3098     }
3099   } else
3100   {
3101     fprintf(stderr, _("What kind of logo do you want to get ?\n"));
3102     return -1;
3103   }
3104
3105   return 0;
3106 }
3107
3108 /* Setting logos. */
3109
3110 int setlogo(int argc, char *argv[])
3111 {
3112
3113   GSM_Bitmap bitmap,oldbit;
3114   GSM_NetworkInfo NetworkInfo;
3115   GSM_Error error;
3116   char model[64];
3117   int num;
3118   
3119   bool ok=true;
3120   
3121   int i;
3122   
3123   fbusinit(NULL);
3124   
3125   if (!strcmp(argv[0],"text") || !strcmp(argv[0],"dealer"))
3126   {
3127     if (!strcmp(argv[0],"text")) bitmap.type=GSM_WelcomeNoteText;
3128                             else bitmap.type=GSM_DealerNoteText;
3129     bitmap.text[0]=0x00;
3130     if (argc>1) strncpy(bitmap.text,argv[1],255);
3131   } else
3132   {
3133     if (!strcmp(argv[0],"op") || !strcmp(argv[0],"startup") || !strcmp(argv[0],"caller") ||
3134         !strcmp(argv[0],"7110op") || !strcmp(argv[0],"6210startup") || !strcmp(argv[0],"7110startup") ||
3135         !strcmp(argv[0],"picture"))
3136     {
3137       if (argc>1)
3138       {
3139         if (!strcmp(argv[0],"startup"))
3140         {
3141           bitmap.type=GSM_StartupLogo;
3142           bitmap.width=84;
3143           bitmap.height=48;
3144           bitmap.size=bitmap.width*bitmap.height/8;
3145           num=argv[1][0]-'0';
3146           if (num>=1 && num<=3) {
3147             bitmap.number=num;
3148           } else {
3149             if (GSM_ReadBitmapFileOnConsole(argv[1], &bitmap)!=GE_NONE) {
3150               GSM->Terminate();
3151               return(-1);
3152             }
3153             bitmap.number=0;
3154             GSM_ResizeBitmap(&bitmap,GSM_StartupLogo);
3155           }
3156         } else {
3157           if (GSM_ReadBitmapFileOnConsole(argv[1], &bitmap)!=GE_NONE) {
3158             GSM->Terminate();
3159             return(-1);
3160           }
3161         }
3162         if (!strcmp(argv[0],"op"))
3163         {
3164           if (bitmap.type!=GSM_OperatorLogo || argc<3)
3165           {
3166             if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
3167           }
3168           GSM_ResizeBitmap(&bitmap,GSM_OperatorLogo);
3169           if (argc==3)
3170           {
3171             strncpy(bitmap.netcode,argv[2],7);
3172             if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown"))
3173             {
3174               fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
3175               return -1;
3176             }
3177           }
3178         }
3179         if (!strcmp(argv[0],"7110op"))
3180         {
3181           if (bitmap.type!=GSM_7110OperatorLogo || argc<3)
3182           {
3183             if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
3184           }
3185           GSM_ResizeBitmap(&bitmap,GSM_7110OperatorLogo);
3186           if (argc==3)
3187           {
3188             strncpy(bitmap.netcode,argv[2],7);
3189             if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown"))
3190             {
3191               fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
3192               return -1;
3193             }
3194           }
3195         }
3196         if (!strcmp(argv[0],"picture"))
3197         {
3198           GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
3199           bitmap.number=1;
3200           if (argc>2)
3201           {
3202             if (strlen(argv[2])==2) {
3203               num=(argv[2][0]-'0')*10+(argv[2][1]-'0');
3204             } else {
3205               num=argv[2][0]-'0';
3206             }
3207             if (num<1) num=1;   
3208             bitmap.number=num;
3209           }
3210           bitmap.number--;
3211           bitmap.text[0]=0;
3212           if (argc>3)
3213             strncpy(bitmap.text,argv[3],121);
3214           strcpy(bitmap.Sender,"\0");
3215           if (argc>4)
3216             strncpy(bitmap.Sender,argv[4],GSM_MAX_SENDER_LENGTH);
3217         }
3218         if (!strcmp(argv[0],"7110startup"))
3219         {
3220           GSM_ResizeBitmap(&bitmap,GSM_7110StartupLogo);
3221         }
3222         if (!strcmp(argv[0],"6210startup"))
3223         {
3224           GSM_ResizeBitmap(&bitmap,GSM_6210StartupLogo);
3225         }
3226         if (!strcmp(argv[0],"caller"))
3227         {
3228           GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
3229           if (argc>2)
3230           {
3231             num=argv[2][0]-'0';
3232             if ((num<0)||(num>9)) num=0;
3233             bitmap.number=num;
3234           } else
3235           {
3236             bitmap.number=0;
3237           }
3238           oldbit.type=GSM_CallerLogo;
3239           oldbit.number=bitmap.number;
3240           if (GSM->GetBitmap(&oldbit)==GE_NONE)
3241           {
3242             /* We have to get the old name and ringtone!! */
3243             bitmap.ringtone=oldbit.ringtone;
3244             strncpy(bitmap.text,oldbit.text,255);
3245           }
3246           if (argc>3) strncpy(bitmap.text,argv[3],255);   
3247         }
3248         fprintf(stdout, _("Setting Logo.\n"));
3249       } else
3250       {
3251         /* FIX ME: is it possible to permanently remove op logo ? */
3252         if (!strcmp(argv[0],"op"))
3253         {
3254           bitmap.type=GSM_OperatorLogo;
3255           strncpy(bitmap.netcode,"000 00",7);
3256           bitmap.width=72;
3257           bitmap.height=14;
3258           bitmap.size=bitmap.width*bitmap.height/8;
3259           GSM_ClearBitmap(&bitmap);
3260         }
3261         if (!strcmp(argv[0],"7110op"))
3262         {
3263           bitmap.type=GSM_7110OperatorLogo;
3264           strncpy(bitmap.netcode,"000 00",7);
3265           bitmap.width=78;
3266           bitmap.height=21;
3267           bitmap.size=(bitmap.width*bitmap.height + 7)/8;
3268           GSM_ClearBitmap(&bitmap);
3269         }
3270         /* FIX ME: how to remove startup and group logos ? */
3271         fprintf(stdout, _("Removing Logo.\n"));
3272       }  
3273     } else
3274     {
3275       fprintf(stderr, _("What kind of logo do you want to set ?\n"));
3276       GSM->Terminate();
3277       return -1;
3278     }
3279   }
3280     
3281   while (GSM->GetModel(model)  != GE_NONE)
3282     sleep(1);
3283   
3284   /* For Nokia 6110/6130/6150 we use different method of uploading.
3285      Phone will display menu, when received it */
3286   if (!strcmp(model,"NSE-3") || !strcmp(model,"NSK-3") || !strcmp(model,"NSM-1"))
3287   {
3288     if (!strcmp(argv[0],"caller") && argc<3)
3289       bitmap.number=255;
3290     if (!strcmp(argv[0],"op") && argc<3)
3291       bitmap.number=255;
3292   }
3293
3294   error=GSM->SetBitmap(&bitmap);
3295   
3296   switch (error)
3297   {
3298     case GE_NONE: oldbit.type=bitmap.type;
3299                   oldbit.number=bitmap.number;
3300                   if (GSM->GetBitmap(&oldbit)==GE_NONE) {
3301                     if (bitmap.type==GSM_WelcomeNoteText ||
3302                         bitmap.type==GSM_DealerNoteText) {
3303                       if (strcmp(bitmap.text,oldbit.text)) {
3304                         fprintf(stderr, _("Error setting"));
3305                         if (bitmap.type==GSM_DealerNoteText) fprintf(stderr, _(" dealer"));
3306                         fprintf(stderr, _(" welcome note - "));
3307
3308                         /* I know, it looks horrible, but... */
3309                         /* I set it to the short string - if it won't be set */
3310                         /* it means, PIN is required. If it will be correct, previous */
3311                         /* (user) text was too long */
3312
3313                         /* Without it, I could have such thing: */
3314                         /* user set text to very short string (for example, "Marcin") */
3315                         /* then enable phone without PIN and try to set it to the very long (too long for phone) */
3316                         /* string (which start with "Marcin"). If we compare them as only length different, we could think, */
3317                         /* that phone accepts strings 6 chars length only (length of "Marcin") */
3318                         /* When we make it correct, we don't have this mistake */
3319                         
3320                         strcpy(oldbit.text,"!\0");
3321                         GSM->SetBitmap(&oldbit);
3322                         GSM->GetBitmap(&oldbit);
3323                         if (oldbit.text[0]!='!') {
3324                           fprintf(stderr, _("SIM card and PIN is required\n"));
3325                         } else {
3326                           GSM->SetBitmap(&bitmap);
3327                           GSM->GetBitmap(&oldbit);
3328                           fprintf(stderr, _("too long, truncated to \"%s\" (length %i)\n"),oldbit.text,strlen(oldbit.text));
3329                         }
3330                         ok=false;
3331                       }
3332                     } else {
3333                       if (bitmap.type==GSM_StartupLogo) {
3334                         for (i=0;i<oldbit.size;i++) {
3335                           if (oldbit.bitmap[i]!=bitmap.bitmap[i]) {
3336                             fprintf(stderr, _("Error setting startup logo - SIM card and PIN is required\n"));
3337                             ok=false;
3338                             break;
3339                           }
3340                         }
3341                       }
3342                     }
3343                   }
3344                   if (ok) fprintf(stdout, _("Done.\n"));
3345                   break;
3346     case GE_NOTIMPLEMENTED:fprintf(stderr, _("Function not implemented.\n"));
3347                            break;
3348     case GE_NOTSUPPORTED:fprintf(stderr, _("This kind of logo is not supported.\n"));
3349                            break;
3350     default:fprintf(stderr, _("Error (wrong location ?) !\n"));
3351             break;
3352   }
3353   
3354   GSM->Terminate();
3355
3356   return 0;
3357 }
3358
3359 /* Calendar notes receiving. */
3360
3361 int getcalendarnote(int argc, char *argv[])
3362 {
3363   GSM_CalendarNote CalendarNote;
3364   GSM_NotesInfo NotesInfo;
3365   GSM_Error error;
3366   int i;
3367   int vCalVer=0;
3368   bool vInfo=false;
3369   int start, stop;
3370   bool was_note=false;
3371   char z_text[MAX_CALENDAR_TEXT_LENGTH+11];
3372
3373   /* Hopefully is 64 larger as FB38_MAX* / FB61_MAX* */
3374   char model[64];
3375
3376   struct tm *now;
3377   time_t nowh;
3378   GSM_DateTime Date;
3379
3380   nowh=time(NULL);
3381   now=localtime(&nowh);
3382   
3383   Date.Year = now->tm_year;
3384
3385   /* I have 100 (for 2000) Year now :-) */
3386   if (Date.Year>99 && Date.Year<1900) {
3387     Date.Year=Date.Year+1900;
3388   }
3389
3390   start=atoi(argv[0]);  
3391   stop=start;
3392   
3393   switch (argc) {
3394     case 2:
3395       if (!strcmp(argv[argc-1],"-v10")) {
3396         vCalVer=10;
3397       } else {
3398         if (!strcmp(argv[argc-1],"-v30")) {
3399           vCalVer=30;
3400         } else {
3401           stop=atoi(argv[1]);
3402         }
3403       }
3404       break;
3405     case 3:
3406       stop=atoi(argv[1]);
3407       if (!strcmp(argv[argc-1],"-v10")) {
3408         vCalVer=10;
3409       } else {
3410         if (!strcmp(argv[argc-1],"-v30")) {
3411           vCalVer=30;
3412         } else {      
3413           usage();
3414           return -1;
3415         }
3416       }
3417       break;
3418   }
3419
3420   fbusinit(NULL);
3421
3422   while (GSM->GetModel(model)  != GE_NONE)
3423     sleep(1);
3424
3425   if (!strcmp(argv[0],"-s") || !strcmp(argv[0],"--short")) 
3426     vInfo=true;
3427   else if (!isdigit(argv[0][0])) {
3428     usage();
3429     return -1;
3430   }
3431     
3432   error=GSM->GetCalendarNotesInfo(&NotesInfo);
3433   if ( error == GE_NONE ) {
3434      if( NotesInfo.HowMany == 0 ) {
3435          fprintf(stderr, _("Sorry! No Calendar Notes present on phone.\n"));
3436          start=0; stop=(-1); /* This for skipping next 'for' loop ;-> */
3437       }
3438 #ifdef DEBUG
3439       fprintf(stdout, _(" CALENDAR NOTES INFO \n"));
3440       fprintf(stdout, _("---------------------\n"));
3441       fprintf(stdout, _("How Many Locations :%d\n"), NotesInfo.HowMany);
3442
3443       /* For 6210 (NPE-3) and 7110 (NSE-5), Locations have a different behaviour */
3444       if ( GetModelFeature (FN_CALENDAR)==F_CAL71 ) {
3445         fprintf(stdout, _("Locations are :\n"));
3446         for(i=0;i<NotesInfo.HowMany;i++)
3447             fprintf(stdout, _("%4d) %4d\n"), i+1, NotesInfo.Location[i]);
3448       }
3449 #endif
3450   } else {
3451       /* For 6210 (NPE-3) and 7110 (NSE-5), Locations have a different behaviour */
3452       if ( GetModelFeature (FN_CALENDAR)==F_CAL71 ) {
3453         fprintf(stderr, _("Can't read Notes Infos from phone.\n"));
3454         start=0; stop=(-1); /* This for skipping next 'for' loop ;-> */
3455       }
3456   }
3457
3458   if (GetModelFeature (FN_CALENDAR)!=F_CAL71) {
3459     error=GE_NONE;
3460     NotesInfo.HowMany=200;
3461     for (i=0;i<200;i++) {
3462       NotesInfo.Location[i]=i+1;
3463     }
3464   }
3465   
3466   if( vInfo && stop!=(-1) && error==GE_NONE )
3467   {
3468     /* Info datas (for 7110 and comp.) */
3469     fprintf(stdout, _(" CALENDAR NOTES SUMMARY INFORMATION \n"));
3470     fprintf(stdout, _(" ==================================\n"));
3471     if (GetModelFeature (FN_CALENDAR)==F_CAL71) {
3472       fprintf(stdout, _("Calendar notes present on phone: %d\n"), NotesInfo.HowMany);
3473       fprintf(stdout, _("Locations are :\n"));
3474     }
3475     fprintf(stdout,  "----------------------------------------------------------------------------\n");
3476     fprintf(stdout,_(" Loc Phys Type    Summary description              Dt start    Alarm  Recurs\n") );
3477     fprintf(stdout,  "----------------------------------------------------------------------------\n");
3478
3479     for(i=0;i<NotesInfo.HowMany;i++)
3480     {
3481       /* very short format ... */
3482       /*
3483       fprintf(stdout, _("%4d) %4d\n"), i, NotesInfo.Location[i]);
3484       */
3485       CalendarNote.Location=i+1;
3486       CalendarNote.ReadNotesInfo=false;
3487
3488       if (GSM->GetCalendarNote(&CalendarNote) == GE_NONE) {
3489         char z_type[11];
3490         char z_recur[15];
3491         switch (CalendarNote.Type) {
3492            case GCN_REMINDER:strcpy(z_type, "REMIND");  break;
3493            case GCN_CALL:    strcpy(z_type, "CALL");    break;
3494            case GCN_MEETING: strcpy(z_type, "MEETING"); break;
3495            case GCN_BIRTHDAY:strcpy(z_type, "BDAY");    break;
3496            default:          strcpy(z_type, "UNKNOWN"); break;
3497           }
3498
3499         if( CalendarNote.Recurrance ) {
3500           sprintf( z_recur,"%d ", CalendarNote.Recurrance/24 );
3501           strcat( z_recur, CalendarNote.Recurrance == 1 ? "day" : "days" );
3502         }
3503         else
3504           strcpy( z_recur, "No" );
3505
3506         strcpy(z_text,"");
3507         
3508         if( CalendarNote.Type == GCN_CALL )
3509           sprintf(z_text, "\"%s\"", CalendarNote.Phone );
3510           
3511         if (CalendarNote.Text[0]!=0)
3512           sprintf(z_text, "\"%s\"", CalendarNote.Text );
3513           
3514         if(CalendarNote.Type == GCN_BIRTHDAY) {
3515           int i_age;
3516           i_age = Date.Year - CalendarNote.Time.Year;
3517           sprintf(z_text, "\"%s (%d %s)\"", CalendarNote.Text,
3518              i_age, (i_age==1)?"year":"years");
3519           strcpy( z_recur, "-" );
3520           if (GetModelFeature (FN_CALENDAR)==F_CAL71)
3521             fprintf(stdout,
3522                 _("%4d %4d %-7.7s %-32.32s %04d-%02d-%02d  %s %s\n"), 
3523               i+1,NotesInfo.Location[i], z_type, z_text,
3524               CalendarNote.Time.Year, 
3525               CalendarNote.Time.Month, 
3526               CalendarNote.Time.Day,
3527               (CalendarNote.AlarmType==0x00) ? "Tone  " : "Silent",
3528               " " );
3529           else
3530             fprintf(stdout,
3531                 _("%4d %4d %-7.7s %-32.32s %04d-%02d-%02d  %s %s\n"), 
3532               i+1,NotesInfo.Location[i], z_type, z_text,
3533               CalendarNote.Time.Year, 
3534               CalendarNote.Time.Month, 
3535               CalendarNote.Time.Day,
3536               (CalendarNote.Alarm.Year) ? "Yes" : "No ",
3537               " " );
3538         } else
3539           if (GetModelFeature (FN_CALENDAR)==F_CAL71)
3540             fprintf(stdout,
3541                 _("%4d %4d %-7.7s %-32.32s %04d-%02d-%02d  %s    %s\n"), 
3542               i+1,NotesInfo.Location[i], z_type, z_text,
3543               CalendarNote.Time.Year, 
3544               CalendarNote.Time.Month, 
3545               CalendarNote.Time.Day,
3546               (CalendarNote.Alarm.Year) ? "Yes" : "No ",
3547               z_recur );
3548            else
3549             fprintf(stdout,
3550                 _("%4d %4d %-7.7s %-32.32s %04d-%02d-%02d  %s\n"), 
3551               i+1,NotesInfo.Location[i], z_type, z_text,
3552               CalendarNote.Time.Year, 
3553               CalendarNote.Time.Month, 
3554               CalendarNote.Time.Day,
3555               (CalendarNote.Alarm.Year) ? "Yes" : "No ");
3556       } else {
3557         if (GetModelFeature (FN_CALENDAR)!=F_CAL71) break;
3558       }
3559     }
3560   }
3561   else
3562   for (i=start;i<=stop;i++) {
3563     if (error==GE_NONE) {
3564         if( i>NotesInfo.HowMany ) {
3565             fprintf(stderr, _("Only %d Calendar Notes present on phone!\n"),NotesInfo.HowMany);
3566             break;
3567         }
3568         if( i==0 ) {
3569             fprintf(stderr, _("Calendar Notes location can't be zero... skipping.\n"));
3570             continue;
3571         }
3572     }
3573     
3574     CalendarNote.Location=i;
3575     CalendarNote.ReadNotesInfo=false;
3576
3577     if (GSM->GetCalendarNote(&CalendarNote) == GE_NONE) {
3578
3579       if (vCalVer!=0) {
3580         if (!was_note) {
3581           fprintf(stdout, GSM_GetVCALENDARStart(vCalVer));
3582           was_note=true;
3583         }
3584
3585         fprintf(stdout, GSM_GetVCALENDARNote(&CalendarNote,vCalVer));
3586
3587       } else {  /* not vCal */
3588
3589         if (was_note) {
3590           fprintf(stdout, "\n");
3591         } else {
3592           was_note=true;
3593         }
3594
3595         fprintf(stdout, _("   Type of the note: "));
3596
3597         switch (CalendarNote.Type) {
3598
3599           case GCN_REMINDER:fprintf(stdout, _("Reminder\n"));break;
3600           case GCN_CALL    :fprintf(stdout, _("Call\n"));    break;
3601           case GCN_MEETING :fprintf(stdout, _("Meeting\n")); break;
3602           case GCN_BIRTHDAY:fprintf(stdout, _("Birthday\n"));break;
3603           default:          fprintf(stdout, _("Unknown\n"));
3604
3605         }
3606
3607         /* For 3310: set date to 2090! */
3608         if (GetModelFeature (FN_CALENDAR)==F_CAL33) {
3609           fprintf(stdout, _("   Date: xxxx-%02d-%02d\n"), CalendarNote.Time.Month,
3610                                                           CalendarNote.Time.Day);
3611         } else {
3612           fprintf(stdout, _("   Date: %s %d-%02d-%02d\n"), 
3613                 DayOfWeek(CalendarNote.Time.Year, CalendarNote.Time.Month, CalendarNote.Time.Day),
3614                                                         CalendarNote.Time.Year,
3615                                                         CalendarNote.Time.Month,
3616                                                         CalendarNote.Time.Day);
3617         }
3618         
3619         fprintf(stdout, _("   Time: %02d:%02d:%02d\n"), CalendarNote.Time.Hour,
3620                                                         CalendarNote.Time.Minute,
3621                                                         CalendarNote.Time.Second);
3622
3623         if (CalendarNote.Alarm.Year!=0) {
3624           fprintf(stdout, _("   Alarm date: %s %d-%02d-%02d\n"), 
3625                         DayOfWeek(CalendarNote.Alarm.Year, CalendarNote.Alarm.Month, CalendarNote.Alarm.Day),
3626                                                               CalendarNote.Alarm.Year,
3627                                                               CalendarNote.Alarm.Month,
3628                                                               CalendarNote.Alarm.Day);
3629
3630           fprintf(stdout, _("   Alarm time: %02d:%02d:%02d\n"), CalendarNote.Alarm.Hour,
3631                                                                 CalendarNote.Alarm.Minute,
3632                                                                 CalendarNote.Alarm.Second);
3633           if ( GetModelFeature (FN_CALENDAR)==F_CAL71 ) 
3634             fprintf(stdout, _("   Alarm type: %s\n"), (CalendarNote.AlarmType==0x00) ?
3635                                                           "With Tone" : "Silent" );
3636         }
3637
3638         if ( GetModelFeature (FN_CALENDAR)==F_CAL71 && CalendarNote.Recurrance!= 0 ) 
3639            fprintf(stdout, "   It repeat every %d day%s\n", CalendarNote.Recurrance/24,
3640                        ((CalendarNote.Recurrance/24)>1) ? "s":"" );
3641
3642         if (CalendarNote.Type == GCN_BIRTHDAY)
3643         {
3644           int i_age;
3645           i_age = Date.Year - CalendarNote.Time.Year;
3646           fprintf(stdout, _("   Text: %s (%d %s)\n"), CalendarNote.Text,
3647               i_age, (i_age==1)?"year":"years");
3648         } else {
3649           if (CalendarNote.Text[0]!=0)
3650             fprintf(stdout, _("   Text: %s\n"), CalendarNote.Text);
3651         }
3652
3653         if (CalendarNote.Type == GCN_CALL)
3654           fprintf(stdout, _("   Phone: %s\n"), CalendarNote.Phone);
3655       }
3656     } else {
3657       fprintf(stderr, _("The calendar note %i can not be read\n"),i);
3658     }
3659   }
3660
3661   if (was_note && vCalVer!=0) {
3662     fprintf(stdout, GSM_GetVCALENDAREnd(vCalVer));
3663   }
3664   
3665   GSM->Terminate();
3666
3667   return 0;
3668 }
3669
3670 /* Writing calendar notes. */
3671
3672 int writecalendarnote(char *argv[])
3673 {
3674   GSM_CalendarNote CalendarNote;
3675   GSM_Error error;
3676   int number;
3677
3678   number=atoi(argv[1]);
3679   
3680   if (number<1) {
3681     fprintf(stdout, _("Number of calendar note must be 1 or higher\n"));
3682     return -1;
3683   }