Translated using Weblate.
[gammu.git] / gammu / gammu.c
blob986c9520606f6deadf2f81f54ef94f668328118d
1 /* (c) 2002-2006 by Marcin Wiacek and Michal Cihar */
2 /* FM stuff by Walek */
4 #define _GNU_SOURCE
5 #include <string.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdarg.h>
9 #include <locale.h>
10 #include <signal.h>
11 #include <ctype.h>
12 #include <wchar.h>
14 #include <gammu.h>
15 #include <gammu-config.h>
16 #include "gammu.h"
17 #include "common.h"
18 #include "memory.h"
19 #include "message.h"
20 #include "search.h"
21 #include "nokia.h"
22 #include "backup.h"
23 #include "files.h"
24 #include "calendar.h"
25 #include "misc.h"
27 #include "../helper/locales.h"
28 #include "../helper/printing.h"
29 #include "../helper/string.h"
30 #include "../helper/cmdline.h"
32 #ifdef DEBUG
33 # include "sniff.h"
34 #endif
35 #ifdef GSM_ENABLE_NOKIA_DCT3
36 # include "depend/nokia/dct3.h"
37 # include "depend/nokia/dct3trac/wmx.h"
38 #endif
39 #ifdef GSM_ENABLE_NOKIA_DCT4
40 # include "depend/nokia/dct4.h"
41 #endif
42 #ifdef GSM_ENABLE_ATGEN
43 # include "depend/siemens/dsiemens.h"
44 #endif
46 #ifdef HAVE_SYS_IOCTL_H
47 # include <sys/ioctl.h>
48 #endif
50 #ifdef CURL_FOUND
51 #include <curl/curl.h>
52 #endif
54 #define ALL_MEMORY_TYPES "DC|MC|RC|ON|VM|SM|ME|MT|FD|SL"
56 #define RSS_URL "http://wammu.eu/news/rss/"
57 #define RSS_STABLE_STRING "Gammu stable version "
58 #define RSS_TESTING_STRING "Gammu test version "
60 static void ListNetworks(int argc, char *argv[])
62 int i = 0;
63 const char *country_code = NULL;
65 if (argc > 2) {
66 for (i = 0; GSM_Countries[i].Code[0] != 0; i++) {
67 if (strcmp(GSM_Countries[i].Name, argv[2]) == 0 || strcasecmp(GSM_Countries[i].Code, argv[2]) == 0) {
68 country_code = GSM_Countries[i].Code;
69 printf(_("Networks for %s:"), GSM_Countries[i].Name);
70 printf("\n\n");
71 break;
74 if (country_code == NULL) {
75 printf(_("Unknown country name: %s."), argv[2]);
76 printf("\n");
77 Terminate(2);
80 printf("%-10s %s\n", _("Network"), _("Name"));
81 i = 0;
82 for (i = 0; GSM_Networks[i].Code[0] != 0; i++) {
83 if (country_code == NULL || strncmp(GSM_Networks[i].Code, country_code, 3) == 0) {
84 printf("%-10s %s\n", GSM_Networks[i].Code, GSM_Networks[i].Name);
89 static void PrintVersion(void)
91 printf(_("[Gammu version %s built %s on %s using %s]"),
92 GAMMU_VERSION, __TIME__, __DATE__, GetCompiler());
93 printf("\n\n");
96 static void Features(int argc UNUSED, char *argv[]UNUSED)
98 PrintVersion();
100 printf("%s\n", _("Compiled in features:"));
102 printf(" * %s\n", _("Protocols"));
103 #ifdef GSM_ENABLE_MBUS2
104 printf(" - %s\n", "MBUS2");
105 #endif
106 #ifdef GSM_ENABLE_FBUS2
107 printf(" - %s\n", "FBUS2");
108 #endif
109 #ifdef GSM_ENABLE_FBUS2DLR3
110 printf(" - %s\n", "FBUS2DLR3");
111 #endif
112 #ifdef GSM_ENABLE_FBUS2PL2303
113 printf(" - %s\n", "FBUS2PL2303");
114 #endif
115 #ifdef GSM_ENABLE_FBUS2BLUE
116 printf(" - %s\n", "FBUS2BLUE");
117 #endif
118 #ifdef GSM_ENABLE_FBUS2IRDA
119 printf(" - %s\n", "FBUS2IRDA");
120 #endif
121 #ifdef GSM_ENABLE_DKU2PHONET
122 printf(" - %s\n", "DKU2PHONET");
123 #endif
124 #ifdef GSM_ENABLE_DKU2AT
125 printf(" - %s\n", "DKU2AT");
126 #endif
127 #ifdef GSM_ENABLE_DKU5FBUS2
128 printf(" - %s\n", "DKU5FBUS2");
129 #endif
130 #ifdef GSM_ENABLE_PHONETBLUE
131 printf(" - %s\n", "PHONETBLUE");
132 #endif
133 #ifdef GSM_ENABLE_AT
134 printf(" - %s\n", "AT");
135 #endif
136 #ifdef GSM_ENABLE_ALCABUS
137 printf(" - %s\n", "ALCABUS");
138 #endif
139 #ifdef GSM_ENABLE_IRDAPHONET
140 printf(" - %s\n", "IRDAPHONET");
141 #endif
142 #ifdef GSM_ENABLE_IRDAAT
143 printf(" - %s\n", "IRDAAT");
144 #endif
145 #ifdef GSM_ENABLE_IRDAOBEX
146 printf(" - %s\n", "IRDAOBEX");
147 #endif
148 #ifdef GSM_ENABLE_IRDAGNAPBUS
149 printf(" - %s\n", "IRDAGNAPBUS");
150 #endif
151 #ifdef GSM_ENABLE_BLUEGNAPBUS
152 printf(" - %s\n", "BLUEGNAPBUS");
153 #endif
154 #ifdef GSM_ENABLE_BLUEFBUS2
155 printf(" - %s\n", "BLUEFBUS2");
156 #endif
157 #ifdef GSM_ENABLE_BLUEPHONET
158 printf(" - %s\n", "BLUEPHONET");
159 #endif
160 #ifdef GSM_ENABLE_BLUEAT
161 printf(" - %s\n", "BLUEAT");
162 #endif
163 #ifdef GSM_ENABLE_BLUEOBEX
164 printf(" - %s\n", "BLUEOBEX");
165 #endif
166 #ifdef LIBUSB_FOUND
167 printf(" - %s\n", "FBUSUSB");
168 #endif
170 printf(" * %s\n", _("Phones"));
171 #ifdef GSM_ENABLE_NOKIA650
172 printf(" - %s\n", "NOKIA650");
173 #endif
174 #ifdef GSM_ENABLE_NOKIA3320
175 printf(" - %s\n", "NOKIA3320");
176 #endif
177 #ifdef GSM_ENABLE_NOKIA6110
178 printf(" - %s\n", "NOKIA6110");
179 #endif
180 #ifdef GSM_ENABLE_NOKIA7110
181 printf(" - %s\n", "NOKIA7110");
182 #endif
183 #ifdef GSM_ENABLE_NOKIA9210
184 printf(" - %s\n", "NOKIA9210");
185 #endif
186 #ifdef GSM_ENABLE_NOKIA6510
187 printf(" - %s\n", "NOKIA6510");
188 #endif
189 #ifdef GSM_ENABLE_NOKIA3650
190 printf(" - %s\n", "NOKIA3650");
191 #endif
192 #ifdef GSM_ENABLE_NOKIA_DCT3
193 printf(" - %s\n", "DCT3");
194 #endif
195 #ifdef GSM_ENABLE_NOKIA_DCT4
196 printf(" - %s\n", "DCT4");
197 #endif
198 #ifdef GSM_ENABLE_ATGEN
199 printf(" - %s\n", "ATGEN");
200 #endif
201 #ifdef GSM_ENABLE_ALCATEL
202 printf(" - %s\n", "ALCATEL");
203 #endif
204 #ifdef GSM_ENABLE_SONYERICSSON
205 printf(" - %s\n", "SONYERICSSON");
206 #endif
207 #ifdef GSM_ENABLE_OBEXGEN
208 printf(" - %s\n", "OBEXGEN");
209 #endif
210 #ifdef GSM_ENABLE_GNAPGEN
211 printf(" - %s\n", "GNAPGEN");
212 #endif
213 printf(" - %s\n", "DUMMY");
215 printf(" * %s\n", _("Miscellaneous"));
216 #ifdef GSM_ENABLE_CELLBROADCAST
217 printf(" - %s\n", "CELLBROADCAST");
218 #endif
219 #ifdef GSM_ENABLE_BACKUP
220 printf(" - %s\n", "BACKUP");
221 #endif
222 #ifdef LIBINTL_LIB_FOUND
223 printf(" - %s\n", "GETTEXT");
224 #endif
225 #ifdef ICONV_FOUND
226 printf(" - %s\n", "ICONV");
227 #endif
228 #ifdef CURL_FOUND
229 printf(" - %s\n", "CURL");
230 #endif
234 * Converts version string to integer to allow comparing.
236 int VersionToInt(const char *Buffer)
238 size_t retval = 0, pos = 0;
240 retval = atoi(Buffer) * 10000;
241 while (Buffer[pos] != '.') {
242 pos++;
243 if (Buffer[pos] == '\0') {
244 return retval;
247 pos++;
248 retval += atoi(Buffer + pos) * 100;
249 while (Buffer[pos] != '.') {
250 pos++;
251 if (Buffer[pos] == '\0') {
252 return retval;
255 pos++;
256 return retval + atoi(Buffer + pos);
260 * Check whether there is not newer version available online.
262 static void CheckVersion(int argc, char *argv[])
264 GSM_File RSS;
265 gboolean checkstable = TRUE;
266 gboolean checktest = TRUE;
267 const char *pos;
268 char new_version[20];
269 size_t i;
270 GSM_Error error;
272 if (argc >= 3) {
273 if (strcasecmp(argv[2], "STABLE") == 0) {
274 checktest = FALSE;
278 /* Read file */
279 RSS.Buffer = NULL;
280 RSS.Used = 0;
281 error = GSM_ReadHTTPFile(RSS_URL, &RSS);
282 Print_Error(error);
284 if (checkstable) {
285 pos = strstr(RSS.Buffer, RSS_STABLE_STRING);
286 if (pos != NULL) {
287 pos += strlen(RSS_STABLE_STRING);
289 for (i = 0; i < sizeof(new_version) - 1 && (isdigit((int)pos[i]) || pos[i] == '.'); i++) {
290 new_version[i] = pos[i];
293 new_version[i] = 0;
295 if (VersionToInt(new_version) > VersionToInt(GAMMU_VERSION)) {
296 printf_info(_("There is newer stable Gammu version available! (%s instead of %s)\n"),
297 new_version, GAMMU_VERSION);
302 if (checktest) {
303 pos = strstr(RSS.Buffer, RSS_TESTING_STRING);
304 if (pos != NULL) {
305 pos += strlen(RSS_TESTING_STRING);
307 for (i = 0; i < sizeof(new_version) - 1 && (isdigit((int)pos[i]) || pos[i] == '.'); i++) {
308 new_version[i] = pos[i];
311 new_version[i] = 0;
313 if (VersionToInt(new_version) > VersionToInt(GAMMU_VERSION)) {
314 printf_info(_("There is newer testing Gammu version available! (%s instead of %s)\n"),
315 new_version, GAMMU_VERSION);
320 free(RSS.Buffer);
323 static void Version(int argc UNUSED, char *argv[]UNUSED)
325 PrintVersion();
327 printf("%s\n", _("Copyright (C) 2003 - 2012 Michal Cihar <michal@cihar.com> and other authors."));
329 printf("\n");
331 printf("%s\n", _("License GPLv2: GNU GPL version 2 <http://creativecommons.org/licenses/GPL/2.0/>."));
333 printf("%s\n", _("This is free software: you are free to change and redistribute it."));
335 printf("%s\n", _("There is NO WARRANTY, to the extent permitted by law."));
337 printf("\n");
339 printf("%s\n", _("Check <http://wammu.eu/gammu/> for updates."));
341 printf("\n");
344 int ProcessParameters(int start, int argc, char *argv[]);
347 * Reads commands from file (argv[2]) or stdin and executes them
348 * sequentially as if they were given on the command line. Also allows
349 * recursive calling (nested batches in the batch files).
351 static void RunBatch(int argc, char *argv[])
353 FILE *bf;
356 * @todo Allocate memory dynamically.
358 char ln[2000];
359 size_t i, len;
360 ssize_t pos;
361 int j, c = 0, argsc;
362 char *argsv[20];
363 gboolean origbatch;
364 char *name;
365 char std_name[] = N_("standard input");
367 if (argc == 2 || strcmp(argv[2], "-") == 0) {
368 bf = stdin;
369 name = gettext(std_name);
370 } else {
371 bf = fopen(argv[2], "r");
372 name = argv[2];
375 if (bf == NULL) {
376 printf(_("Batch file could not be opened: %s\n"), argv[2]);
377 return; /* not exit(), so that any parent batch can continue */
380 argsv[0] = argv[0];
381 origbatch = batch;
382 batch = TRUE;
383 while (!feof(bf)) {
384 ln[0] = 0;
385 if (fgets(ln, sizeof(ln) - 2, bf) == NULL) {
386 if (!feof(bf)) {
387 printf_err("%s", _("Error reading batch! Terminating.\n"));
388 } else {
389 printf_info("%s", _("Batch processed, terminating.\n"));
391 break;
394 /* Skip all traling whitespace */
395 for (pos = strlen(ln) - 1; pos >= 0; pos--) {
396 if (isspace((int)ln[pos])) {
397 ln[pos] = 0;
398 } else {
399 break;
403 if (strlen(ln) < 1 || ln[0] == '#') {
404 /* line is empty and is not a comment */
405 continue;
408 /* split words into strings in the array argsv */
409 i = 0;
410 j = 0;
411 argsc = 0;
412 len = strlen(ln);
413 while (i <= len) {
414 if (ln[i] == ' ' || ln[i] == 0) {
415 argsc++;
416 argsv[argsc] = malloc(i - j + 1);
417 strncpy(argsv[argsc], ln + j, i - j);
418 argsv[argsc][i - j] = 0;
419 j = i + 1;
421 i++;
423 if (argsc > 0) {
424 /* we have some usable command and parameters, send them into standard processing */
425 printf ("----------------------------------------------------------------------------\n");
426 printf(_("Executing batch \"%s\" - command %i: %s\n"), name, ++c, ln);
428 * @todo Handle return value from ProcessParameters.
430 ProcessParameters(0, argsc + 1, argsv);
431 for (j = 1; j <= argsc; j++) {
432 free(argsv[j]);
436 if (!origbatch) {
437 /* only close the batch if we are not in a nested batch */
438 batch = FALSE;
439 if (batchConn) {
440 GSM_Terminate();
443 fclose(bf);
446 NORETURN
447 void SendSMSDSMSObsolete(int argc, char *argv[])
449 printf_err("%s\n", _("SMS daemon is now in separate binary, please use gammu-smsd-inject instead of gammu sendsmsdsms!"));
450 Terminate(99);
453 NORETURN
454 void SMSDaemonObsolete(int argc, char *argv[])
456 printf_err("%s\n", _("SMS daemon is now in separate binary, please use gammu-smsd instead of gammu smsd!"));
457 Terminate(99);
460 void Help(int argc, char *argv[]);
462 static GSM_Parameters Parameters[] = {
463 /* *INDENT-OFF* */
464 {"help", 0, 1, Help, {H_Gammu,0}, "[topic]"},
465 {"identify", 0, 0, Identify, {H_Info,0}, ""},
466 {"version", 0, 0, Version, {H_Gammu,0}, ""},
467 {"features", 0, 0, Features, {H_Gammu,0}, ""},
468 {"checkversion", 0, 1, CheckVersion, {H_Gammu,0}, "[STABLE]"},
469 {"getdisplaystatus", 0, 0, GetDisplayStatus, {H_Info,0}, ""},
470 {"getlocation", 0, 0, GetLocation, {H_Info,0}, ""},
471 {"monitor", 0, 1, Monitor, {H_Info,H_Network,H_Call,0}, "[times]"},
472 {"battery", 0, 0, Battery, {H_Info,0}, ""},
473 {"setautonetworklogin", 0, 0, SetAutoNetworkLogin, {H_Network,0}, ""},
474 {"listnetworks", 0, 1, ListNetworks, {H_Network,0}, "[country]"},
475 {"getgprspoint", 1, 2, GetGPRSPoint, {H_Network,0}, "start [stop]"},
476 {"screenshot", 1, 1, Screenshot, {H_Other,0}, "filenamebase"},
477 {"getfilesystemstatus", 0, 0, GetFileSystemStatus, {H_Filesystem,0}, ""},
478 {"getfilesystem", 0, 1, GetFileSystem, {H_Filesystem,0}, "[-flatall|-flat]"},
479 {"getfilefolder", 1,40, GetFileFolder, {H_Filesystem,0}, "fileID, fileID, ..."},
480 {"addfolder", 2, 2, AddFolder, {H_Filesystem,0}, "parentfolderID name"},
481 {"deletefolder", 1, 1, DeleteFolder, {H_Filesystem,0}, "name"},
482 {"getfolderlisting", 1, 1, GetFolderListing, {H_Filesystem,0}, "folderID"},
483 {"getrootfolders", 0, 0, GetRootFolders, {H_Filesystem,0}, ""},
484 {"setfileattrib", 1, 5, SetFileAttrib, {H_Filesystem,0}, "folderID [-system] [-readonly] [-hidden] [-protected]"},
485 {"getfiles", 1,40, GetFiles, {H_Filesystem,0}, "fileID, fileID, ..."},
486 {"addfile", 2, 9, AddSendFile, {H_Filesystem,0}, "folderID name [-type JAR|BMP|PNG|GIF|JPG|MIDI|WBMP|AMR|3GP|NRT][-readonly][-protected][-system][-hidden][-newtime]"},
487 {"sendfile", 1, 1, AddSendFile, {H_Filesystem,0}, "name"},
488 {"deletefiles", 1,20, DeleteFiles, {H_Filesystem,0}, "fileID"},
489 #if defined(GSM_ENABLE_NOKIA_DCT3) || defined(GSM_ENABLE_NOKIA_DCT4)
490 {"nokiaaddplaylists", 0, 0, NokiaAddPlayLists, {H_Filesystem,H_Nokia,0}, ""},
491 {"nokiaaddfile", 2, 5, NokiaAddFile, {H_Filesystem,H_Nokia,0}, "APPLICATION|GAME file [-readonly][-overwrite][-overwriteall]"},
492 {"nokiaaddfile", 2, 5, NokiaAddFile, {H_Filesystem,H_Nokia,0}, "GALLERY|GALLERY2|CAMERA|TONES|TONES2|RECORDS|VIDEO|PLAYLIST|MEMORYCARD file [-name name][-protected][-readonly][-system][-hidden][-newtime]"},
493 {"playsavedringtone", 1, 1, DCT4PlaySavedRingtone, {H_Ringtone,0}, "number"},
494 #endif
495 {"playringtone", 1, 1, PlayRingtone, {H_Ringtone,0}, "file"},
496 {"getdatetime", 0, 0, GetDateTime, {H_DateTime,0}, ""},
497 {"setdatetime", 0, 2, SetDateTime, {H_DateTime,0}, "[HH:MM[:SS]] [YYYY/MM/DD]"},
498 {"getalarm", 0, 1, GetAlarm, {H_DateTime,0}, "[start]"},
499 {"setalarm", 2, 2, SetAlarm, {H_DateTime,0}, "hour minute"},
500 {"resetphonesettings", 1, 1, ResetPhoneSettings, {H_Settings,0}, "PHONE|DEV|UIF|ALL|FACTORY"},
501 {"getmemory", 2, 4, GetMemory, {H_Memory,0}, ALL_MEMORY_TYPES " start [stop [-nonempty]]"},
502 {"deletememory", 2, 3, DeleteMemory, {H_Memory,0}, ALL_MEMORY_TYPES " start [stop]"},
503 {"deleteallmemory", 1, 1, DeleteAllMemory, {H_Memory,0}, ALL_MEMORY_TYPES},
504 {"getallmemory", 1, 1, GetAllMemory, {H_Memory,0}, ALL_MEMORY_TYPES},
505 {"searchmemory", 1, 1, SearchMemory, {H_Memory,0}, "text"},
506 {"listmemorycategory", 1, 1, ListMemoryCategory, {H_Memory, H_Category,0}, "text|number"},
507 {"getfmstation", 1, 2, GetFMStation, {H_FM,0}, "start [stop]"},
508 {"getsmsc", 0, 2, GetSMSC, {H_SMS,0}, "[start [stop]]"},
509 {"setsmsc", 2, 2, SetSMSC, {H_SMS,0}, "location number"},
510 {"getsms", 2, 3, GetSMS, {H_SMS,0}, "folder start [stop]"},
511 {"deletesms", 2, 3, DeleteSMS, {H_SMS,0}, "folder start [stop]"},
512 {"deleteallsms", 1, 1, DeleteAllSMS, {H_SMS,0}, "folder"},
513 {"getsmsfolders", 0, 0, GetSMSFolders, {H_SMS,0}, ""},
514 {"getallsms", 0, 1, GetAllSMS, {H_SMS,0}, "-pbk"},
515 {"geteachsms", 0, 1, GetEachSMS, {H_SMS,0}, "-pbk"},
517 #define SMS_TEXT_OPTIONS "[-inputunicode][-16bit][-flash][-len len][-autolen len][-unicode][-enablevoice][-disablevoice][-enablefax][-disablefax][-enableemail][-disableemail][-voidsms][-replacemessages ID][-replacefile file][-text msgtext][-textutf8 msgtext]"
518 #define SMS_PICTURE_OPTIONS "[-text text][-unicode][-alcatelbmmi]"
519 #define SMS_PROFILE_OPTIONS "[-name name][-bitmap bitmap][-ringtone ringtone]"
520 #define SMS_EMS_OPTIONS "[-unicode][-16bit][-format lcrasbiut][-text text][-unicodefiletext file][-defsound ID][-defanimation ID][-tone10 file][-tone10long file][-tone12 file][-tone12long file][-toneSE file][-toneSElong file][-fixedbitmap file][-variablebitmap file][-variablebitmaplong file][-animation frames file1 ...][-protected number]"
521 #define SMS_SMSTEMPLATE_OPTIONS "[-unicode][-text text][-unicodefiletext file][-defsound ID][-defanimation ID][-tone10 file][-tone10long file][-tone12 file][-tone12long file][-toneSE file][-toneSElong file][-variablebitmap file][-variablebitmaplong file][-animation frames file1 ...]"
522 #define SMS_ANIMATION_OPTIONS ""
523 #define SMS_OPERATOR_OPTIONS "[-netcode netcode][-biglogo]"
524 #define SMS_RINGTONE_OPTIONS "[-long][-scale]"
525 #define SMS_SAVE_OPTIONS "[-folder id][-unread][-read][-unsent][-sent][-sender number][-smsname name]"
526 #define SMS_SEND_OPTIONS "[-report][-validity HOUR|6HOURS|DAY|3DAYS|WEEK|MAX][-save [-folder number]]"
527 #define SMS_COMMON_OPTIONS "[-smscset number][-smscnumber number][-reply][-maxsms num]"
529 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,0}, "TEXT " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_TEXT_OPTIONS},
530 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Ringtone,0}, "RINGTONE file " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_RINGTONE_OPTIONS},
531 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "OPERATOR file " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_OPERATOR_OPTIONS},
532 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "CALLER file " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS},
533 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "PICTURE file " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_PICTURE_OPTIONS},
534 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "ANIMATION frames file1 file2... " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_ANIMATION_OPTIONS},
535 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_MMS,0}, "MMSINDICATOR URL Title Sender " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS},
536 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_WAP,0}, "WAPINDICATOR URL Title " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS},
537 #ifdef GSM_ENABLE_BACKUP
538 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_WAP,0}, "BOOKMARK file location " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS},
539 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_WAP,0}, "WAPSETTINGS file location DATA|GPRS " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS},
540 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_MMS,0}, "MMSSETTINGS file location " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS},
541 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Calendar,0}, "CALENDAR file location " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS},
542 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_ToDo,0}, "TODO file location " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS},
543 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Memory,0}, "VCARD10|VCARD21 file SM|ME location [-nokia]" SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS},
544 #endif
545 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Settings,0}, "PROFILE " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_PROFILE_OPTIONS},
546 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,0}, "EMS " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_EMS_OPTIONS},
547 {"savesms", 1,30, SendSaveDisplaySMS, {H_SMS,0}, "SMSTEMPLATE " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_SMSTEMPLATE_OPTIONS},
549 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,0}, "TEXT destination " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS SMS_TEXT_OPTIONS},
550 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Ringtone,0}, "RINGTONE destination file " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS SMS_RINGTONE_OPTIONS},
551 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "OPERATOR destination file " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS SMS_OPERATOR_OPTIONS},
552 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "CALLER destination file " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS},
553 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "PICTURE destination file " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS SMS_PICTURE_OPTIONS},
554 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "ANIMATION destination frames file1 file2... " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS SMS_ANIMATION_OPTIONS},
555 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_MMS,0}, "MMSINDICATOR destination URL Title Sender " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS},
556 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_WAP,0}, "WAPINDICATOR destination URL Title " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS},
557 #ifdef GSM_ENABLE_BACKUP
558 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_WAP,0}, "BOOKMARK destination file location " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS},
559 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_WAP,0}, "WAPSETTINGS destination file location DATA|GPRS " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS},
560 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_MMS,0}, "MMSSETTINGS destination file location " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS},
561 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Calendar,0}, "CALENDAR destination file location " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS},
562 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_ToDo,0}, "TODO destination file location " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS},
563 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Memory,0}, "VCARD10|VCARD21 destination file SM|ME location [-nokia]" SMS_SEND_OPTIONS SMS_COMMON_OPTIONS},
564 #endif
565 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Settings,0}, "PROFILE destination " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS ""SMS_PROFILE_OPTIONS},
566 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,0}, "EMS destination " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS SMS_EMS_OPTIONS},
567 {"sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,0}, "SMSTEMPLATE destination " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS SMS_SMSTEMPLATE_OPTIONS},
569 {"displaysms", 2,30, SendSaveDisplaySMS, {H_SMS,0}, "... (options like in sendsms)"},
571 {"addsmsfolder", 1, 1, AddSMSFolder, {H_SMS,0}, "name"},
572 {"smsd", 2, 2, SMSDaemonObsolete, {H_Obsolete,0}, ""},
573 {"sendsmsdsms", 2,30, SendSMSDSMSObsolete, {H_Obsolete,0}, ""},
574 {"getmmsfolders", 0, 0, GetMMSFolders, {H_MMS,0}, ""},
575 {"getallmms", 0, 1, GetEachMMS, {H_MMS,0}, "[-save]"},
576 {"geteachmms", 0, 1, GetEachMMS, {H_MMS,0}, "[-save]"},
577 {"getringtone", 1, 2, GetRingtone, {H_Ringtone,0}, "location [file]"},
578 {"getphoneringtone", 1, 2, GetRingtone, {H_Ringtone,0}, "location [file]"},
579 {"getringtoneslist", 0, 0, GetRingtonesList, {H_Ringtone,0}, ""},
580 {"setringtone", 1, 6, SetRingtone, {H_Ringtone,0}, "file [-location location][-scale][-name name]"},
581 #if defined(GSM_ENABLE_NOKIA_DCT3) || defined(GSM_ENABLE_NOKIA_DCT4)
582 {"nokiacomposer", 1, 1, NokiaComposer, {H_Ringtone,H_Nokia,0}, "file"},
583 #endif
584 {"copyringtone", 2, 3, CopyRingtone, {H_Ringtone,0}, "source destination [RTTL|BINARY]"},
585 {"getussd", 1, 1, GetUSSD, {H_Call,0}, "code"},
586 {"dialvoice", 1, 2, DialVoice, {H_Call,0}, "number [show|hide]"},
587 {"maketerminatedcall", 2, 3, MakeTerminatedCall, {H_Call,0}, "number length [show|hide]"},
588 {"getspeeddial", 1, 2, GetSpeedDial, {H_Call,H_Memory,0}, "start [stop]"},
589 {"cancelcall", 0, 1, CancelCall, {H_Call,0}, "[id]"},
590 {"answercall", 0, 1, AnswerCall, {H_Call,0}, "[id]"},
591 {"unholdcall", 1, 1, UnholdCall, {H_Call,0}, "id"},
592 {"holdcall", 1, 1, HoldCall, {H_Call,0}, "id"},
593 {"conferencecall", 1, 1, ConferenceCall, {H_Call,0}, "id"},
594 {"splitcall", 1, 1, SplitCall, {H_Call,0}, "id"},
595 {"switchcall", 0, 1, SwitchCall, {H_Call,0}, "[id]"},
596 {"transfercall", 0, 1, TransferCall, {H_Call,0}, "[id]"},
597 {"divert", 3, 5, CallDivert, {H_Call,0}, "get|set all|busy|noans|outofreach all|voice|fax|data [number timeout]"},
598 {"canceldiverts", 0, 0, CancelAllDiverts, {H_Call,0}, ""},
599 {"senddtmf", 1, 1, SendDTMF, {H_Call,0}, "sequence"},
600 {"getcalendarsettings", 0, 0, GetCalendarSettings, {H_Calendar,H_Settings,0}, ""},
601 {"getalltodo", 0, 0, GetAllToDo, {H_ToDo,0}, ""},
602 {"listtodocategory", 1, 1, ListToDoCategory, {H_ToDo, H_Category,0}, "text|number"},
603 {"gettodo", 1, 2, GetToDo, {H_ToDo,0}, "start [stop]"},
604 {"deletetodo", 1, 2, DeleteToDo, {H_ToDo,0}, "start [stop]"},
605 {"getallnotes", 0, 0, GetAllNotes, {H_Note,0}, ""},
606 {"deletecalendar", 1, 2, DeleteCalendar, {H_Calendar,0}, "start [stop]"},
607 {"getallcalendar", 0, 0, GetAllCalendar, {H_Calendar,0}, ""},
608 {"getcalendar", 1, 2, GetCalendar, {H_Calendar,0}, "start [stop]"},
609 {"addcategory", 2, 2, AddCategory, {H_Category,H_ToDo,H_Memory,0}, "TODO|PHONEBOOK text"},
610 {"getcategory", 2, 3, GetCategory, {H_Category,H_ToDo,H_Memory,0}, "TODO|PHONEBOOK start [stop]"},
611 {"getallcategory", 1, 1, GetAllCategories, {H_Category,H_ToDo,H_Memory,0}, "TODO|PHONEBOOK"},
612 {"reset", 1, 1, Reset, {H_Other,0}, "SOFT|HARD"},
613 {"getprofile", 1, 2, GetProfile, {H_Settings,0}, "start [stop]"},
614 {"getsecuritystatus", 0, 0, GetSecurityStatus, {H_Info,0}, ""},
615 {"entersecuritycode", 2, 3, EnterSecurityCode, {H_Other,0}, "PIN|PUK|PIN2|PUK2|PHONE|NETWORK code|- [newpin|-]"},
616 {"deletewapbookmark", 1, 2, DeleteWAPBookmark, {H_WAP,0}, "start [stop]"},
617 {"getwapbookmark", 1, 2, GetWAPBookmark, {H_WAP,0}, "start [stop]"},
618 {"getwapsettings", 1, 2, GetWAPMMSSettings, {H_WAP,0}, "start [stop]"},
619 {"getmmssettings", 1, 2, GetWAPMMSSettings, {H_MMS,0}, "start [stop]"},
620 {"getsyncmlsettings", 1, 2, GetSyncMLSettings, {H_WAP,0}, "start [stop]"},
621 {"getchatsettings", 1, 2, GetChatSettings, {H_WAP,0}, "start [stop]"},
622 {"readmmsfile", 1, 2, ReadMMSFile, {H_MMS,0}, "file [-save]"},
623 {"getbitmap", 1, 3, GetBitmap, {H_Logo,0}, "STARTUP [file]"},
624 {"getbitmap", 1, 3, GetBitmap, {H_Logo,0}, "CALLER location [file]"},
625 {"getbitmap", 1, 3, GetBitmap, {H_Logo,0}, "OPERATOR [file]"},
626 {"getbitmap", 1, 3, GetBitmap, {H_Logo,0}, "PICTURE location [file]"},
627 {"getbitmap", 1, 3, GetBitmap, {H_Logo,0}, "TEXT"},
628 {"getbitmap", 1, 3, GetBitmap, {H_Logo,0}, "DEALER"},
629 {"setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "STARTUP file|1|2|3"},
630 {"setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "COLOURSTARTUP [fileID]"},
631 {"setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "WALLPAPER fileID"},
632 {"setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "CALLER location [file]"},
633 {"setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "OPERATOR [file [netcode]]"},
634 {"setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "COLOUROPERATOR [fileID [netcode]]"},
635 {"setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "PICTURE file location [text]"},
636 {"setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "TEXT text"},
637 {"setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "DEALER text"},
638 {"copybitmap", 1, 3, CopyBitmap, {H_Logo,0}, "inputfile [outputfile [OPERATOR|PICTURE|STARTUP|CALLER]]"},
639 {"presskeysequence", 1, 1, PressKeySequence, {H_Other,0}, "mMnNpPuUdD+-123456789*0#gGrR<>[]hHcCjJfFoOmMdD@"},
640 #if defined(WIN32) || defined(HAVE_PTHREAD)
641 {"searchphone", 0, 1, SearchPhone, {H_Other,0}, "[-debug]"},
642 #endif
643 {"install", 0, 1, Install, {H_Other,0}, "[-minimal]"},
644 #ifdef GSM_ENABLE_BACKUP
645 {"savefile", 4, 5, SaveFile, {H_Backup,H_Calendar,0}, "CALENDAR target.vcs file location"},
646 {"savefile", 4, 5, SaveFile, {H_Backup,H_ToDo,0}, "TODO target.vcs file location"},
647 {"savefile", 4, 5, SaveFile, {H_Backup,H_Memory,0}, "VCARD10|VCARD21 target.vcf file SM|ME location"},
648 {"savefile", 4, 5, SaveFile, {H_Backup,H_WAP,0}, "BOOKMARK target.url file location"},
649 {"convertbackup", 2, 2, ConvertBackup, {H_Backup,0}, "source.file output.file"},
650 {"backup", 1, 2, DoBackup, {H_Backup,H_Memory,H_Calendar,H_ToDo,H_Category,H_Ringtone,H_WAP,H_FM,0}, "file [-yes]"},
651 {"backupsms", 1, 2, BackupSMS, {H_Backup,H_SMS,0}, "file [-yes|-all]"},
652 {"restore", 1, 2, Restore, {H_Backup,H_Memory,H_Calendar,H_ToDo,H_Category,H_Ringtone,H_WAP,H_FM,0}, "file [-yes]"},
653 {"addnew", 1, 4, AddNew, {H_Backup,H_Memory,H_Calendar,H_ToDo,H_Category,H_Ringtone,H_WAP,H_FM,0}, "file [-yes] [-memory ME|SM|..]"},
654 {"restoresms", 1, 2, RestoreSMS, {H_Backup,H_SMS,0}, "file [-yes]"},
655 {"addsms", 2, 3, AddSMS, {H_Backup,H_SMS,0}, "folder file [-yes]"},
656 #endif
657 {"clearall", 0, 0, ClearAll, {H_Memory,H_Calendar,H_ToDo,H_Category,H_Ringtone,H_WAP,H_FM,0}, ""},
658 {"networkinfo", 0, 0, NetworkInfo, {H_Network,0}, ""},
659 #ifdef GSM_ENABLE_AT
660 {"siemenssatnetmon", 0, 0, ATSIEMENSSATNetmon, {H_Siemens,H_Network,0}, ""},
661 {"siemensnetmonact", 1, 1, ATSIEMENSActivateNetmon, {H_Siemens,H_Network,0}, "netmon_type"},
662 {"siemensnetmonitor", 1, 1, ATSIEMENSNetmonitor, {H_Siemens,H_Network,0}, "test"},
663 #endif
664 #ifdef GSM_ENABLE_NOKIA6110
665 {"nokiagetoperatorname", 0, 0, DCT3GetOperatorName, {H_Nokia,H_Network,0}, ""},
666 {"nokiasetoperatorname", 0, 2, DCT3SetOperatorName, {H_Nokia,H_Network,0}, "[networkcode name]"},
667 {"nokiadisplayoutput", 0, 0, DCT3DisplayOutput, {H_Nokia,0}, ""},
668 #endif
669 #ifdef GSM_ENABLE_NOKIA_DCT3
670 {"nokianetmonitor", 1, 1, DCT3netmonitor, {H_Nokia,H_Network,0}, "test"},
671 {"nokianetmonitor36", 0, 0, DCT3ResetTest36, {H_Nokia,0}, ""},
672 {"nokiadebug", 1, 2, DCT3SetDebug, {H_Nokia,H_Network,0}, "filename [[v11-22][,v33-44]...]"},
673 #endif
674 #ifdef GSM_ENABLE_NOKIA_DCT4
675 {"nokiagetpbkfeatures", 1, 1, DCT4GetPBKFeatures, {H_Nokia,H_Memory,0}, "memorytype"},
676 {"nokiasetvibralevel", 1, 1, DCT4SetVibraLevel, {H_Nokia,H_Other,0}, "level"},
677 {"nokiagetvoicerecord", 1, 1, DCT4GetVoiceRecord, {H_Nokia,H_Other,0}, "location"},
678 #ifdef GSM_ENABLE_NOKIA6510
679 {"nokiasetlights", 2, 2, DCT4SetLight, {H_Nokia,H_Tests,0}, "keypad|display|torch on|off"},
680 {"nokiatuneradio", 0, 0, DCT4TuneRadio, {H_Nokia,H_FM,0}, ""},
681 #endif
682 {"nokiamakecamerashoot", 0, 0, DCT4MakeCameraShoot, {H_Nokia,H_Other,0}, ""},
683 #endif
684 #if defined(GSM_ENABLE_NOKIA_DCT3) || defined(GSM_ENABLE_NOKIA_DCT4)
685 {"nokiavibratest", 0, 0, NokiaVibraTest, {H_Nokia,H_Tests,0}, ""},
686 {"nokiagett9", 0, 0, NokiaGetT9, {H_Nokia,H_SMS,0}, ""},
687 {"nokiadisplaytest", 1, 1, NokiaDisplayTest, {H_Nokia,H_Tests,0}, "number"},
688 {"nokiagetadc", 0, 0, NokiaGetADC, {H_Nokia,H_Tests,0}, ""},
689 {"nokiasecuritycode", 0, 0, NokiaSecurityCode, {H_Nokia,H_Info,0}, ""},
690 {"nokiaselftests", 0, 0, NokiaSelfTests, {H_Nokia,H_Tests,0}, ""},
691 {"nokiasetphonemenus", 0, 0, NokiaSetPhoneMenus, {H_Nokia,H_Other,0}, ""},
692 #endif
693 #ifdef DEBUG
694 {"decodesniff", 2, 3, DecodeSniff, {H_Decode,0}, "MBUS2|IRDA file [phonemodel]"},
695 {"decodebinarydump", 1, 2, DecodeBinaryDump, {H_Decode,0}, "file [phonemodel]"},
696 #endif
697 {"batch", 0, 1, RunBatch, {H_Other,0}, "[file]"},
698 {"", 0, 0, NULL, {0}, ""}
701 static HelpCategoryDescriptions HelpDescriptions[] = {
702 {H_Call, "call", N_("Calls")},
703 {H_SMS, "sms", N_("SMS and EMS")},
704 {H_Memory, "memory", N_("Memory (phonebooks and calls)")},
705 {H_Filesystem, "filesystem", N_("Filesystem")},
706 {H_Logo, "logo", N_("Logo and pictures")},
707 {H_Ringtone, "ringtone", N_("Ringtones")},
708 {H_Calendar, "calendar", N_("Calendar notes")},
709 {H_ToDo, "todo", N_("To do lists")},
710 {H_Note, "note", N_("Notes")},
711 {H_DateTime, "datetime", N_("Date, time and alarms")},
712 {H_Category, "category", N_("Categories")},
713 #ifdef GSM_ENABLE_BACKUP
714 {H_Backup, "backup", N_("Backing up and restoring")},
715 #endif
716 #if defined(GSM_ENABLE_NOKIA_DCT3) || defined(GSM_ENABLE_NOKIA_DCT4)
717 {H_Nokia, "nokia", N_("Nokia specific")},
718 #endif
719 #ifdef GSM_ENABLE_AT
720 {H_Siemens, "siemens", N_("Siemens specific")},
721 #endif
722 {H_Network, "network", N_("Network")},
723 {H_WAP, "wap", N_("WAP settings and bookmarks")},
724 {H_MMS, "mms", N_("MMS and MMS settings")},
725 {H_Tests, "tests", N_("Phone tests")},
726 {H_FM, "fm", N_("FM radio")},
727 {H_Info, "info", N_("Phone information")},
728 {H_Settings, "settings", N_("Phone settings")},
729 #ifdef DEBUG
730 {H_Decode, "decode", N_("Dumps decoding")},
731 #endif
732 {H_Other, "other", N_("Functions that don't fit elsewhere")},
733 {H_Gammu, "gammu", N_("Gammu information")},
734 {0, NULL, NULL}
735 /* *INDENT-ON* */
738 void HelpHeader(void)
740 PrintVersion();
743 void HelpGeneral(void)
745 int i = 0;
747 HelpHeader();
749 printf("%s\n\n", _("Usage: gammu [parameters] <command> [options]"));
750 printf("%s\n", _("Parameters before command configure gammu behaviour:"));
751 printf("%s\n", _("-c / --config <filename> ... name of configuration file"));
752 printf("%s\n", _("-s / --section <confign> ... section of config file to use, eg. 42"));
753 printf("%s\n", _("-d / --debug <level> ... debug level (nothing|text|textall|textalldate|binary|errors)"));
754 printf("%s\n\n", _("-f / --debug-file <filename> ... file for logging debug messages"));
756 printf("%s\n\n", _("Commands can be specified with or without leading --."));
758 /* We might want to put here some most used commands */
759 printf("%s\n\n", _("For more details, call help on specific topic (gammu --help topic). Topics are:"));
761 while (HelpDescriptions[i].category != 0) {
762 printf("%11s - %s\n", HelpDescriptions[i].option,
763 gettext(HelpDescriptions[i].description));
764 i++;
766 printf("\n");
769 void HelpSplit(int cols, int len, const char *buff)
771 int l, len2, pos, split;
772 gboolean in_opt, first = TRUE;
773 const char *remain;
774 char spaces[50], buffer[500];
776 if (cols == 0) {
777 printf(" %s\n", buff);
778 } else {
779 printf(" ");
780 spaces[0] = 0;
781 len2 = strlen(buff);
782 if (len + len2 < cols) {
783 printf("%s\n", buff);
784 } else {
785 for (l = 0; l < len; l++)
786 strcat(spaces, " ");
788 remain = buff;
790 while (strlen(remain) > 0) {
791 split = 0;
792 pos = 0;
793 in_opt = FALSE;
794 if (!first)
795 printf("%s", spaces);
796 while (pos < cols - len && remain[pos] != 0) {
797 if (in_opt && remain[pos] == ']') {
798 in_opt = FALSE;
799 split = pos;
800 } else if (remain[pos] == '[') {
801 in_opt = TRUE;
802 } else if (!in_opt
803 && remain[pos] == ' ') {
804 split = pos - 1;
806 pos++;
808 /* Can not be split */
809 if (split == 0) {
810 printf("%s\n", remain);
811 remain += strlen(remain);
812 } else {
813 first = FALSE;
814 split++;
815 strncpy(buffer, remain, split);
816 buffer[split] = 0;
817 printf("%s\n", buffer);
818 remain += split;
819 if (remain[0] == ' ')
820 remain++;
827 void Help(int argc, char *argv[])
829 int i = 0, j = 0, k, cols;
830 gboolean disp;
832 #ifdef TIOCGWINSZ
833 struct winsize w;
834 #endif
835 #if defined(WIN32) || defined(DJGPP)
836 #else
837 char *columns;
838 #endif
840 /* Just --help */
841 if (argc == 1) {
842 HelpGeneral();
843 return;
846 if (!strcmp(argv[1], "all")) {
847 HelpHeader();
848 } else {
849 while (HelpDescriptions[i].category != 0) {
850 if (strcasecmp(argv[1], HelpDescriptions[i].option) ==
852 break;
853 i++;
855 if (HelpDescriptions[i].category == 0) {
856 HelpGeneral();
857 printf("%s\n", _("Unknown help topic specified!"));
858 return;
860 HelpHeader();
861 printf(_("Gammu commands, topic: %s\n\n"),
862 HelpDescriptions[i].description);
865 #if defined(WIN32) || defined(DJGPP)
866 cols = 80;
867 #else
868 cols = 0;
869 /* If stdout is a tty, we will wrap to columns it has */
870 if (isatty(1)) {
871 #ifdef TIOCGWINSZ
872 if (ioctl(2, TIOCGWINSZ, &w) == 0) {
873 if (w.ws_col > 0)
874 cols = w.ws_col;
876 #endif
877 if (cols == 0) {
878 columns = getenv("COLUMNS");
879 if (columns != NULL) {
880 cols = atoi(columns);
881 if (cols <= 0)
882 cols = 0;
886 if (cols == 0) {
887 /* Fallback */
888 cols = 80;
891 #endif
893 while (Parameters[j].Function != NULL) {
894 k = 0;
895 disp = FALSE;
896 if (!strcmp(argv[1], "all")) {
897 if (j == 0)
898 disp = TRUE;
899 if (j != 0) {
900 if (strcmp
901 (Parameters[j].help,
902 Parameters[j - 1].help)) {
903 disp = TRUE;
904 } else {
905 if (strcmp
906 (Parameters[j].parameter,
907 Parameters[j - 1].parameter)) {
908 disp = TRUE;
912 } else {
913 while (Parameters[j].help_cat[k] != 0) {
914 if (Parameters[j].help_cat[k] ==
915 HelpDescriptions[i].category) {
916 disp = TRUE;
917 break;
919 k++;
922 if (disp) {
923 printf("%s", Parameters[j].parameter);
924 if (Parameters[j].help[0] == 0) {
925 printf("\n");
926 } else {
927 HelpSplit(cols - 1,
928 strlen(Parameters[j].parameter) + 1,
929 gettext(Parameters[j].help));
932 j++;
936 int ProcessParameters(int start, int argc, char *argv[])
938 int z = 0;
939 gboolean count_failed = FALSE;
941 /* Check parameters */
942 while (Parameters[z].Function != NULL) {
943 if (strcasecmp(Parameters[z].parameter, argv[1 + start]) == 0 ||
944 (strncmp(argv[1 + start], "--", 2) == 0 &&
945 strcasecmp(Parameters[z].parameter,
946 argv[1 + start] + 2) == 0)
948 if (argc - 2 - start < Parameters[z].min_arg) {
949 if (!count_failed) {
950 if (Parameters[z].min_arg ==
951 Parameters[z].max_arg) {
952 printf(_("More parameters required (function requires %d)\n"),
953 Parameters[z].min_arg);
954 } else {
955 printf(_("More parameters required (function requires %d to %d)\n"),
956 Parameters[z].min_arg,
957 Parameters[z].max_arg);
959 if (Parameters[z].help[0] != 0) {
960 printf("%s:\n",
961 _("Parameters help"));
964 if (Parameters[z].help[0] != 0) {
965 printf("%s\n",
966 gettext(Parameters[z].help));
968 count_failed = TRUE;
969 } else if (argc - 2 - start > Parameters[z].max_arg) {
970 if (!count_failed) {
971 if (Parameters[z].min_arg ==
972 Parameters[z].max_arg) {
973 printf(_("Too many parameters (function accepts %d)\n"),
974 Parameters[z].min_arg);
975 } else {
976 printf(_("Too many parameters (function accepts %d to %d)\n"),
977 Parameters[z].min_arg,
978 Parameters[z].max_arg);
980 if (Parameters[z].help[0] != 0) {
981 printf("%s:\n",
982 _("Parameters help"));
985 if (Parameters[z].help[0] != 0) {
986 printf("%s\n",
987 gettext(Parameters[z].help));
989 count_failed = TRUE;
990 } else {
991 Parameters[z].Function(argc - start,
992 argv + start);
993 break;
996 z++;
999 /* Tell user when we did nothing */
1000 if (Parameters[z].Function == NULL) {
1001 if (!count_failed) {
1002 HelpGeneral();
1003 printf("%s\n", _("Bad option!"));
1004 return 2;
1006 return 2;
1008 return 0;
1011 int main(int argc, char *argv[])
1013 int start = 0;
1014 int i, ret;
1015 char *cp, *locales_path, *rss;
1016 GSM_Config *smcfg;
1017 GSM_Config *smcfg0;
1018 GSM_Debug_Info *di;
1019 GSM_Error error;
1021 gboolean help = FALSE;
1022 gboolean debug_level_set = FALSE;
1023 gboolean debug_file_set = FALSE;
1024 const char *config_file = NULL;
1025 int only_config = -1;
1027 di = GSM_GetGlobalDebug();
1029 /* We don't want to use getopt here */
1030 for (i = 1; i < argc; i++) {
1031 if (strcasecmp(argv[i], "--help") == 0 ||
1032 strcasecmp(argv[i], "-h") == 0 ||
1033 strcasecmp(argv[i], "help") == 0) {
1034 help = TRUE;
1035 start++;
1036 } else if ((strcasecmp(argv[i], "--config") == 0 ||
1037 strcasecmp(argv[i], "-c") == 0) &&
1038 i + 1 < argc) {
1039 i++;
1040 config_file = argv[i];
1041 start += 2;
1042 } else if ((strcasecmp(argv[i], "--section") == 0 ||
1043 strcasecmp(argv[i], "-s") == 0) &&
1044 i + 1 < argc) {
1045 i++;
1046 only_config = GetInt(argv[i]);
1047 start += 2;
1048 } else if ((strcasecmp(argv[i], "--debug") == 0 ||
1049 strcasecmp(argv[i], "-d") == 0) &&
1050 i + 1 < argc) {
1051 i++;
1052 GSM_SetDebugFileDescriptor(stderr, FALSE, di);
1053 GSM_SetDebugLevel(argv[i], di);
1054 debug_level_set = TRUE;
1055 start += 2;
1056 } else if ((strcasecmp(argv[i], "--debug-file") == 0 ||
1057 strcasecmp(argv[i], "-f") == 0) &&
1058 i + 1 < argc) {
1059 i++;
1060 error = GSM_SetDebugFile(argv[i], di);
1061 Print_Error(error);
1062 debug_file_set = TRUE;
1063 start += 2;
1064 } else if (isdigit((int)argv[i][0])) {
1065 /* Compatibilitty: config file section */
1066 only_config = GetInt(argv[i]);
1067 if (only_config >= 0)
1068 start++;
1069 else
1070 only_config = -1;
1071 } else if (GSM_SetDebugLevel(argv[i], di)) {
1072 /* Compatibility: debug level */
1073 start++;
1074 debug_level_set = TRUE;
1075 } else {
1076 break;
1080 error = GSM_FindGammuRC(&cfg, config_file);
1081 if (error != ERR_NONE || cfg == NULL) {
1082 if (error == ERR_FILENOTSUPPORTED) {
1083 printf_warn("%s\n",
1084 _("Configuration could not be parsed!"));
1085 } else {
1086 printf_warn("%s\n", _("No configuration file found!"));
1089 locales_path = INI_GetValue(cfg, "gammu", "gammuloc", FALSE);
1090 GSM_InitLocales(locales_path);
1091 #ifdef LIBINTL_LIB_FOUND
1092 if (locales_path != NULL) {
1093 bindtextdomain("gammu", locales_path);
1094 } else {
1095 #if defined(LOCALE_PATH)
1096 bindtextdomain("gammu", LOCALE_PATH);
1097 #else
1098 bindtextdomain("gammu", ".");
1099 #endif
1101 textdomain("gammu");
1102 #endif
1104 gsm = GSM_AllocStateMachine();
1105 if (gsm == NULL) {
1106 printf_err("%s", _("Failed to allocate memory, aborting!\n"));
1107 exit(1);
1110 #ifdef CURL_FOUND
1111 curl_global_init(CURL_GLOBAL_ALL);
1112 #endif
1114 #ifdef DEBUG
1115 if (!debug_level_set) {
1116 GSM_SetDebugLevel("textall", di);
1118 if (!debug_file_set) {
1119 GSM_SetDebugFileDescriptor(stdout, FALSE, di);
1121 #endif
1123 cp = INI_GetValue(cfg, "gammu", "gammucoding", FALSE);
1124 if (cp) {
1125 GSM_SetDebugCoding(cp, di);
1128 /* Help? */
1129 if (help) {
1130 Help(argc - start, argv + start);
1131 Terminate(0);
1134 /* Do we have enough parameters? */
1135 if (argc <= start + 1) {
1136 HelpGeneral();
1137 printf("%s\n", _("Too few parameters!"));
1138 Terminate(2);
1141 smcfg0 = GSM_GetConfig(gsm, 0);
1143 for (i = 0; (smcfg = GSM_GetConfig(gsm, i)) != NULL; i++) {
1144 /* Wanted user specific configuration? */
1145 if (only_config != -1) {
1146 smcfg = smcfg0;
1147 error = GSM_ReadConfig(cfg, smcfg, only_config);
1148 /* Here we get only in first for loop */
1149 if (error != ERR_NONE) {
1150 printf_err(_("Failed to read [gammu%d] section from configuration file (gammurc)!\n"),
1151 only_config);
1152 printf_warn("%s\n", _("No configuration read, using builtin defaults!"));
1153 GSM_ReadConfig(NULL, smcfg, 0);
1155 } else {
1156 error = GSM_ReadConfig(cfg, smcfg, i);
1157 if (error != ERR_NONE) {
1158 if (i != 0) {
1159 /* We just end here, we already have some valid config */
1160 break;
1162 if (error == ERR_USING_DEFAULTS) {
1163 printf_warn("%s\n", _("No configuration read, using builtin defaults!"));
1167 GSM_SetConfigNum(gsm, GSM_GetConfigNum(gsm) + 1);
1169 /* We want to use only one file descriptor for global and state machine debug output */
1170 smcfg->UseGlobalDebugFile = TRUE;
1172 /* It makes no sense to open several debug logs... */
1173 if (i == 0) {
1174 /* Just for first config */
1175 /* When user gave debug level on command line */
1176 if (!debug_level_set) {
1177 /* Try to set debug level from config file */
1178 GSM_SetDebugLevel(smcfg->DebugLevel, di);
1180 /* If user gave debug file in gammurc, we will use it */
1181 if (!debug_file_set) {
1182 error = GSM_SetDebugFile(smcfg->DebugFile, di);
1183 Print_Error(error);
1187 if (i == 0) {
1188 rss = INI_GetValue(cfg, "gammu", "rsslevel", FALSE);
1189 if (rss) {
1190 printf_warn("Configuration option rsslevel is ignored, use '%s' instead\n", "gammu checkversion");
1194 /* We wanted to read just user specified configuration. */
1195 if (only_config != -1) {
1196 break;
1200 /* Check used version vs. compiled */
1201 if (!strcasecmp(GetGammuVersion(), GAMMU_VERSION) == 0) {
1202 printf_err(_("Version of installed libGammu.so (%s) is different to version of Gammu (%s)\n"),
1203 GetGammuVersion(), GAMMU_VERSION);
1204 Terminate(98);
1207 ret = ProcessParameters(start, argc, argv);
1209 Terminate(ret);
1211 return ret;
1214 /* How should editor hadle tabs in this file? Add editor commands here.
1215 * vim: noexpandtab sw=8 ts=8 sts=8: