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