From owner-freebsd-questions Tue Aug 20 01:00:12 1996 Return-Path: owner-questions Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id BAA06776 for questions-outgoing; Tue, 20 Aug 1996 01:00:12 -0700 (PDT) Received: from freenet.hamilton.on.ca (main.freenet.hamilton.on.ca [199.212.94.65]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id BAA06765 for ; Tue, 20 Aug 1996 01:00:07 -0700 (PDT) From: hoek@freenet.hamilton.on.ca Received: from james.freenet.hamilton.on.ca (james.freenet.hamilton.on.ca [199.212.94.66]) by freenet.hamilton.on.ca (8.7.5/8.7.3) with ESMTP id EAA13867; Tue, 20 Aug 1996 04:00:04 -0400 (EDT) Received: (from ac199@localhost) by james.freenet.hamilton.on.ca (8.7.5/8.7.3) id EAA14857; Tue, 20 Aug 1996 04:01:47 -0400 (EDT) Date: Tue, 20 Aug 1996 04:01:47 -0400 (EDT) Message-Id: <199608200801.EAA14857@james.freenet.hamilton.on.ca> X-Mailer: slnr v.2.13 as ported to FreeBSD To: Leonard@pacbell.net Cc: questions@freebsd.org Subject: Re: Pager Program? Sender: owner-questions@freebsd.org X-Loop: FreeBSD.org Precedence: bulk In Email, Leonard Chung wrote: > At 05:10 PM 8/19/96 -0400, hoek@freenet.hamilton.on.ca wrote: > script after running chmod +x on it, but FBSD refused to run the script Actually, it was the shell that refused to run the script. :) FBSD didn't even get to find out about the whole thing. > saying that it isn't a valid command. Am I doing something wrong here? Yes. > If you could add some comments, that'd be great. Also, I tried to run the Ok, here's a commented version, in addition to a bit of documentation. Like I said before, though, it hasn't been "real-world" tested, since I don't have a pager. All I know is that it dials my phone number whenever the modem sends a RING. :) The basic idea is as follows, Your modem is attached to a com port. For every com port you have, there is a file in your /dev directory which, when read from, returns data from the com port, and, when written to, sends data to the com port. (Incidentally, this file has associated with information regarding the baud rate, cr->nl mapping, and just about everything else. man 1 stty if such unimportant details are interesting. man 3 tcgetattr is even more interesting, actually. This `struct termios' stuff is associated with, for example, stdin, stderr, and /dev/mouse) We want a shell script that will, when it reads a `RING', print `atdt 5557399'. It must not just print `atdt 5557399', however. It must, after the `RING', wait about 10 minutes so that the person can leave their message. Because it's possible for the attempted `atdt 5557399' to fail, it must also somehow know that the pager was successfully dialed. Because the reading (from the com port) will BLOCK (or wait) until a whole line is read, the script will have to fork one process to read for a succesful "CONNECTED" message, and another to dial in the meantime. Depending on your specific modem some changes may be necessary. Hopefully they wouldn't/won't be too hard to make. This script expects to have data from the modem sent to it as (stdin) and data printed to (stdout) is expected to go to the modem. Therefore, it must be started like this, ./pager < /dev/cuaa? > /dev/cuaa? So that it can read/write to /dev/cuaa? it must be run as root. Where the `?' is, you should put the com port number of the modem - 1. For example, if you modem is on com1, you would use ./pager < /dev/cuaa0 > /dev/cuaa0 We need to specify the `./' in front of `pager' because the pager program is not in one of the directories specified in your PATH. Alternatively, if it is, you may have to type `rehash' to make csh know that it is in one of the directories specified in your PATH. There! Lotsa comments! :) Any other (fairly specific questions, I trust) will be entertained, too. :) #! /bin/sh # This line makes the system use the /bin/sh program to interpret the # file. It also means that making this a setuid program will not make # it a setuid program. # If there is already an environment variable by the name of LOGFILE, # then we'll leave LOGFILE as that. Otherwise, we'll make LOGFILE # equal to `/dev/null'. LOGFILE=~/.junk ./pager < /dev/cuaa1 > /dev/cuaa1 # would set LOGFILE to ~/.junk. LOGFILE=${LOGFILE:-/dev/null} # Later we fork another process. Because it's a different process it # will have a different process id. However, it needs to know what # the pid of it's parent is, so we'll store it here. (It needs to # know because the two communicate via files named after the pid). MYPID=$$ export MYPID # These are the afore-mentioned files. $$ expands to the pid. We # could have used DIALINGPAGER.${MYPID}, too. rm -f /tmp/DIALINGPAGER.$$ rm -f /tmp/CONNECTED.$$ # Turn echoing off. Standard hayes command. We use the `printf' # program so that we have translation of \r and \n (for example. # Some (most, all?) modems expect lines to be terminated in the # DOS fashion of \r\n instead of just \n. printf 'ate0\r\n' printf 'atx3\r\n' # equivelant to C's while (1) { while [ ! ] do # Read one line of input into the variable ${l}. read l # Remove any \r and \n 's from ${l}. l=`echo ${l} | perl -pe 's/\r|\n//g'` # `man 1 [' for more info on the `[' expression syntax. # We put an `x' in front of RING and ${l} since it's possible # for ${l} to be empty, which would result in `[ = xRING ]' # which, of course, is a syntax error. if [ x"${l}" = xRING ] then # Print a dated message into the logfile. `>>' # specifies that we concatanate to the logfile. # a simple `>' would overwrite it (unless some NOCLOBBER # screw-up variable is defined). man 1 date date '+%m/%d %H:%M Caught a `RING'\''!' >> ${LOGFILE} # True if the file does not exist. # Obviously we don't want to be trying to dial the # pager if we are already trying to dial the pager. if [ ! -e /tmp/DIALINGPAGER.$$ ] then # Fork a second copy of `sh' and run it in the background. Pass to it # the following commends, upto the `EOF'. Do not perform any # interpretation on the text between here and the EOF before passing # it to the forked shell. `man 1 sh' and then text-search for the # string `here-document'. sh << "EOF" & # Defines a shell function called redial. I really # don't know why I made this a function. In retrospect, # it's kind of silly. Oh well, at least I don't make # a gratouitous (sp?) use of `cat' anywhere... :) redial () { # Append dated message to logfile. date '+%m/%d %H:%M Dialing pager.' >> ${LOGFILE} # Can you find the hidden message? ;) printf 'atdt 5557399\r\n' } # NOTE that we have not yet executed any of the commands # in the redial function. # # Goto sleep for ten minutes to allow the person ample # time to finish their message. sleep 600 # Loop until the file /tmp/CONNECTED.#### exists. while [ ! -e /tmp/CONNECTED.$MYPID ] do # Call the redial function. redial # Allow time for the modem to actually dial sleep 30 done # We're out of the loop. That means that the # file /tmp/CONNECTED.#### exists. That means we # connected. Yea! Let's make a dated logfile entry. date '+%m/%d %H:%M Successfully dialed pager.' >> ${LOGFILE} # Remove these two files. And do so silently. rm -f /tmp/DIALINGPAGER.$MYPID rm -f /tmp/CONNECTED.$MYPID # This signifies the end of the commands passed to the second, forked, # backgroud shell. Try to envision the flow of commands. This section # was really just one command it executed in the background. To the # shell it executed in the background, this section was a number of # commands. The foreground shell has already continued executing # commands far far beyond this one. The background shell, however, # stops here (since this is all that is passed to it). EOF # Create the file to show that we currently have # a shell in the background dialing the pager. That # background shell will delete the file when it is # no longer dialing the pager. touch /tmp/DIALINGPAGER.$$ # ENDIF, in BASIC terminology. This endif goes with # the original test to see if there was already # a process dialing the pager. For some reason I didn't # intend between hither and thither. Shucks Darn. fi # else if. # My modem seems to send either `BUSY' or `NO CARRIER' # when it connects to a voice line. If ${l} equals this # then we must have connected. Your modem may be different. elif [ x"${l}" = xBUSY -o x"${l}" = x"NO CARRIER" ] then # Create the file to let the spawned background shell # know that we have connected. touch /tmp/CONNECTED.$$ # Log It! date '+%m/%d %H:%M Connected!' >> ${LOGFILE} # Else if ${l} has equaled nieither RING, nor BUSY, nor # NO CARRIER, then do this. else # Okay, only do this if ${l} actually equals something # and is not just an empty line. (Your modem probably # sends an empty line along with every interesting # line). if [ ! x"${l}" = x ] then # Log It! date '+%m/%d %H:%M Caught a `'"${l}"\' >> ${LOGFILE} fi fi # end of the intermniable while loop. done # Try doing that with a DOS batch file! ;) -- -- tIM...HOEk Outnumbered? Maybe. Outspoken? NEVER!