From nobody@FreeBSD.org  Sun Jan 24 06:02:27 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 6521D106566C
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 24 Jan 2010 06:02:27 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 532A68FC18
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 24 Jan 2010 06:02:27 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o0O62RJU007725
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 24 Jan 2010 06:02:27 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o0O62REn007724;
	Sun, 24 Jan 2010 06:02:27 GMT
	(envelope-from nobody)
Message-Id: <201001240602.o0O62REn007724@www.freebsd.org>
Date: Sun, 24 Jan 2010 06:02:27 GMT
From: Garrett Cooper <yaneurabeya@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [PATCH] Fix non-POSIX compliant multiline conditional in portsnap(1)
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         143142
>Category:       bin
>Synopsis:       [PATCH] Fix non-POSIX compliant multiline conditional in portsnap(1)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    eadler
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jan 24 06:10:00 UTC 2010
>Closed-Date:    Sat Oct 20 23:37:32 UTC 2012
>Last-Modified:  Sun Feb 03 22:27:58 UTC 2013
>Originator:     Garrett Cooper
>Release:        9-CURRENT
>Organization:
Ironport
>Environment:
[gcooper@optimus /usr/ports]$ uname -a
FreeBSD optimus.zenmetsuhitotuyaneshita.net 9.0-CURRENT FreeBSD 9.0-CURRENT #0: Thu Jan  7 17:03:57 PST 2010     root@optimus.zenmetsuhitotuyaneshita.net:/usr/obj/usr/src/sys/OPTIMUS  amd64
>Description:
Over a year ago, I submitted an email to determine why bash didn't function with portsnap because I tried updating my ports via my Mac, because at the time I didn't have a network connection in my apartment. bash is the system shell on Mac, and thus it failed to execute, like so:

[gcooper@optimus /usr/ports]$ bash `which portsnap`
/usr/sbin/portsnap: line 882: syntax error near unexpected token `newline'
/usr/sbin/portsnap: line 882: ` if !'

