umtsmon is a tool to handle UMTS (3G) devices in Linux This is a port to TDE from https://sourceforge.net/p/umtsmon/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.cpp 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. /* umtsmon - a program to control/monitor your UMTS card
  2. * This file copyright (C) 2006, 2008 Klaas van Gend
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation
  7. * applicable version is GPL version 2 only.
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program; if not, write to the Free Software
  14. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #include "umtsmon_global.h"
  17. #include "mainwindow.h"
  18. #include "TheDeviceManagerSingleton.h"
  19. #include "Runner.h"
  20. #include "Popup.h"
  21. #include "Internationalisation.h"
  22. #include <ntqapplication.h>
  23. #include <ntqmessagebox.h>
  24. #include <ntqtextcodec.h>
  25. #include <assert.h>
  26. #include <signal.h>
  27. #include <stdlib.h>
  28. // forward declarations
  29. void popupAbortMessageBox(int);
  30. void printAbortMessage(int);
  31. static const int MAXLONGCOMMANDSIZE = 20;
  32. static const int MAXSHORTCOMMANDSIZE = 4;
  33. // oops global variable declared here...
  34. // let's make sure they do not multiply :-)
  35. int theVerbosity = 1;
  36. int thePPPVerbosity = 0;
  37. static char* theLocale = NULL;
  38. static bool setDefProfile(char* anArgument)
  39. {
  40. DEBUG5("setDefProfile: '%s'\n", anArgument);
  41. // all argument checking is done in in the class :-D
  42. if (Profile::setActiveProfile(anArgument) == false)
  43. {
  44. printf("ERROR: Profile \"%s\" does not exist\n", anArgument);
  45. exit(2);
  46. }
  47. return true;
  48. }
  49. static bool setForceAutodetection( __attribute__ ((unused)) char* anArgument)
  50. {
  51. TheDeviceManagerSingleton::me().setForceAutodetection();
  52. return true;
  53. }
  54. static bool setLocale(char* anArgument)
  55. {
  56. // will be parsed/verified later in main()
  57. theLocale = anArgument;
  58. return true;
  59. }
  60. static bool setAutoConnect(__attribute__ ((unused)) char* anArgument)
  61. {
  62. DEBUG5("setautoconnect\n");
  63. TheSettingsSingleton::getTQSRef().writeEntry(theGeneralAutoConnectSettingName, true);
  64. return true;
  65. }
  66. static bool setNoAutoConnect(__attribute__ ((unused)) char* anArgument)
  67. {
  68. DEBUG5("setNOautoconnect\n");
  69. TheSettingsSingleton::getTQSRef().writeEntry(theGeneralAutoConnectSettingName, false);
  70. return true;
  71. }
  72. static bool setSerial(char* anArgument)
  73. {
  74. DEBUG5("setSerial: '%s'\n", anArgument);
  75. // no need to do advanced parameter checking
  76. // - that'll be done later on, right?
  77. // is there a comma in? in that case we neet to set both AT and PPP
  78. TQStringList myList = TQStringList::split(',', anArgument);
  79. switch (myList.count())
  80. {
  81. case 1:
  82. TheDeviceManagerSingleton::me().setSuggestedAT(myList[0]);
  83. TheDeviceManagerSingleton::me().setSuggestedPPP("");
  84. TheDeviceManagerSingleton::me().setSuggestedDeviceType(DeviceCapabilities::GENERIC_USER_SERIAL);
  85. break;
  86. case 2:
  87. TheDeviceManagerSingleton::me().setSuggestedAT(myList[0]);
  88. TheDeviceManagerSingleton::me().setSuggestedPPP(myList[1]);
  89. TheDeviceManagerSingleton::me().setSuggestedDeviceType(DeviceCapabilities::GENERIC_USER_SERIAL);
  90. break;
  91. default:
  92. printf("ERROR: supply max 2 devices to --serial\n");
  93. exit(2);
  94. break;
  95. }
  96. return true;
  97. }
  98. static bool setVerbosity(char* anArgument)
  99. {
  100. DEBUG1("setVerbosity: '%s'\n", anArgument);
  101. // the argument should be a number. Let's parse.
  102. int myNumber = atoi(anArgument);
  103. if (myNumber < 1 || myNumber > MAX_VERBOSITY)
  104. {
  105. printf("ERROR: verbosity argument should be between 1 and 5\n");
  106. return false;
  107. }
  108. theVerbosity = myNumber;
  109. DEBUG2("set verbosity level to %d\n", theVerbosity);
  110. // check if we have a second argument after a comma (ppp-verbosity)
  111. char* comma = strchr(anArgument, ',');
  112. if (comma != NULL)
  113. {
  114. myNumber = atoi(comma + 1);
  115. if (myNumber < 0 || myNumber > 2)
  116. {
  117. printf("ERROR: PPP verbosity argument should be between 0 and 2\n");
  118. return false;
  119. }
  120. thePPPVerbosity = myNumber;
  121. }
  122. else
  123. {
  124. // verbosity > 2 => pppverbosity = 1; verbosity > 4 => pppverbosity = 2
  125. thePPPVerbosity = (theVerbosity - 1) / 2;
  126. }
  127. DEBUG2("set PPP verbosity level to %d\n", thePPPVerbosity);
  128. return true;
  129. }
  130. static bool help( __attribute__ ((unused)) char* anArgument)
  131. {
  132. printf(APPNAME " " APPRELEASE "" APPFLAVOUR "\n\nhelp text\n\n");
  133. printf(" --help gives this help text\n");
  134. printf(" -h gives this help text\n");
  135. printf(" --force-autodetect force autodetection (don't use info from config file)\n");
  136. printf(" --serial <at>[,ppp] will prevent autodetection of devices and use serial port <at>[,<ppp>]\n");
  137. printf(" -s <at>[,<ppp>] will prevent autodetection of devices and use serial port <at>[,<ppp>]\n");
  138. printf(" --verbosity <lvl>[,ppplvl] set verbosity, 1=little (default), %d=all\n", MAX_VERBOSITY);
  139. printf(" -v <lvl>[,ppplvl] set verbosity\n");
  140. printf(" --language <locale> set the language, e.g. nl or pt_BR\n");
  141. printf(" --autoconnect set autoconnect to true (persistant!)\n");
  142. printf(" --no-autoconnect set autoconnect to false (persistant!)\n");
  143. printf(" --default-profile <profilename> sets the default profile to connect with (persistant!)\n");
  144. printf("\n(parameters in <> are required, parameters in [] are optional)\n");
  145. printf("\n");
  146. exit(1);
  147. }
  148. /// the formatting for theArgsTable
  149. struct ArgsStruct
  150. {
  151. char theFullCommand [MAXLONGCOMMANDSIZE];
  152. char theShortCommand[MAXSHORTCOMMANDSIZE];
  153. bool needsArgument;
  154. bool (*theFunctionPtr)(char* anArgument);
  155. };
  156. static ArgsStruct theArgsTable[] =
  157. {
  158. // long, short, has args, function name
  159. { "--help", "-h", false, help, },
  160. { "--serial", "-s", true, setSerial, },
  161. { "--verbosity", "-v", true, setVerbosity, },
  162. { "--force-autodetect", "", false, setForceAutodetection, },
  163. { "--language", "", true, setLocale, },
  164. { "--autoconnect", "", false, setAutoConnect, },
  165. { "--no-autoconnect", "", false, setNoAutoConnect, },
  166. { "--default-profile", "-p", true, setDefProfile, },
  167. // keep this one last
  168. { "\0", "\0", false, NULL, },
  169. };
  170. /** compare strings.
  171. * @returns If 0, no match, if positive nonzero: the character at this index is extra
  172. */
  173. static int compareStrings(const char* anArgument, const char* aCommand)
  174. {
  175. int i=0;
  176. while(true)
  177. {
  178. // we're at the end of the command - a match, maybe with info left...
  179. if (aCommand[i] == 0)
  180. return i;
  181. // the argument is shorter than the command - cannot be a match :-(
  182. if (anArgument[i] == 0)
  183. break;
  184. if (anArgument[i] != aCommand[i])
  185. break;
  186. i++;
  187. }
  188. // if we get here, it was no match :-(
  189. return 0;
  190. }
  191. int main( int argc, char **argv )
  192. {
  193. TQApplication myTQApp( argc, argv );
  194. puts( APPNAME " version " APPRELEASE "" APPFLAVOUR " ." );
  195. // perform command line parsing
  196. // skip argv[0] because we know what's in there
  197. for ( int i = 1; i < myTQApp.argc(); i++ )
  198. {
  199. int myMatchPoint = 0;
  200. char* myArgvPtr = myTQApp.argv()[i];
  201. ArgsStruct* myTEntry;
  202. for (int j = 0; theArgsTable[j].theFullCommand[0]!='\0'; j++)
  203. {
  204. myTEntry = &(theArgsTable[j]);
  205. myMatchPoint = compareStrings(myArgvPtr, myTEntry->theFullCommand);
  206. if (myMatchPoint)
  207. break;
  208. myMatchPoint = compareStrings(myArgvPtr, myTEntry->theShortCommand);
  209. if (myMatchPoint)
  210. break;
  211. } // end of the 'j' loop
  212. if (myMatchPoint)
  213. {
  214. char* anArgument = NULL;
  215. // there are several cases:
  216. // 1) -s 3
  217. // 2) -s3
  218. // 3) -s=3
  219. // 4) --serial=3
  220. // 5) --serial 3
  221. // 6) --help (no arguments)
  222. // 7) -h (no arguments)
  223. // cases 1,2,3,4,5:
  224. if (myTEntry->needsArgument)
  225. {
  226. // is there extra data in this argument (i.e. cases 2,3,4)
  227. if (myArgvPtr[myMatchPoint] != 0)
  228. {
  229. // is it a '=' (case3,4) - then advance one character
  230. if (myArgvPtr[myMatchPoint] == '=')
  231. myMatchPoint++;
  232. anArgument = &myArgvPtr[myMatchPoint];
  233. }
  234. else
  235. {
  236. // case 1,5:
  237. // is there a next argument to parse?
  238. if ( (i+1) < myTQApp.argc())
  239. {
  240. anArgument = myTQApp.argv()[i+1];
  241. i++;
  242. }
  243. else
  244. anArgument = NULL;
  245. }
  246. }
  247. if (myTEntry->needsArgument==true && anArgument==NULL)
  248. {
  249. printf("parsing error: missing argument to '%s'!\n", myArgvPtr);
  250. exit(3);
  251. }
  252. if (myTEntry->theFunctionPtr(anArgument) == false)
  253. {
  254. printf("...\nExiting gracefully\n\n");
  255. help(NULL);
  256. // this should never be reached:
  257. exit(1);
  258. }
  259. }
  260. else
  261. {
  262. printf("ERROR: unknown argument '%s'\n", myArgvPtr);
  263. exit(2);
  264. }
  265. } // end of the 'i' loop
  266. // If a user who doesn't run umtsmon from the command line hits an assert,
  267. // the program stops without a visible UI message.
  268. // let's fix that here: if no verbosity is set, register a SIGABRT handler to pop up a dialog
  269. if (theVerbosity <= 1)
  270. {
  271. printf("installing GUI SIGABRT handler\n");
  272. signal(SIGABRT, popupAbortMessageBox);
  273. }
  274. else
  275. {
  276. // also register a handler explaining what to do
  277. // if the users enabled lots of verbosity
  278. if (theVerbosity >= 5)
  279. {
  280. printf("installing text SIGABRT handler\n");
  281. signal(SIGABRT, printAbortMessage);
  282. }
  283. }
  284. // Setup translations
  285. // * we may have a valid theLocale (i.e. specified on command line), we should check it
  286. // * we may have a valid locale as a setting, we should check it
  287. // * we may have a valid locale in the environment
  288. Internationalisation myI18n( &myTQApp );
  289. bool myI18nResult = false;
  290. if (theLocale!=NULL)
  291. {
  292. myI18nResult = myI18n.tryLocale(theLocale);
  293. if (myI18nResult == false)
  294. {
  295. DEBUG1("ERROR: your specified locale (\"%s\") is not valid\n", theLocale);
  296. exit(1);
  297. }
  298. }
  299. else
  300. myI18nResult = myI18n.trySavedLocale();
  301. if (myI18nResult == false)
  302. myI18nResult = myI18n.tryLocale(TQTextCodec::locale());
  303. if (myI18nResult == false)
  304. DEBUG5("Running on the default (en_US) locale\n");
  305. Popup::WarningWithMemory("WelcomeMsg", TQObject::tr("Welcome to umtsmon."));
  306. // check for rootness - useful for the logs if users do odd things
  307. if (Runner::amIRoot())
  308. DEBUG1(APPNAME " is running as root!!!\n");
  309. ////////////////////////////////////
  310. // and start the application
  311. // do not forget to pass on some initialised classes
  312. mainwindow w;
  313. myTQApp.setMainWidget( &w );
  314. w.setI18nRef(myI18n);
  315. w.show();
  316. return myTQApp.exec();
  317. }
  318. void popupAbortMessageBox(__attribute__ ((unused)) int aSignalNumber)
  319. {
  320. static bool isFirstTimeHere=true;
  321. if ( !isFirstTimeHere )
  322. return;
  323. isFirstTimeHere=false;
  324. TQMessageBox::critical (NULL,
  325. APPNAME " assert error",
  326. APPNAME " ran into a problem and unfortunately had to close. "
  327. "It is highly likely that if you run " APPNAME "from a command line, like:\n"
  328. APPNAME " -v5\n"
  329. "you will get information on what went wrong, including"
  330. " information on how to help us solve it.\n"
  331. "We thank you in advance for helping us improve " APPNAME "!",
  332. TQMessageBox::Ok | TQMessageBox::Default,
  333. TQMessageBox::NoButton,
  334. TQMessageBox::NoButton);
  335. // do not call exit here - or the signal will not be handled correctly
  336. }
  337. void printAbortMessage(__attribute__ ((unused)) int aSignalNumber)
  338. {
  339. printf("\n\n *** " APPNAME " version " APPRELEASE "" APPFLAVOUR " closed due to an"
  340. " unrecoverable program error.\n"
  341. " *** Please e-mail all of the above output to"
  342. " umtsmon-develop@lists.sourceforge.net,\n"
  343. " *** Or go to the " APPNAME " website and file a bug.\n\n\n");
  344. // do not call exit here - or the signal will not be handled correctly
  345. }