Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

A workaround for dial-up disconnects and fax receive Internet
Like others, I've experienced the lockup of dial-up internet connections when fax receive is active. I recently tried Page Sender in hopes it would fix the problem, but it has the same problem as does enabling "Receive faxes on this computer" in the Print & Fax System Pref.

I've found a correlation but not the cause: If you attempt a dial-up connection within roughly 20 seconds of waking from sleep, the connection will fail. The system recovers from this failure gracefully. However if efax is running, pppd will hang. Attempts to kill the pppd panic crash the computer (Mac OS 10.3.5 and probably earlier version of 10), so my only recourse is to restart. The manual workaround is simply to wait 20 seconds before connecting, but with others using the computer, this hasn't worked well. I tried several ways to solve this problem with AppleScript, but my final solution is user friendly and totally automatic.

A shell script uses scselect to disable dial-out during the critical period, then re-enable it when the danger of hanging pppd is over. It uses a special network location setup with the modem disabled. This mechanism is very fast, but assumes one normal location. Others may be able to design a way to restore one of several possible working locations.

Since there's only a problem if efax is running, the script first checks to see if it is. It then uses scselect to switch the network location to one that does not have the modem enabled. It then sleeps for 20 seconds, then selects the normal network location, re-enabling dial-up connections.SleepWatcher runs the script when the computer exits sleep (wakes up). My script usesCocoaDialog to present a message and progress bar, so the sleep time is broken into one second increments.

Here's the script; it's called WakeupPPPchecks in my case. Don't forget to give this script execute permission: [sudo]chmod +x WakeupPPPchecks [/sudo] CocoaDialog provides a great progress bar and worked better than AppleScript for status reports in the face of changing user environments, but is certainly eye candy. Thanks to the many posts on Mac OS X Hints which led to this workaround.
    •    
  • Currently 1.00 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (1 vote cast)
 
[11,078 views]  

A workaround for dial-up disconnects and fax receive | 5 comments | Create New Account
Click here to return to the 'A workaround for dial-up disconnects and fax receive' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Some more info on the pppd hang
Authored by: hamarkus on Sep 01, '04 06:23:03PM

Interesting, while I was still using a modem (now on cable), my connection would drop on average every 30 minutes, sometimes getting stuck in disconnecting mode (in the menu bar) during that. Also sending faxes (via FaxCenter, i.e. using efax) to unreliable destinations could cause hangs of the modem with the process efax getting stuck.

The 20 second delay you mentioned is similar to the delay I observed after waking up from sleep (the computer not me) during which trying to start a dial-up connection via the menu bar would simply be ignored.

I figured out that if I killed the modemd, AppleModem and pppd processes in that order I could almost always recover everything and reconnect to the internet without having to restart the OS (pppd sometimes needed several kill -9 attempts).

But the one time I used kill -9 on pppd without first killing modemd and AppleModem I got a kernel panic. I guess if you kill a process which other processes rely on (modemD and AppleModem relying on pppd) you can seriously screw up your system.