According to the bash folks (<http://www.mail-archive.com/bug-bash@gnu.org/msg04116.html>), multiline // inline conditionals aren't POSIX compliant. Thus, there are two issues with how portsnap is coded today. The attached patch takes care of those issues, and also swaps out `basename $0` for ${0##*/} (equivalent logic in Bourne shell).

This has been tested on sh in -CURRENT and bash 4.x, and there isn't a regression with the affected logic paths when doing:

portsnap fetch extract

Additional blocks may or may not need to be tested.
>How-To-Repeat:
bash `which portsnap`
>Fix:
See attached patch.

Patch attached with submission follows:

Index: portsnap.sh
===================================================================
--- portsnap.sh	(revision 202909)
+++ portsnap.sh	(working copy)
@@ -34,7 +34,7 @@
 # --no-stats	-- don't show progress statistics while fetching files
 usage() {
 	cat <<EOF
-usage: `basename $0` [options] command ... [path]
+usage: ${0##*/} [options] command ... [path]
 
 Options:
   -d workdir   -- Store working files in workdir
@@ -240,23 +240,23 @@
 	_WORKDIR_bad="Directory does not exist or is not writable: "
 
 	if [ -z "${SERVERNAME}" ]; then
-		echo -n "`basename $0`: "
+		echo -n "${0##*/}: "
 		echo "${_SERVERNAME_z}"
 		exit 1
 	fi
 	if [ -z "${KEYPRINT}" ]; then
-		echo -n "`basename $0`: "
+		echo -n "${0##*/}: "
 		echo "${_KEYPRINT_z}"
 		exit 1
 	fi
 	if ! echo "${KEYPRINT}" | grep -qE "^[0-9a-f]{64}$"; then
-		echo -n "`basename $0`: "
+		echo -n "${0##*/}: "
 		echo -n "${_KEYPRINT_bad}"
 		echo ${KEYPRINT}
 		exit 1
 	fi
 	if ! [ -d "${WORKDIR}" -a -w "${WORKDIR}" ]; then
-		echo -n "`basename $0`: "
+		echo -n "${0##*/}: "
 		echo -n "${_WORKDIR_bad}"
 		echo ${WORKDIR}
 		exit 1
@@ -277,13 +277,13 @@
 	_PORTSDIR_bad="Directory is not writable: "
 
 	if ! [ -d "${WORKDIR}" ]; then
-		echo -n "`basename $0`: "
+		echo -n "${0##*/}: "
 		echo -n "${_WORKDIR_bad}"
 		echo ${WORKDIR}
 		exit 1
 	fi
 	if [ -d "${PORTSDIR}" ] && ! [ -w "${PORTSDIR}" ]; then
-		echo -n "`basename $0`: "
+		echo -n "${0##*/}: "
 		echo -n "${_PORTSDIR_bad}"
 		echo ${PORTSDIR}
 		exit 1
@@ -292,7 +292,7 @@
 	if ! [ -d "${WORKDIR}/files" -a -r "${WORKDIR}/tag"	\
 	    -a -r "${WORKDIR}/INDEX" -a -r "${WORKDIR}/tINDEX" ]; then
 		echo "No snapshot available.  Try running"
-		echo "# `basename $0` fetch"
+		echo "# ${0##*/} fetch"
 		exit 1
 	fi
 
@@ -306,8 +306,8 @@
 
 	if ! [ -r ${PORTSDIR}/.portsnap.INDEX ]; then
 		echo "${PORTSDIR} was not created by portsnap."
-		echo -n "You must run '`basename $0` extract' before "
-		echo "running '`basename $0` update'."
+		echo -n "You must run '${0##*/} extract' before "
+		echo "running '${0##*/} update'."
 		exit 1
 	fi
 
@@ -584,7 +584,7 @@
 fetch_progress() {
 	LNC=0
 	while read x; do
-		LNC=$(($LNC + 1))
+		: $(( LNC += 1 ))
 		if [ $(($LNC % 10)) = 0 ]; then
 			echo -n $LNC
 		elif [ $(($LNC % 2)) = 0 ]; then
@@ -879,35 +879,30 @@
 extract_run() {
 	mkdir -p ${PORTSDIR} || return 1
 
-	if !
-		if ! [ -z "${EXTRACTPATH}" ]; then
-			grep "^${EXTRACTPATH}" ${WORKDIR}/INDEX
-		elif ! [ -z "${REFUSE}" ]; then
-			grep -vE "${REFUSE}" ${WORKDIR}/INDEX
-		else
-			cat ${WORKDIR}/INDEX
-		fi | tr '|' ' ' | while read FILE HASH; do
-		echo ${PORTSDIR}/${FILE}
-		if ! [ -r "${WORKDIR}/files/${HASH}.gz" ]; then
-			echo "files/${HASH}.gz not found -- snapshot corrupt."
-			return 1
-		fi
-		case ${FILE} in
-		*/)
-			rm -rf ${PORTSDIR}/${FILE%/}
-			mkdir -p ${PORTSDIR}/${FILE}
-			tar -xzf ${WORKDIR}/files/${HASH}.gz	\
-			    -C ${PORTSDIR}/${FILE}
-			;;
-		*)
-			rm -f ${PORTSDIR}/${FILE}
-			tar -xzf ${WORKDIR}/files/${HASH}.gz	\
-			    -C ${PORTSDIR} ${FILE}
-			;;
-		esac
-	done; then
+	(if ! [ -z "${EXTRACTPATH}" ]; then
+		grep "^${EXTRACTPATH}" ${WORKDIR}/INDEX
+	elif ! [ -z "${REFUSE}" ]; then
+		grep -vE "${REFUSE}" ${WORKDIR}/INDEX
+	else
+		cat ${WORKDIR}/INDEX
+	fi) | tr '|' ' ' | while read FILE HASH; do
+	echo ${PORTSDIR}/${FILE}
+	if ! [ -r "${WORKDIR}/files/${HASH}.gz" ]; then
+		echo "files/${HASH}.gz not found -- snapshot corrupt."
 		return 1
 	fi
+	case ${FILE} in
+	*/)
+		rm -rf ${PORTSDIR}/${FILE%/}
+		mkdir -p ${PORTSDIR}/${FILE}
+		tar -xzf ${WORKDIR}/files/${HASH}.gz -C ${PORTSDIR}/${FILE}
+		;;
+	*)
+		rm -f ${PORTSDIR}/${FILE}
+		tar -xzf ${WORKDIR}/files/${HASH}.gz -C ${PORTSDIR} ${FILE}
+		;;
+	esac; done
+	[ $? -ne 0 ] && return 1
 	if [ ! -z "${EXTRACTPATH}" ]; then
 		return 0;
 	fi
@@ -948,14 +943,11 @@
 
 # Install new files
 	echo "Extracting new files:"
-	if !
-		if ! [ -z "${REFUSE}" ]; then
-			grep -vE "${REFUSE}" ${WORKDIR}/INDEX | sort
-		else
-			sort ${WORKDIR}/INDEX
-		fi |
-	    comm -13 ${PORTSDIR}/.portsnap.INDEX - |
-	    while read LINE; do
+	(if ! [ -z "${REFUSE}" ]; then
+		grep -vE "${REFUSE}" ${WORKDIR}/INDEX | sort
+	else
+		sort ${WORKDIR}/INDEX
+	fi) | comm -13 ${PORTSDIR}/.portsnap.INDEX - | while read LINE; do
 		FILE=`echo ${LINE} | cut -f 1 -d '|'`
 		HASH=`echo ${LINE} | cut -f 2 -d '|'`
 		echo ${PORTSDIR}/${FILE}
@@ -974,9 +966,8 @@
 			    -C ${PORTSDIR} ${FILE}
 			;;
 		esac
-	done; then
-		return 1
-	fi
+	done
+	[ $? -ne 0 ] && return 1
 
 	extract_metadata
 	extract_indices
@@ -999,9 +990,9 @@
 # interactively, then run fetch_check_params and fetch_run
 cmd_fetch() {
 	if [ ! -t 0 ]; then
-		echo -n "`basename $0` fetch should not "
+		echo -n "${0##*/} fetch should not "
 		echo "be run non-interactively."
-		echo "Run `basename $0` cron instead."
+		echo "Run ${0##*/} cron instead."
 		exit 1
 	fi
 	fetch_check_params


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->cperciva 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun Jan 24 07:48:02 UTC 2010 
Responsible-Changed-Why:  
Over to maintainer. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=143142 
Responsible-Changed-From-To: cperciva->eadler 
Responsible-Changed-By: eadler 
Responsible-Changed-When: Mon Oct 15 12:42:45 UTC 2012 
Responsible-Changed-Why:  
I'll take it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=143142 
State-Changed-From-To: open->analyzed 
State-Changed-By: eadler 
State-Changed-When: Sat Oct 20 23:06:42 UTC 2012 
State-Changed-Why:  
awaiting approval or review prior to commit (no action needed from 
submitter) 

http://www.freebsd.org/cgi/query-pr.cgi?pr=143142 
State-Changed-From-To: analyzed->closed 
State-Changed-By: eadler 
State-Changed-When: Sat Oct 20 23:37:32 UTC 2012 
State-Changed-Why:  
Per submitter request 

http://www.freebsd.org/cgi/query-pr.cgi?pr=143142 

From: Garrett Cooper <yaneurabeya@gmail.com>
To: bug-followup@FreeBSD.org, gcooper@FreeBSD.org
Cc:  
Subject: Re: bin/143142: [PATCH] Fix non-POSIX compliant multiline conditional
 in portsnap(1)
Date: Sat, 20 Oct 2012 16:33:40 -0700

     This patch isn't relevant anymore. I'm running into different
 issues trying to run portsnap with bash today, but the attached patch
 doesn't fix them.
     Please close this PR.
 Thanks,
 -Garrett
>Unformatted:
