Subject: [PATCH] [BZ 121788] qethqoat and qetharp: return codes fixed
From: Rene Trumpp <trumpp@de.ibm.com>

Description:  qethqoat and qetharp: return codes fixed
Symptom:      The qethqoat and qetharp tools did not return proper return
              codes.
Problem:      The qethqoat and qetharp tools did not return proper return
              codes, they return errnos.
Solution:     Return codes are now 0 (command ran successfully) and
              1 (an error occurred).
Reproduction: Enter an invalid parameter, return code should now be 1.
Upstream-ID:  -
Problem-ID:   121788

Signed-off-by: Rene Trumpp <trumpp@de.ibm.com>
---
 README              |    3 ++
 qetharp/qetharp.8   |   11 +++++++++
 qetharp/qetharp.c   |   60 ++++++++++++++++++++++++++--------------------------
 qethqoat/qethqoat.8 |   11 +++++++++
 qethqoat/qethqoat.c |   17 +++++++-------
 5 files changed, 64 insertions(+), 38 deletions(-)

--- a/README
+++ b/README
@@ -239,6 +239,9 @@ Release History:
     - dbginfo.sh: Cleanup messages of the script
     - dbginfo.sh: Reduced log output for sysfs collection
     - dbginfo.sh: Adding data collection from journalctl
+    - qethqoat: Fix return codes and add new error message for too long
+          interface names
+    - qetharp: Fix return codes
 
     Bug Fixes:
     - lsdasd: Fix device selection for a given busid
--- a/qetharp/qetharp.8
+++ b/qetharp/qetharp.8
@@ -70,6 +70,17 @@ shows version information.
 \fB-h\fR or \fB--help\fR
 shows usage information for qetharp.
 
+.SH RETURN CODES
+qetharp writes the response to stdout and any error message to stderr.
+The command completes with one of the following return codes:
+.TP
+.BR "0"
+The qetharp command ran successfully.
+
+.TP
+.BR "1"
+An error occurred.
+
 .SH EXAMPLE
 .TP
 \fBqetharp -q eth0\fR  
--- a/qetharp/qetharp.c
+++ b/qetharp/qetharp.c
@@ -96,7 +96,7 @@ static int ip_to_str(char *tmpbuff, __u8
 			ip[10],ip[11],ip[12],ip[13],ip[14],
 			ip[15]);
 	} else {
-		rc = -1;
+		rc = 1;
 		goto out;
 	}
 	rc = 0;
@@ -112,13 +112,13 @@ static int lookup_hostname(const char *
 	int rc;
 
 	if (getaddrinfo(addr, NULL, NULL, &addrinfo)) {
-		rc = -1;
+		rc = 1;
 	} else {
 		if (getnameinfo(addrinfo->ai_addr,
 				addrinfo->ai_addrlen,
 				hostname,
 				buflen, NULL, 0, 0)) {
-			rc = -1;
+			rc = 1;
 		} else {
 			rc = 0;
 		}
@@ -269,18 +269,18 @@ qetharp_purge(struct option_info *opin)
 
 	if (!opin->dev_name) {
 		printf("\nError: no interface specified!\n");
-		return -1;
+		return 1;
 	}
 		
 	if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 		perror("Socket failed: %m\n");
-		return -1;
+		return 1;
 	}
 	strcpy(ifr.ifr_name, opin->dev_name);
 	if (ioctl(sd, SIOC_QETH_ARP_FLUSH_CACHE, &ifr) < 0) {
 		close(sd);
 		perror("\nUnsuccessful");
-		return -1;
+		return 1;
 	}
 
 	return 0;
@@ -297,16 +297,16 @@ qetharp_add(struct option_info *opin)
 	memset(&arp_entry, 0, sizeof(struct qeth_arp_cache_entry));
 	if (!opin->dev_name) {
 		printf("\nError: no interface specified!\n");
-		return -1;
+		return 1;
 	}
 	if (!opin->ip_addr) {
 		printf("\nError: no ip address specified!\n");
-		return -1;
+		return 1;
 	}
 	r=sscanf(opin->ip_addr,"%u.%u.%u.%u",&i1,&i2,&i3,&i4);
 	if ( (r!=4) || (i1>255) || (i2>255) || (i3>255) || (i4>255) ) {
 		printf("\nError: invalid ip address specified!\n");
-		return -1;
+		return 1;
 	}
 	arp_entry.ipaddr[0]=i1;
 	arp_entry.ipaddr[1]=i2;
@@ -315,13 +315,13 @@ qetharp_add(struct option_info *opin)
 	
 	if (!opin->mac_addr) {
 		printf("\nError: no MAC address specified!\n");
-		return -1;
+		return 1;
 	}
 	r=sscanf(opin->mac_addr,"%x:%x:%x:%x:%x:%x",&i1,&i2,&i3,&i4,&i5,&i6);
 	if ( (r!=6) || (i1>255) || (i2>255) || (i3>255) || 
 	     (i4>255) || (i5>255) || (i6>255) ) {
 		printf("\nError: invalid MAC address specified!\n");
-		return -1;
+		return 1;
 	}
 	arp_entry.macaddr[0]=i1;
 	arp_entry.macaddr[1]=i2;
@@ -332,7 +332,7 @@ qetharp_add(struct option_info *opin)
 
 	if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 		perror("Socket failed: %m\n");
-		return -1;
+		return 1;
 	}
 	strcpy(ifr.ifr_name, opin->dev_name);
 	ifr.ifr_ifru.ifru_data = (void*)&arp_entry;
