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