[PATCH] Bug fixes for libgsmd-tool -m shell

Jorgen Cederlof jc at lysator.liu.se
Sun Jul 20 02:04:08 CEST 2008


Registering to an operator with R=xxxxx in libgsmd-tool -m shell
results in

  R=12345
  # Unknown command `R=12345'

. This has been broken since revision 3657, 2007-12-17.

When fixing it I cleaned up the handling of all commands taking
arguments, which also fixes the segfaults when too few arguments are
given to most commands (try typing e.g. just "pr") and a problem when
a command works even when there is trailing garbage in the command
name (e.g. "prxxxxxxxxx=1").

  Jörgen

Index: target/gsm/src/util/shell.c
===================================================================
--- target/gsm/src/util/shell.c	(revision 4541)
+++ target/gsm/src/util/shell.c	(working copy)
@@ -614,6 +614,7 @@
 	char buf[STDIN_BUF_SIZE+1];
 	fd_set readset;
 	char *ptr, *fcomma, *lcomma;
+	int value;
 	int gsm_fd = lgsm_fd(lgsmh);
 	const struct msghandler_s *hndl;
 
@@ -696,13 +697,14 @@
 			} else if (!strcmp(buf, "r")) {
 				printf("Register\n");
 				lgsm_netreg_register(lgsmh, "\0     ");
-			} else if (!strcmp(buf,"R")) {
+			} else if (!strncmp(buf, "R=", 2) &&
+				   (ptr = strchr(buf, '=')) &&
+				   strlen(ptr+1) >= 5) {
 				printf("Register to operator\n");
-				ptr = strchr(buf, '=');
-				if (!ptr || strlen(ptr) < 6)
-					printf("No.\n");
-				else
-					lgsm_netreg_register(lgsmh, ptr + 1);
+				lgsm_netreg_register(lgsmh, ptr + 1);
+			// Careful here; other commands also start with "R":
+			} else if (!strncmp(buf, "R=", 2)) {
+				printf("Register to operator\nNo.\n");
 			} else if (!strcmp(buf, "U")) {
 				printf("Unregister\n");
 				lgsm_netreg_deregister(lgsmh);
@@ -728,41 +730,45 @@
 				pending_responses ++;
 			} else if (!strcmp(buf, "q")) {
 				exit(0);
-			} else if (buf[0] == 'S' ) {
-				if(!strchr(buf,'=') || atoi((strchr(buf,'=')+1)) < 0) {
-					printf("Sleep 5 secs\n");
-					sleep(5);
-				}else {
-					printf("Sleep %d secs\n",atoi(strchr(buf,'=')+1));
-					sleep(atoi(strchr(buf,'=')+1));
-				}
+			} else if (!strncmp(buf, "S=", 2) &&
+				   (ptr = strchr(buf,'=')) &&
+				   (value = atoi(ptr+1)) >= 0) {
+				printf("Sleep %d secs\n", value);
+				sleep(value);
+			} else if (!strncmp(buf, "S", 1)) {
+				printf("Sleep 5 secs\n");
+				sleep(5);
 			} else if (buf[0] == 'T') {
 				if (strlen(buf) < 2)
 					continue;
 				printf("DTMF: %c\n", buf[1]);
 				lgsm_voice_dtmf(lgsmh, buf[1]);
-			} else if ( !strncmp(buf, "pd", 2)) {
+			} else if (!strncmp(buf, "pd=", 3) &&
+				   (ptr = strchr(buf, '='))) {
 				printf("Delete Phonebook Entry\n");			
-				ptr = strchr(buf, '=');
 				lgsm_pb_del_entry(lgsmh, atoi(ptr+1));
-			} else if ( !strncmp(buf, "prr", 3)) {	
+			} else if (!strncmp(buf, "pd", 2)) {
+				printf("Delete Phonebook Entry\nNo.\n");
+			} else if (!strncmp(buf, "prr=", 3) &&
+				   (ptr = strchr(buf, '=')) &&
+				   (fcomma = strchr(ptr+1, ','))) {
 				printf("Read Phonebook Entries\n");
 				struct lgsm_phonebook_readrg pb_readrg;
-
-				ptr = strchr(buf, '=');
 				pb_readrg.index1 = atoi(ptr+1);				
-				ptr = strchr(buf, ',');
-				pb_readrg.index2 = atoi(ptr+1);
+				pb_readrg.index2 = atoi(fcomma+1);
 				lgsm_pb_read_entries(lgsmh, &pb_readrg);
 				pending_responses ++;
-			} else if ( !strncmp(buf, "pr", 2)) {
-				ptr = strchr(buf, '=');
+			} else if (!strncmp(buf, "prr", 3)) {	
+				printf("Read Phonebook Entries\nNo.\n");
+			} else if (!strncmp(buf, "pr=", 3) &&
+				   (ptr = strchr(buf, '='))) {
 				lgsm_pb_read_entry(lgsmh, atoi(ptr+1));
-			} else if ( !strncmp(buf, "pf", 2)) {
+			} else if (!strncmp(buf, "pr", 2)) {
+				printf("No.\n");
+			} else if (!strncmp(buf, "pf=", 3) &&
+				   (ptr = strchr(buf, '='))) {
 				printf("Find Phonebook Entry\n");
 				struct lgsm_phonebook_find pb_find;
-
-				ptr = strchr(buf, '=');
 				strncpy(pb_find.findtext,
 						ptr + 1,
 						sizeof(pb_find.findtext) - 1);
@@ -770,15 +776,16 @@
 			
 				lgsm_pb_find_entry(lgsmh, &pb_find);
 				pending_responses ++;
-			} else if ( !strncmp(buf, "pw", 2)) {
+			} else if (!strncmp(buf, "pf", 2)) {
+				printf("Find Phonebook Entry\nNo.\n");
+			} else if (!strncmp(buf, "pw=", 3) &&
+				   (ptr = strchr(buf, '=')) &&
+				   (fcomma = strchr(buf+1, ',')) &&
+				   (lcomma = strchr(fcomma+1, ','))) {
 				printf("Write Phonebook Entry\n");
 				struct lgsm_phonebook pb;
-
-				ptr = strchr(buf, '=');
+				
 				pb.index = atoi(ptr+1);
-
-				fcomma = strchr(buf, ',');
-				lcomma = strchr(fcomma+1, ',');
 				strncpy(pb.numb, fcomma + 1, (lcomma - fcomma - 1));
 				pb.numb[(lcomma - fcomma - 1)] = '\0';
 				if ('+' == pb.numb[0])
@@ -789,49 +796,53 @@
 				pb.text[strlen(lcomma + 1)] = '\0';
 
 				lgsm_pb_write_entry(lgsmh, &pb);
+			} else if (!strncmp(buf, "pw", 2)) {
+				printf("Write Phonebook Entry\nNo.\n");
 			} else if ( !strncmp(buf, "pm", 2)) {
 				lgsm_pb_list_storage(lgsmh);
-			} else if ( !strncmp(buf, "pp", 2)) {
+			} else if (!strncmp(buf, "pp=", 3) &&
+				   (ptr = strchr(buf, '='))) {
 				char storage[3];
-
-				ptr = strchr(buf, '=');
 				strncpy(storage, (ptr+1), 2);
-
 				lgsm_pb_set_storage(lgsmh, storage);
+			} else if (!strncmp(buf, "pp", 2)) {
+				printf("No.\n");
 			} else if ( !strncmp(buf, "ps", 2)) {	
 				printf("Get Phonebook Support\n");
 				lgsm_pb_get_support(lgsmh);
 				pending_responses ++;
-			} else if ( !strncmp(buf, "sd", 2)) {		
-				printf("Delete SMS\n");			
+			} else if (!strncmp(buf, "sd=", 3) &&
+				   (ptr = strchr(buf, '=')) &&
+				   (lcomma = strchr(buf+1, ','))) {
+				printf("Delete SMS\n");
 				struct lgsm_sms_delete sms_del;
-
-				ptr = strchr(buf, '=');
 				sms_del.index = atoi(ptr+1);
-				ptr = strchr(buf, ',');
-				sms_del.delflg = atoi(ptr+1);	
-			
+				sms_del.delflg = atoi(lcomma+1);
 				lgsm_sms_delete(lgsmh, &sms_del);
 				pending_responses ++;
-			} else if ( !strncmp(buf, "sl", 2)) {
+			} else if (!strncmp(buf, "sd", 2)) {
+				printf("Delete SMS\nNo.\n");
+			} else if (!strncmp(buf, "sl=", 3) &&
+				   (ptr = strchr(buf, '='))) {
 				printf("List SMS\n");
-				ptr = strchr(buf, '=');
-
 				lgsm_sms_list(lgsmh, atoi(ptr+1));
 				pending_responses ++;
-			} else if ( !strncmp(buf, "sr", 2)) {
+			} else if (!strncmp(buf, "sl", 2)) {
+				printf("List SMS\nNo.\n");
+			} else if (!strncmp(buf, "sr", 2) &&
+				   (ptr = strchr(buf, '='))) {
 				printf("Read SMS\n");
-				ptr = strchr(buf, '=');
-
 				lgsm_sms_read(lgsmh, atoi(ptr+1));
 				pending_responses ++;
-			} else if ( !strncmp(buf, "ss", 2)) {
+			} else if (!strncmp(buf, "sr", 2)) {
+				printf("Read SMS\nNo.\n");
+			} else if (!strncmp(buf, "ss=", 3) &&
+				   (ptr = strchr(buf, '=')) &&
+				   (fcomma = strchr(ptr+1, ',')) &&
+				   (lcomma = strchr(fcomma+1, ','))) {
 				struct lgsm_sms sms;
 
-				ptr = strchr(buf, '=');
 				sms.ask_ds = atoi(ptr+1);
-				fcomma = strchr(buf, ',');
-				lcomma = strchr(fcomma+1, ',');
 				strncpy(sms.addr, fcomma+1, lcomma-fcomma-1);
 				sms.addr[lcomma-fcomma-1] = '\0';
 				/* todo define \" to allow " in text */
@@ -851,14 +862,16 @@
 
 				lgsm_sms_send(lgsmh, &sms);
 				pending_responses ++;
-			} else if ( !strncmp(buf, "sw", 2)) {	
-				printf("Write SMS\n");				
+			} else if (!strncmp(buf, "ss", 2)) {
+				printf("Send SMS\nNo.\n");
+			} else if (!strncmp(buf, "sw=", 3) &&
+				   (ptr = strchr(buf, '=')) &&
+				   (fcomma = strchr(ptr+1, ',')) &&
+				   (lcomma = strchr(fcomma+1, ','))) {	
+				printf("Write SMS\n");
 				struct lgsm_sms_write sms_write;
 
-				ptr = strchr(buf, '=');
 				sms_write.stat = atoi(ptr+1);
-				fcomma = strchr(buf, ',');
-				lcomma = strchr(fcomma+1, ',');
 				strncpy(sms_write.sms.addr,
 						fcomma+1, lcomma-fcomma-1);
 				sms_write.sms.addr[lcomma-fcomma-1] = '\0';
@@ -868,6 +881,8 @@
 
 				lgsm_sms_write(lgsmh, &sms_write);
 				pending_responses ++;
+			} else if (!strncmp(buf, "sw", 2)) {
+				printf("Write SMS\nNo.\n");
 			} else if (!strncmp(buf, "sm", 2)) {
 				printf("Get SMS storage preferences\n");
 				lgsm_sms_get_storage(lgsmh);
@@ -886,13 +901,13 @@
 				printf("Get the default SMSC\n");
 				lgsm_sms_get_smsc(lgsmh);
 				pending_responses ++;
+			} else if (!strncmp(buf, "sC=", 3) &&
+				   (ptr = strchr(buf, '=')) &&
+				   strlen(ptr+1) >= 5) {
+				printf("Set the default SMSC\n");
+				lgsm_sms_set_smsc(lgsmh, ptr + 1);
 			} else if (!strncmp(buf, "sC", 2)) {
-				printf("Set the default SMSC\n");
-				ptr = strchr(buf, '=');
-				if (!ptr || strlen(ptr) < 6)
-					printf("No.\n");
-				else
-					lgsm_sms_set_smsc(lgsmh, ptr + 1);
+				printf("Set the default SMSC\nNo.\n");
 			} else if (!strcmp(buf, "n")) {
 				lgsm_get_subscriber_num(lgsmh);
 				pending_responses ++;
@@ -900,14 +915,14 @@
 				printf("Get Voicemail Number\n");
 				lgsm_voicemail_get(lgsmh);
 				pending_responses ++;
-			} else if ( !strncmp(buf, "svm", 3)) {
+			} else if (!strncmp(buf, "svm=", 4) &&
+				   (ptr = strchr(buf, '=')) &&
+				   strlen(ptr+1) >= 2) {
 				printf("Set Voicemail Number\n");
-				ptr = strchr(buf, '=');
-				if (!ptr || strlen(ptr) < 3)
-					printf("No.\n");
-				else
-					lgsm_voicemail_set(lgsmh, ptr + 1);
+				lgsm_voicemail_set(lgsmh, ptr + 1);
 				pending_responses ++;
+			} else if (!strncmp(buf, "svm", 3)) {
+				printf("Set Voicemail Number\nNo.\n");
 			} else if (!strncmp(buf, "im", 2)) {
 				printf("Get imsi\n");
 				lgsm_get_imsi(lgsmh);
@@ -962,14 +977,16 @@
 				printf("Release all active calls\n");
 				lgsm_voice_ctrl(lgsmh, &ctrl);
 				pending_responses ++;
-			} else if ( !strncmp(buf, "Rx", 2)) {
+			} else if (!strncmp(buf, "Rx=", 3) &&
+				   (ptr = strchr(buf, '='))) {
 				struct lgsm_voicecall_ctrl ctrl;	
 				ctrl.proc = LGSM_VOICECALL_CTRL_R_ACT_X; 
 				printf("Release specific active call x\n");
-				ptr = strchr(buf, '=');
 				ctrl.idx = atoi(ptr+1);
 				lgsm_voice_ctrl(lgsmh, &ctrl);
 				pending_responses ++;
+			} else if (!strncmp(buf, "Rx", 2)) {
+				printf("Release specific active call x\nNo.\n");
 			} else if ( !strncmp(buf, "Ha", 2)) {
 				struct lgsm_voicecall_ctrl ctrl;	
 				ctrl.proc = LGSM_VOICECALL_CTRL_H_ACTS_A_HLD_WAIT; 
@@ -977,49 +994,61 @@
 				        " call\n");
 				lgsm_voice_ctrl(lgsmh, &ctrl);
 				pending_responses ++;