@@ -340,7 +340,7 @@ qetharp_add(struct option_info *opin)
 	if (ioctl(sd, SIOC_QETH_ARP_ADD_ENTRY, &ifr) < 0) {
 		close(sd);
 		perror("\nUnsuccessful");
-		return -1;
+		return 1;
 	}
 
 	return 0;
@@ -357,16 +357,16 @@ qetharp_delete(struct option_info *opin)
 	memset(&arp_entry,0,sizeof(struct qeth_arp_cache_entry));
 	if (!opin->dev_name) {
 		printf("\nError: no interface specified!\n");
-		return -1;
+		return 1;
 	}
 	if (!opin->ip_addr) {
 		printf("\nError: no ip address specified!\n");
-		return -1;
+		return 1;
 	}
 	r=sscanf(opin->ip_addr,"%u.%u.%u.%u",&i1,&i2,&i3,&i4);
 	if ( (r!=4) || (i1>255) || (i2>255) || (i3>255) || (i4>255) ) {
 		printf("\nError: invalid ip address specified!\n");
-		return -1;
+		return 1;
 	}
 	arp_entry.ipaddr[0]=i1;
 	arp_entry.ipaddr[1]=i2;
@@ -375,7 +375,7 @@ qetharp_delete(struct option_info *opin)
 	
 	if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 		perror("Socket failed: %m\n");
-		return -1;
+		return 1;
 	}
 	strcpy(ifr.ifr_name, opin->dev_name);
 	ifr.ifr_ifru.ifru_data = (void*)&arp_entry;
@@ -383,7 +383,7 @@ qetharp_delete(struct option_info *opin)
 	if (ioctl(sd, SIOC_QETH_ARP_REMOVE_ENTRY, &ifr) < 0) {
 		close(sd);
 		perror("\nUnsuccessful");
-		return -1;
+		return 1;
 	}
 
 	return 0;
@@ -400,12 +400,12 @@ qetharp_query(struct option_info *opin)
 
 	if (!opin->dev_name) {
 		printf("\nError: no interface specified!\n");
-		return -1;
+		return 1;
 	}
 		
 	if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
 		perror("Socket failed: %m\n");
-		return -1;
+		return 1;
 	}
 	strcpy(ifr.ifr_name, opin->dev_name);
 	memsize = QETH_QARP_USER_DATA_SIZE;
