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