[ Reply to This | # ]
A workaround for dial-up disconnects and fax receive
Authored by: rodl2 on Sep 05, '04 12:05:11PM

I tried to view the script, but I get a 404 error

---
"He who limps still walks." -Stanislaw Lec

"If it moves and it shouldn't, use duct tape. If it doesn't move and it should, use WD-40." --CC



[ Reply to This | # ]
A workaround for dial-up disconnects and fax receive
Authored by: kwindrem on Sep 07, '04 01:14:21PM
Here's another attempt at posting the script contents.


# check for fax/ppp conflicts and notify user

# pppd will fail/hang if a dial-up attempt is made within 20 seconds of waking with efax running
# this script checks for that condition,
# disables dial-ups during the critical period
# and provides status for the user

# Sleepwatcher's rc.wakup calls this script
# Add this line to /etc/rc.wakup
# this script sleeps for 20 seconds!
# run in background to avoid delaying the caller

# /Applications/Utilities/WakeupPPPchecks&

# check to see if a delay is needed
if [ `ps -auxww | grep -v grep | grep -c efax` != 0 ]; then

# disable dialup connections -- edit to select proper location!
	scselect "modem disabled"

# display progress bar dialog
# thanks to Kevin Hendricks for this code
# create a named pipe
rm -f /tmp/hpipe
mkfifo /tmp/hpipe

# create a background job which takes its input from the named pipe
/Applications/Utilities/CocoaDialog.app/Contents/MacOS/CocoaDialog progressbar --percent 0 --title "Dial-up Delay" --text "Please wait. Dial out to the internet is disabled while system stabilizes." < /tmp/hpipe &

# associate file descriptor 3 with that pipe and send a character through the pipe
exec 3<> /tmp/hpipe

# delay 20 seconds 1 sec at a time and update progress bar
for ((delay=0; $delay<=100; delay=$delay+5)); do
{
	echo -n $delay >&3
	sleep 1
}
done;

# now turn off the progress bar by closing file descriptor 3
exec 3>&-

# wait for all background jobs to exit
wait
rm -f /tmp/hpipe

# reenable dial out -- edit to select proper location!
	scselect "Normal"
fi


[ Reply to This | # ]
A workaround for dial-up disconnects and fax receive
Authored by: mudhiker on Sep 08, '04 10:45:44PM

I think this bug (which has been bothering me lately) showed up with 10.3.5. The new security update does something to PPPD and I don't seem to have the mysterious ppp hanging problem anymore. I think it's fixed. I troubleshat it for several days, noticed the 20 second delay, then this hint appeared and my own observations were confirmed. No joy with the apple support site though. I never can find much useful on that.



[ Reply to This | # ]
A new workaround for dial-up disconnects and fax receive
Authored by: kwindrem on Dec 27, '04 08:58:06PM
My original scipt helped, but there were still holes. I've tried a couple of different versions of the original idea, but the problem still occurs occationally. Here's a totally different approach:

To prevent pppd from hanging, it's execution is delayed after boot, wake from sleep or a disconnect (for any reason). I found no clean ways to hook pppd, but did manage to wrap a shell script around it where the delay can be inserted.

It installs and uninstalls itself with shell command line calls:


sudo PPPfix install
sudo PPPfix uninstall
and will repair the the pppd hook automatically should an OS update overwrite it.

The script requires SleepWatcher (http://home.t-online.de/home/bernhard.baehr/).

Here's the script (hopefully well enough documented for others to use):


#!/bin/sh -
# PPPfix -- works around pppd Disconnecting... hang

# pppd may fail if a dial-up attempt is made within ~20 seconds of waking/startup
# and also if a reconnect attempt occurs too soon after a disconnect
# with efax running, pppd will also hang in the Disconnecting... state if these failures occur
# the workaround is to hold off pppd's launch until the critical periods have passed

# holding off pppd startup is done by wrapping a shell script around the standard pppd executable
# the real pppd executable is renamed and a symbolic link to PPPfix
# named "pppd" is placed in pppd's original location so that configd will call it instead of the real pppd
# the script then checks to see if a dial attempt was made during the critical period
# and if so sleeps for the necessary time if necessary before launching the real pppd
# when the real pppd finishes, a new unsafe zone is computed

# this script has four distinct behaviors depending on how it is called
# they are grouped together in a common script to make it easier
# to synchronize operations and maintain changes

# 1) when called without any parameters,
# it checks and repairs the wrapper if it has been disturbed
# (e.g., an OS update might overwrite the shell with a new executable)
# then it sets up the initial unsafe zone and exits

# Sleepwatcher provides an excellent place for this call
# since it runs every time the system wakes up or boots.
# Sleepwatcher must be installed to use this script as is
# it can be dounloaded at http://www.bernhard-baehr.de/sleepwatcher_1.0.1.dmg

# 2) when called with install as the first parameter,
# the wrapper is installed and a symbolic link to PPPfix is created in /var/.wakeup
# so that sleepwatcher will execute it during the next boot/wakeup

# 3) when called with uninstall as the first parameter
# the pppd wrapper is uninstalled and normal pppd behavior is restored
# the /var/.wakup link is removed to prevent sleepwatcher from calling PPPfix

# the install and uninstall calls should be made manually
# this should be done manually but must be run with root privlidges:
# sudo /Applications/Utilities/PPPfix install
# sudo /Applications/Utilities/PPPfix uninstall

# 4) in all other cases, this script functions as the wrapper for the real pppd
# so that it's execution can be held off during unsafe periods
# all parameters passed to PPPfix are forwarded to the real pppd
# the assumption is that it's called by configd
# if not, behavior is not defined

# names of related files -- CHANGE these if locations or names vary
pppFix="/Applications/Utilities/PPPfix"
origPPPD="/usr/sbin/pppd"		# the location/name of the normal pppd execitable
renamedPPPD="${origPPPD}Real"		# the renamed location/name for the ppp executable
rootWakeup="/var/root/.wakeup"		# location of root's sleepwatcher wakup script

pppTimeFile="/tmp/pppSafeTime"		# used to store earliest "safe" time for pppd launch


# to ease calculations, times used in this script are seconds past the Epoch
# the following macro is used to get the system time

getTime="date +%s"


# calculate the earliest "safe" PPP startup time
# based on current time and delay time passed to function as 1st arguement
# safe time is stored in a file so multiple instances of PPPfix can access it

function setPPPsafeTime ()
{
	# compute and store earliest safe run time for pppd
	goTime=`$getTime`
	(( goTime=$goTime+$1 ))

	echo $goTime > $pppTimeFile
}


# this function is used to hook pppd if it has not been already
# tests prevent hooking the hook overwriting the pppd executable
# original pppd must NOT be a symbolic link
# PPPfix (this script) must exist and be executable

function hookPPPD ()
{
	if [[ ! -h $origPPPD && -x $pppFix ]]; then
	{
		# remove any existing renamed pppd
		rm -f $renamedPPPD

		# rename real pppd
		mv $origPPPD $renamedPPPD

		# setup PPPfix as the wrapper for pppd
		ln -s $pppFix $origPPPD

		logger fixed PPPD hook to holdoff execution during critical times
	}
	fi
}

# this function unhooks pppd and restores the pppd executable to its normal location/name
# original pppd must be a symbolic link
# tests prevent deleting the real executable
# the renamed real pppd must exist
# pppd must be a symbolic link to PPPfix

function unhookPPPD ()
{
	if [[ $origPPPD -ef $pppFix && -a $renamedPPPD ]]; then
	{
		rm -f $origPPPD
		mv $renamedPPPD $origPPPD

		logger PPPD hook uninstalled
	}
	fi
}


# delay times for unsafe zones
wakeupDelay=25		# time to disable PPP after wakeup/boot
reconnectDelay=15	# time to delay pppd after a disconnec



# this is the section executed at wake/boot
# called from sleepwatcher (no parameters) (root privileges)
if [[ $# == 0 ]]; then
{
	# check pppd hook and repair if necessary
	hookPPPD

	# set boot/wakeup unsafe zone
	setPPPsafeTime $wakeupDelay
}

# installer -- called from command line with root privileges 
elif [[ $1 == "install" ]]; then
{
	hookPPPD

	# install root's .wakeup file executed by Sleepwatcher
	if [[ ! -a $rootWakeup ]]; then
	{
		ln -s $pppFix $rootWakeup
	}
	else
	{
		echo $rootWakeup already exists -- install wakeup call manually
	}
	fi

}

# uninstaller -- called from command line with root privileges
elif [[ $1 == "uninstall" ]]; then
{
	unhookPPPD

	# uninstall root's .wakeup file executed by Sleepwatcher
	# .wakeup must be a symbolic link to PPPfix
	if [[ $rootWakeup -ef $pppFix ]]; then
	{
		rm -f $pppFix $rootWakeup
	}
	else
	{
		echo $rootWakeup is not a link to $pppFix -- uninstall wakeup call manually
	}
	fi
}

# this is the pppd wrapper -- called by configd (lots of parameters)
else
{
	# delay only needed if safe time file exists
	# and current time is before the safe time in the file
	if [ -s $pppTimeFile ]; then
	{
		safeTime=$(< $pppTimeFile)
		nowTime=`$getTime`

		if [ $nowTime -lt $safeTime ]; then
		{
			(( delayTime=$safeTime-$nowTime ))
			logger delaying pppd startup $delayTime seconds

			sleep $delayTime
		}
		fi
	}
	fi


	# run real pppd executable -- forward all parameters passed to PPPfix
	`$renamedPPPD "$@"`

	# save status so this script can emulate exit status of real pppd
	pppdStatus=$?

	# compute and store earliest safe run time for pppd
	setPPPsafeTime $reconnectDelay

	exit $pppdStatus
}
fi


[ Reply to This | # ]