@@ -419,7 +419,7 @@ qetharp_query(struct option_info *opin)
 	if (ioctl(sd, SIOC_QETH_ARP_QUERY_INFO, &ifr) < 0) {
 		close(sd);
 		perror("\nUnsuccessful");
-		return -1;
+		return 1;
 	}
 	if (opin->compact_output!=OPTION_INFO_COMPACT_OUTPUT) {
 		show_header();
@@ -437,7 +437,7 @@ qetharp_query(struct option_info *opin)
 		result = get_arp_from_osacard(udata, mask_bits, opin);
 	else {
 		perror("\nReceived entries with invalid format");
-		return -1;
+		return 1;
 	}
 	free(udata);
 
@@ -472,25 +472,25 @@ qetharp_parse_info(struct option_info *o
 {
 	if (opin->dev_name && (strlen(opin->dev_name) >= IFNAMSIZ)) {
 		printf("\nError: interface name too long\n");
-		return -1;
+		return 1;
 	}
 	if ((opin->purge_flag+opin->query_flag+
 	    opin->add_flag+opin->delete_flag)==0) {
 		qetharp_usage();
-		return -1;	
+		return 1;
 	}
 	if ((opin->purge_flag+opin->query_flag+
 	    opin->add_flag+opin->delete_flag)!=1) {
 		printf("\nUse only one of the options '-a', " \
 		       "'-d', '-p' and 'q' per call.\n");
-		return -1;	
+		return 1;
 	}
 	if (opin->purge_flag &&
 	    (opin->query_flag || opin->host_resolution)) {
 		printf("\nError in using '-p' option:\n" \
 			"\tYou can not use '-p' option in conjunction with " \
 			"'-q' or '-n'.\n");
-		return -1;
+		return 1;
 	}
 	if (opin->purge_flag) {
 		return qetharp_purge(opin);
@@ -499,13 +499,13 @@ qetharp_parse_info(struct option_info *o
 	    !(opin->query_flag)) {
 		printf("\nError in using '-n' option:\n" \
 		       "\t'-q' option missing!\n");
-		return -1;
+		return 1;
 	}
 	if ((opin->ipv6) &&
 	    !(opin->query_flag)) {
 		printf("\nError in using '-6' option:\n" \
 		       "\t'-q' option missing!\n");
-		return -1;
+		return 1;
 	}
 	if (opin->query_flag) {
 		return qetharp_query(opin);
@@ -514,7 +514,7 @@ qetharp_parse_info(struct option_info *o
 		if ((!opin->ip_flag)||(!opin->mac_flag)) {
 			printf("\nError in using '-a' option:\n" \
 			       "\t'-i' or '-m' option missing!\n");
-			return -1;
+			return 1;
 		}
 		return qetharp_add(opin);
 	}
@@ -522,7 +522,7 @@ qetharp_parse_info(struct option_info *o
 		if (!opin->ip_flag) {
 			printf("\nError in using '-d' option:\n" \
 			       "\t'-i' option missing!\n");
-			return -1;
+			return 1;
 		}
 		return qetharp_delete(opin);
 	}
--- a/qethqoat/qethqoat.8
+++ b/qethqoat/qethqoat.8
@@ -40,6 +40,17 @@ Defines the scope of the query. Followin
 
 \fB1\fP  Interface (default)
 
+.SH RETURN CODES
+qethqoat writes the response to stdout and any error message to stderr.
+The command completes with one of the following return codes:
+.TP
+.BR "0"
+The qethqoat command ran successfully.
+
+.TP
+.BR "1"
+An error occurred.
+
 .SH EXAMPLE
 .TP
 To display physical and logical device information for interface eth0 issue:
--- a/qethqoat/qethqoat.c
+++ b/qethqoat/qethqoat.c
@@ -556,15 +556,17 @@ int main(int argc, char **argv)
 		return 1;
 	} else {
 		opts.ifname = argv[optind];
-		if (strlen(opts.ifname) >= IFNAMSIZ)
-			return -EINVAL;
+		if (strlen(opts.ifname) >= IFNAMSIZ) {
+			fprintf(stderr, "qethqoat: Interface name too long\n");
+			return 1;
+		}
 	}
 
 	oat_data.command = 0;
 	oat_data.ptr = (__u64)(unsigned long)malloc(datalen);
 	if (!oat_data.ptr) {
 		perror("qethqoat");
-		return errno;
+		return 1;
 	}
 	oat_data.buffer_len = datalen;
 	oat_data.response_len = 0;
@@ -574,7 +576,7 @@ int main(int argc, char **argv)
 		if (!rf) {
 			perror("qethqoat");
 			free((void *)(unsigned long)oat_data.ptr);
-			return errno;
+			return 1;
 		}
 		oat_data.response_len = fread(
 			(char *)(unsigned long)oat_data.ptr,
@@ -586,7 +588,7 @@ int main(int argc, char **argv)
 	if (sd < 0) {
 		perror("qethqoat");
 		free((void *)(unsigned long)oat_data.ptr);
-		return errno;
+		return 1;
 	}
 
 	strncpy(ifr.ifr_name, opts.ifname, IFNAMSIZ);
@@ -597,10 +599,9 @@ int main(int argc, char **argv)
 	if (rc) {
 		if (print_IPA_error(rc))
 			perror("qethqoat");
-		rc = errno;
 		close(sd);
 		free((void *)(unsigned long)oat_data.ptr);
-		return rc;
+		return 1;
 	}
 	close(sd);
 parse:
@@ -612,7 +613,7 @@ parse:
 		if (l_iconv_ebcdic_ascii == (iconv_t) -1) {
 			perror("qethqoat");
 			free((void *)(unsigned long)oat_data.ptr);
-			return errno;
+			return 1;
 		}
 		parse_data((char *)(unsigned long)oat_data.ptr,
 			oat_data.response_len);
