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