-			} else if ( !strncmp(buf, "Hx", 2)) {
+			} else if (!strncmp(buf, "Hx=", 3) &&
+				   (ptr = strchr(buf, '='))) {
 				struct lgsm_voicecall_ctrl ctrl;	
 				ctrl.proc = LGSM_VOICECALL_CTRL_H_ACTS_EXCEPT_X; 
 				printf("Hold all active calls except call x\n");
-				ptr = strchr(buf, '=');
 				ctrl.idx = atoi(ptr+1);
 				lgsm_voice_ctrl(lgsmh, &ctrl);
 				pending_responses ++;
+			} else if (!strncmp(buf, "Hx", 2)) {
+				printf("Hold all active calls except call x\nNo.\n");
 			} else if ( !strncmp(buf, "MP", 2)) {
 				struct lgsm_voicecall_ctrl ctrl;
 				ctrl.proc = LGSM_VOICECALL_CTRL_M_HELD; 
 				printf("Add a held call to the conversation\n");
 				lgsm_voice_ctrl(lgsmh, &ctrl);
 				pending_responses ++;
-			} else if ( !strncmp(buf, "CFD", 3)) {
+			} else if (!strncmp(buf, "CFD=", 4) &&
+				   (ptr = strchr(buf, '='))) {
 				printf("Disable call forwarding\n");
-				ptr = strchr(buf, '=');
 				lgsm_voice_fwd_disable(lgsmh, atoi(ptr+1));
 				pending_responses ++;
-			}else if ( !strncmp(buf, "CFE", 3)) {
+			} else if (!strncmp(buf, "CFD", 3)) {
+				printf("Disable call forwarding\nNo.\n");
+			} else if (!strncmp(buf, "CFE=", 4) &&
+				   (ptr = strchr(buf, '='))) {
 				printf("Enable call forwarding\n");
-				ptr = strchr(buf, '=');
 				lgsm_voice_fwd_enable(lgsmh, atoi(ptr+1));
 				pending_responses ++;
-			}else if ( !strncmp(buf, "CFQ", 3)) {
+			} else if (!strncmp(buf, "CFE", 3)) {
+				printf("Enable call forwarding\nNo.\n");
+			}else if (!strncmp(buf, "CFQ=", 4) &&
+				  (ptr = strchr(buf, '='))) {
 				printf("Query the status of call forwarding\n");
-				ptr = strchr(buf, '=');
 				lgsm_voice_fwd_stat(lgsmh, atoi(ptr+1));
 				pending_responses ++;
-			}else if ( !strncmp(buf, "CFR", 3)) {
+			} else if (!strncmp(buf, "CFQ", 3)) {
+				printf("Query the status of call forwarding\nNo.\n");
+			} else if (!strncmp(buf, "CFR=", 4) &&
+				   (ptr = strchr(buf, '=')) &&
+				   (lcomma = strchr(ptr+1, ','))) {
 				struct lgsm_voicecall_fwd_reg lvfr;
 				printf("Register call forwarding\n");
-				ptr = strchr(buf, '=');
 				lvfr.reason = atoi(ptr+1);
-				ptr = strchr(buf, ',');
 				strcpy(lvfr.number.addr, ptr+1);
 				lgsm_voice_fwd_reg(lgsmh, &lvfr);
 				pending_responses ++;
-			}else if ( !strncmp(buf, "CFe", 3)) {
+			} else if (!strncmp(buf, "CFR", 3)) {
+				printf("Register call forwarding\nNo.\n");
+			} else if (!strncmp(buf, "CFe=", 4) &&
+				   (ptr = strchr(buf, '='))) {
 				printf("Erase a record of call forwarding\n");
-				ptr = strchr(buf, '=');
 				lgsm_voice_fwd_erase(lgsmh, atoi(ptr+1));
 				pending_responses ++;
+			} else if (!strncmp(buf, "CFe", 3)) {
+				printf("Erase a record of call forwarding\nNo.\n");
 			}else if ( !strncmp(buf, "cbc", 3)) {
 				printf("Battery Connection status and Battery Charge Level\n");
 				lgsm_get_battery(lgsmh);




More information about the devel mailing list