./comgt.0.32/0000755000175000001440000000000010516161012011556 5ustar paulusers./comgt.0.32/TODO0000755000175000001440000000115110516161012012247 0ustar paulusersTo Do ===== Better error handling for built-in scripts. (non-existent at the moment) Old - unlikely to be addressed: Option: locking (uucp? What's the standard?) (Who cares?) Better testkey (Change stdin mode to raw, update input, system, exec & exit) getcomchar() (Get one byte from com so a dumb term could be written in a script. Should be done only after testkey) Polling sucks. Could this be (major) changed to be interrupt-driven? (Do people still use non-16550s out there?) Error reporting doesn't display the line containing the error. $Id: TODO,v 1.1 2006/08/20 23:53:19 pharscape Exp $./comgt.0.32/comgt.10000644000175000001440000011053610516161012012757 0ustar paulusers.\" Paul Hardwick .\" paul@peck.org.uk .TH comgt 1 "20 October, 2006" .LO 1 .SH NAME comgt \- Option GlobeTrotter GPRS/EDGE/3G/HSDPA and Vodafone 3G/GPRS datacard control tool .SH SYNOPSIS .B comgt .RB \-d .I "device" .RB -ehstvVx .I "script" .SH OPTIONS .in +5 .B \-d .I device .in +10 set the device to be used to communicate with the data-card. If not specified then comgt trys .I /dev/noz2, /dev/ttyUSB2 and then .I/dev/modem .PP .in +5 .B \-e .in +10 turn on serial communications echo. .PP .in +5 .B \-h .in +10 display summary help and exit. .PP .in +5 .B \-s .in +10 don\'t run the internal .I default script before an external script. .PP .in +5 .B \-t .in +10 change to an alternate line terminator (default "\n"). .PP .in +5 .B \-v .in +10 run in verbose mode. This traces scripts as they are executed. It is intended to help in debugging scripts. .PP .in +5 .B \-V .in +10 Print Version information. .PP .in +5 .B \-x .in +10 for internal and external scripts, any reference to 115200 baud is converted to 57600. This is useful for data cards that don't like 115200 baud such as the GlobeTrotter EDGE. .PP .in -10 .SH DESCRIPTION .B comgt is a scripting language interpreter useful for establishing communications on serial lines and through PCMCIA modems as well as GPRS and 3G datacards. .PP .B comgt has some features that are rarely found in other utilities of the same type. .in 5 .SS Features .nf - Pre-defined built-in scripts for 2G/3G datacard control - Simple, BASIC-like script language. - Command-line and file sourcing of script. - Multi-response waitfor. - waitquiet permits line stabilization. - In-line text capture. - Multi-process support: fork, wait, kill, exit. - Debugging verbose and log output. - logging to file. - Flow control: goto, gosub, return, if, else. - Low-impact on system resources. - Time commands and functions. - String manipulations. - Environment manipulation: env(), putenv. - External utilities system calls: system, exec. .PP .SS Supported GPRS and 3G datacards .B comgt has been tested against GlobeTrotter GPRS,EDGE, Combo EDGE, 3G, 3G EDGE, HSDPA and GlobeTrotter Fusion as well as Vodafone 3G. It can set the PIN and display information about datacards before a PPP connection is started. Additionally, because the GlobeTrotter and Vodafone 3G/GPRS datacard have a secondary serial interface, these datacards can be monitored while a PPP connection is in existence and transferring data. .PP .B comgt is primarily designed to work with the GlobeTrotter range of datacards but should be compatible with any other GPRS or 3G datacard provided its interface is implemented as one or more serial or USB serial devices and it is controlled and queried by an implementation of the Hayes command interface with the same AT command extensions used by the listed datacards. . .SS Using comgt .B comgt has only one function: to run a script. This may be one of a number of "standard" internal scripts or an external script. Both types of script are invoked in the same way. The "standard" scripts are built into .B comgt and will work for serially connected modems, built-in modems, PCMCIA modems as well as the GlobeTrotter GPRS and the Vodafone 3G/GPRS datacards. . There is a search priority order for scripts - 1)internal, 2)working directory, 3)/etc/comgt .PP .SS Built-in scripts .in -5 .I comgt .in +5 This runs the default internal script. Running .B comgt without any script specified, e.g., .I comgt -d /dev/ttyS1 it will check for a PIN and prompt you if it is required. The next thing it does is wait for the device to register, it then reports the signal strength. If you don\'t specify a port with the .B -d option then .I /dev/modem is assumed. If the -s switch is not used then this default script is run before any external script. .in -5 .I comgt help .in +5 Lists these and the other options available. .PP .in -5 .I comgt info .in +5 Lists the datacard configuration. .in -5 .I comgt sig .in +5 Prints the signal strength. .in -5 .I comgt reg .in +5 Prints the registration state. .in -5 .I comgt 3G .in +5 Puts a GlobeTrotter 3G/Fusion and Vodafone 3G into 3G network only mode (UMTS/HSDPA). .in -5 .I comgt 2G .in +5 Puts a GlobeTrotter 3G/Fusion and Vodafone 3G into 2G network only mode (GSM/GPRS/EDGE). .in -5 .I comgt 3G2G .in +5 Puts a GlobeTrotter 3G/Fusion and Vodafone 3G into 3G preferred mode (UMTS/HSDPA and GSM/GPRS/EDGE). .in -5 .I comgt GTEDGE .in +5 Use this command to initialise GlobeTrotter EDGE and GlobeTrotter Combo EDGE cards before doing anything else. (It switches on the radio). .in -5 .I comgt USA .in +5 Switch to 900/1900 MHz band for USA operation. GlobeTrotter GPRS datacards only. .in -5 .I comgt EUROPE .in +5 Switch to 900/1800 MHz band for European operation. GlobeTrotter GPRS datacards only. .in -5 .I comgt PIN .in +5 Test the SIM PIN status and use the environment variable COMGTPIN as the value . .in -5 .I comgt APN .in +5 Set the APN of the datacard to the value contained in the COMGTAPN environment variable. .PP .SS Custom Scripts As well as built in scripts you can make your own. The following script sets a Vodafone 3G datacard or Option Fusion card\'s UMTS mode to GPRS: .PP .in +5 #Set GPRS only mode .br set com 115200n81 .br set senddelay 0.05 .br waitquiet 1 0.2 .br send "AT_OPSYS=0^m" .br print "Setting GPRS only mode" .PP If you saved the above script as GPRS you would call it like this: .PP .in +5 .I comgt GPRS .in -5 .PP If you needed to specify the port as well then do this: .PP .in +5 .I comgt -d /dev/ttyS1 GPRS .in -5 .PP You can also pass environment parameters to a .B comgt script via .I $env(). . .SS Replacing chat .B chat is a utility that comes with the ppp package (for Linux, anyway) that, with a set of expect-send string couples, does enough to connect most people to ISPs and such. While chat\'s use is very simple, it isn\'t very flexible. That\'s where .B comgt takes over. .PP .B comgt can be used in place of .B chat using the same strategy. For example, a pppd line reading: .PP .in +5 .nf pppd connect \\ \'chat -v "" ATDT5551212 CONNECT "" ogin: ppp \\ word: whitewater\' \\ /dev/cua1 38400 debug crtscts modem defaultroute .fi .in -5 .PP Would, using .B comgt, read: .PP .in +5 .nf pppd connect \'comgt -s /root/scripts/isp.scr\' /dev/cua1 38400 \\ debug crtscts modem defaultroute .fi .in -5 .PP And the isp.scr script would read: .PP .nf send "ATDT5551212^m" waitfor 60 "ogin:" send "ppp^m" waitfor 60 "word:" send "whitewater^m" .fi .PP Of course it then becomes trivial to make this script a whole lot more functional by adding code for busy detect, re-dialing, etc... . .SS Verbose output When the verbose option is turned on, .B comgt reports everthing on the standard error channel. If turned on from the command line (-v), the output contains 4 sections. .PP - Command line argument actions .in +2 These are actions taken because they were specified from the command line, such as opening a communication device (-d), etc... For these to be output, you must specify -v as the first argument. .in -2 .PP - List of arguments .in +2 The number and list of arguments passed. This is useful in case you have a bunch of environment variables or quotes, back-quotes, backslashes on the command line and you\'re not sure what the script really sees. .in -2 .PP - Script list .in +2 A list of the script to execute. This may be a concatenation of the default internal script, unless this is suppressed by the -s option, and a script file. Every line is listed with its line number and character position. .in -2 .PP - Execution output .in +2 List of commands as they are executed. The parser prints the line its currently on, starting from the exact point where its at to the end of the line. Multiple command groups on a single line produce multiple output lines. Verbose output may be mixed with script output (print, eprint or lprint.) .in -2 .PP Here\'s an example: .PP .in +2 .nf $ comgt -v -d/dev/cua1 -s blah.scr comgt 00:18:46 -> Verbose output enabled comgt 00:18:46 -> Script file: blah.scr comgt 00:18:46 -> argc:5 comgt 00:18:46 -> argv[0]=comgt comgt 00:18:46 -> argv[1]=-v comgt 00:18:46 -> argv[2]=-d/dev/cua1 comgt 00:18:46 -> argv[3]=-s comgt 00:18:46 -> argv[4]=blah.scr comgt 00:18:46 -> ---Script--- .in +3 1@0000 set com 38400n81 let a=2 2@0025 print "9x",a,"=",9*a,"\\n" 3@0051 sleep 5 4@0059 exit 0 .in -3 comgt 00:18:46 -> ---End of script--- comgt 00:18:46 -> @0000 set com 38400n81 let a=2 comgt 00:18:46 -> @0017 let a=2 comgt 00:18:46 -> @0025 print "9x",a,"=",9*a,"\\n" 9x2=18 comgt 00:18:46 -> @0051 sleep 5 comgt 00:18:51 -> @0059 exit 0 .in -2 .fi . .SH Programming manual .SS Syntax The syntax used for .B comgt scripts is rather simple, somewhat BASIC-like. A script is a non-tokenized, pure ASCII text file containing lines terminated by newline characters (Unix standard.) Scripts can be created and/or modified using any standard text editor (vi, vim, joe, pico, emacs, ed, microEmacs) Lines in a .B comgt script read like so: .nf - Empty line - [indent]rem remark - [indent][[:|label] LABEL] [command [arguments]] rem remark - [indent][[:|label] LABEL] [command [arguments]] [command [arguments]]... .PP Characters used for indentation are the space and tabulation characters. The rem command makes the script parser skip the rest of the line. The rem command can also be written as "#" or "//". .PP Labels consist of lowercase and uppercase letters and digits. Case is ignored in labels. .PP Commands and their arguments are separated by spaces and/or tabs. Command groups are separated by spaces, tabs, or newlines. .PP Expressions must not contain spaces or tabs. .nf This is ok : let n=x+76 This is not: let n= x + 76 Because this space ^ would terminate the let command group. .fi . .SS Error reporting When .B comgt detects a script error, it immediately turns on verbose mode, generates a dump (see the dump command), reports the error in three lines and stops the execution. The first line reported is the command group being executed, the second one shows where the parser got and the third line reports the character position of the program counter, the error and the exit code. Here\'s an example: .PP .in +5 .nf $ comgt -vs blar2.scr .fi .in -5 .PP Where the blar2.scr script is: .PP .nf .in +5 inc n dec d3 let a=58/3 let $d="fod" let c=1/0 let $y4="sdfgsdfgsdfg" .in -5 .fi .PP The trace and error report looks like this: .PP .in +5 .nf comgt 11:20:15 -> Verbose output enabled comgt 11:20:15 -> Script file: blar2.scr comgt 11:20:15 -> argc:3 comgt 11:20:15 -> argv[0]=comgt comgt 11:20:15 -> argv[1]=-vs comgt 11:20:15 -> argv[2]=blar2.scr comgt 11:20:15 -> ---Script--- .in +3 1@0000 inc n 2@0007 dec d3 3@0015 let a=58/3 4@0027 let $d="fod" 5@0041 let c=1/0 6@0052 let $y4="sdfgsdfgsdfg" .in -3 comgt 11:20:15 -> ---End of script--- comgt 11:20:15 -> @0000 inc n comgt 11:20:15 -> @0007 dec d3 comgt 11:20:15 -> @0015 let a=58/3 comgt 11:20:15 -> @0027 let $d="fod" comgt 11:20:15 -> @0041 let c=1/0 comgt 11:20:15 -> -- Error Report -- comgt 11:20:15 -> ----> ^ comgt 11:20:15 -> Error @49, line 5, Division by zero. (6) .fi .in -5 . .SS Exit codes When .B comgt terminates, it does so with an "exit code". That is a number passed back to the calling process to signify success or failures. In every-day Unix, 0 (zero) means success and everything else means whatever the author of the program wants it to mean. In a shell script, or directly on the command line, you may look at the content of .I $? after having called .B comgt to examine its exit code. .PP Example: .PP .in +5 .nf #!/bin/sh comgt /root/bin/call-isp if [ $? != 0 ]; then echo "Oops! Something went wrong." fi .fi .in -5 .PP Internal .B comgt error codes are as follows: .PP .in +5 .nf 0 : No problems whatsoever. Apparently. 1 : Communication device problems. 2 : Console (tty) device problems. 3 : Memory problems. 4 : File or pipe problems. 5 : Syntax errors. 6 : Division by zero. 7 : Variable mis-management. 8 : System problems. (Couldn\'t call /bin/sh or some such) .fi .in -5 . .SS Commands .PP .nf Command : : Alias: label Description : Notes an anchor point for goto or gosub to branch to. Syntax : Keyword must not contain any special characters. Note : Must be first statement in a line. See Also : goto, gosub, return. Example: :loop gosub bravo print "The time is ",$time(),"\\n" sleep 1 goto loop label bravo print "Twonk!\\n" return Command : abort Description : Causes comgt to call abort() and produce a core dump. Syntax : abort See Also : dump, exit. Command : cd Description : Change directory. Syntax : cd directory Notes : -1 is returned in % if the change could not be made. Notes : directory is a string and thus could be a variable. See Also : $cwd(). Example: cd "duh" if % != 0 print "Could not cd into duh.\\n" Command : close Description : closes file previously opened with open. Syntax : close file See Also : open. Command : dec Description : Decrements the content of an integer variable by 1. Syntax : dec x Notes : x is from a to z or a0 to z9. Notes : Note that "let x=x-1" also works. See Also : let, inc. Command : dump Description : Lists all non-zero integer variables and modified string Description : variables as log entries (standard error channel.) Syntax : dump See Also : abort, exit Command : else Description : Alternatively execute commands if last "if" tested false. Syntax : else commands... See Also : if Example: if w<350 print "Wow! Imagine that.\\n" else print "Rush Limbaugh is a big fat bastard.\\n" Command : eprint Description : print a comma-separated list of arguments on stderr. Syntax : eprint var,stringvar,"text",... Notes : Like print but on the standard error file descriptor. Notes : The error output can be re-directed with "2>file" on Notes : the command line. See Also : print. Command : exec Description : Replaces current comgt process with another process. Syntax : exec "command -args..." See Also : system, fork. Example: #Finished script, call cu. exec "cu -l "+$dev()+" -s "+$baud() Command : exit Description : terminates script execution with exit code. Syntax : exit exit_code See Also : abort, dump. Example: :error exit 1 :smeggit exit 0 Command : flash Description : Toggles DTR on communication device for a specified time. Syntax : flash float_constant Notes : float_constant is precise down to 1/100th sec. Notes : Causes modem to drop carrier or go to command mode, Notes : depending on modem settings. Setting the baud rate to 0 Notes : for a time has the same effect. See Also : sleep, set com. Example: :disconnect flash 0.5 exit 0 Command : fprint Description : print a comma-separated list of arguments in a file. Syntax : fprint var,stringvar,"text",... Notes : Like print but appended to a file previously opened Notes : by open. See Also : print. Command : fork Description : forks comgt process in two. Both processes continue Description : executing the script. Syntax : fork Notes : % returns 0 for child process, new process ID for Notes : parent or -1 for error. See Also : wait, kill, pid(), ppid(). Example: fork if % = -1 goto error if % = 0 goto child :parent ... Command : get Description : get string from communication device. Syntax : get timeout "terminators" $string Notes : timeout is a float constant, terminators is a Notes : list of characters that, when received, terminate Notes : get. Terminators are ignored when received first. See Also : waitfor. Example: waitfor 60 "connect" if % != 0 goto error get 2 " ^m" $s print "Connection parameters: ",$s,"\\n" Command : gosub Description : calls a subroutine. Syntax : gosub label Notes : Currently, comgt only supports 128 levels of gosub Notes : calls (enough!) See Also : :, goto, return. Example: gosub routine sleep 1 gosub routine goto end :routine print "Flim-flam!\\n" return Command : goto Description : Sends execution somewhere else in the script. Syntax : goto label See Also : :, gosub, return. Example: :win95 print "Today I want to go and use Linux, thank you.\\n" goto win95 Command : hset Description : Set the hundreds timer. Syntax : hset value Notes : This command resets the hundreds of seconds timer to Notes : a value for htime to start from. See Also : htime(). Example: hset 0 :loop print "Time in 1/100 of a sec.: ",htime(),"\\n" sleep 0.01 goto loop Command : if Description : tests a condition Syntax : if test_condition commands... Notes : Conditionnaly executes commands if test condition is true. Notes : Test operators are = (equal), != (not equal), Notes : <> (not equal to) < (less than), > (greater than), Notes : <= (less or equal), >= (greater or equal). Notes : All operators can be used with integers and strings. Notes : If test_condition is false, if skips to Notes : the next line. See Also : else. Example: if n>30 print "Oh-ho! too many sheep!\\n" goto error if n=17 print "Hurray! we\'ve enough sheep\\n" goto party if n<17 print "Murray, get more sheep.\\n" goto getmore if $z < "Marmaluke" goto ... if 3*a>5+b goto ... Command : inc Description : increments the content of an integer variable by 1. Syntax : inc x Notes : x is a-z or a0-z9. See Also : dec, let. Command : input Description : input string from keyboard into string variable. Syntax : input $x Notes : input terminates entry only with the ENTER key. Notes : Spaces, tabs and other funny characters are all Notes : stored in the variable. See Also : set echo. Example: print "Enter your full name :" input $n4 Command : kill Description : Sends a signal to a process. Syntax : kill signal processID Notes : Both signal and processID are integer values. Same as Notes : standard unix kill except that signal aliases are not Notes : accepted and signal is not optional. Notes : 0 is returned in % if the signal could be sent, -1 Notes : otherwise. Notes : Signal 0 can be used to detect process existance. See Also : wait, pid(), ppid(). Example: fork let p=% if p = 0 goto child sleep 300 kill 15 p sleep 1 kill 0 p if % != 0 print "Child terminated\\n" goto ok print "Could not terminate child!\\n" kill 9 p sleep 1 kill 0 p if % = 0 print "Could not kill child!\\n" goto error print "Child killed.\\n" :ok ... Command : let Description : Does a variable assignment. Syntax : let x=content Notes : x is [$]a0-z9. See Also : inc, dec. Example: let a=5 let b=(time()-a)+5 let y7=6809 let z=0%11010111 #Binary let z=077324 #octal let z=0xf5b8 #hexadecimal let $c="Daniel " let $d=$c+" Chouinard" let $s5="Frimpin\' Jeosaphat!" Command : lprint Description : Print a comma-separated list of arguments to the log. Syntax : fprint var,stringvar,"text",... Notes : Like print but printed like a log entry if verbose is on. Notes : logging is sent to stderr. See Also : print, eprint, fprint. Command : open Description : Opens a file or a communication device. Syntax : open com device, open com (stdin), open file FILE See Also : close. Example: open com /dev/cua1 set com 38400n81 open file "/tmp/log" fprintf "This is a log\\n" close file Command : print Description : print a comma-separated list of arguments. Syntax : print var,stringvar,"text",... Notes : Spaces and newlines are not automatically added. See Also : eprint, fprint, lprint. Example: let b=26 let $c="text variables" print "Contstant text ",b," ",$c," time: ",$time(),"\\n" Command : putenv Description : Sets an environment variable. Syntax : putenv "var=content" Notes : Environment variables are automatically exported, Notes : never returned. Children processes inherit the Notes : environment. See Also : $env(). Example: putenv "SCRIPTDIR=/usr/lib/comgt/scripts" system "dothat" # dothat reads env. var. SCRIPTDIR... Command : rem Aliases: #, // Description : Remark. Rest of line is ignored. Syntax : Note that a space must follow "rem". Example: #This is a remark // So is this rem This ain\'t no disco. Command : return Description : Returns from subroutine. Syntax : return See Also : gosub. Command : send Description : sends a string to the communication line (modem usually). Syntax : send string Notes : Carriage return (ENTER) is not sent automatically Notes : (use ^m). Example: send "atdt555-1212^m" send $g+"^m" send "The time is "+$time()+"^m^j" Command : set Description : sets working parameters. Syntax : set parameter value Notes : Command Description ----------------------------- ------------------------------------------------- set echo on|off Keyboard echo on-screen. set comecho on|off Received characters echoed on-screen. set senddelay time_constant In-between character delay for "send" set ignorecase on|off Case sensitivity for "waitfor". Default=on. set clocal on|off clocal on = ignore modem signals set umask mode file mode creation defaults. See man umask. set verbose on|off verbose on = debug output enabled. set com com_params communication parameters. ex.: 19200n81, 300e71 baud ||| Parity | Data bits | Stop bits | Example: set echo off print "Password :" input $p print "\\n" set echo on set comecho on set clocal on set senddelay 0.1 set ignorecase on set com 38400n81 set umask 022 # Must be octal (leading zero) ... Note on clocal: If want your script to keep working after the carrier detect signal has dropped, set clocal on, otherwise, a CD drop causes the device line to close (hang up). This could happen if, let\'s say, your script calls and connects, then disconnects or drops dtr (flash), then tries to re-connect again. Command : sleep Description : Pauses execution. Syntax : sleep float_constant Notes : Float_constant is precise down to 1/100th sec, unless Notes : more than 100 seconds, in which case the precision Notes : falls down to 1 sec. Example: sleep 0.06 sleep 3 sleep 86400 /* A whole day */ Command : system Description : Calls a system (unix) command Syntax : system "command" See Also : exec. Example: :dir print "listing of directory ",$cwd(),\\n" system "ls -l |more" Command : testkey Description : Tests keyboard for keystroke, returns 1 in % if present. Syntax : testkey Notes : Can only test for ENTER key. Future versions of comgt Notes : will test for more and return keycodes in %. See Also : input. Example: let n=1 :loop print n," sheep... ZZZzzz...\\n" sleep n inc n testkey if % = 0 goto loop Command : wait Description : Wait for a child process to terminate. Syntax : wait Notes : Process ID of terminated child is returned in % See Also : fork, kill. Example: fork let p=% if p=0 goto child if p=-1 goto error print "Waiting for child to finish..." wait print "\\n" if %!=p print "Wait got wrong PID!\\n" goto error print "Child is done.\\n" Command : waitfor Description : Waits until one of a list of strings is received Syntax : waitfor timeout "string1","string2","string3"... Notes : Timeout is a floating time constant. waitquiet returns Notes : 0 for the first string received, 1 for the second, etc... Notes : and -1 for a timeout. Case is ignored by default unless Notes : ignorecase is set to off. See Also : get. Example: :dial send "atdt555-4411^m" waitfor 60 "no carrier","busy","no dial tone","connect" if % = -1 goto timedout if % = 0 goto nocd if % = 1 goto redial if % = 2 goto error if % = 3 goto connected Command : waitquiet Description : Waits until communication line stops receiving for a time. Syntax : waitquiet timeout quiettime Notes : Both timeout and quiettime are floating time constants Notes : with 1/100th sec. accuracy. Usefull for "swallowing" Notes : incoming characters for a while or waiting for an Notes : unknown prompt. Example: :closecon send "logoff^m" waitquiet 10 0.5 send "yes^m" .fi . .SS Integer functions .PP .nf I-Function : Access Description : Verifies access rights to a file Syntax : let x=access("/tmp/file","frwx") Notes : The second string contains one or more of Notes : \'f\',\'r\',\'w\',\'x\' to repectively check Notes : existence, read, write and execute permissions. Notes : Under root id, the only useful check is \'f\', as Notes : all others will return true. Return Value: 0 if the file exists, is readable, writable, Return Value: executable, or -1 if not. See Also : man access(2) I-Function : baud Description : Returns current baudrate of communication line. Syntax : let x=baud() Notes : Does not necessarily match the modem connection speed. See Also : $baud(). I-Function : len Description : Returns the length of a string. Syntax : let x=len($s) Notes : "" is zero. Strings currently have a maximum length of Notes : 1024 characters. comgt doesn\'t handle string overflow Notes : at all. I-Function : htime Description : Returns hundreds of seconds since start of script. Syntax : let x=htime() Notes : Set to a specific value with hset. See Also : hset. I-Function : pid Description : Returns process ID number of current process (comgt) Syntax : let x=pid() See Also : ppid(), fork I-Function : ppid Description : Returns process ID number of parent process. Syntax : let x=ppid() Notes : Can be used by forked child to detect parent Notes : process. I-Function : time Description : Returns time in seconds since Jan 1, 00:00:00 1970 GMT. Syntax : let x=time() Notes : Used to calculate time differences. See Also : $time() I-Function : val Description : Returns value of string. Syntax : let x=val($x) Notes : String is not an expression; must only contain [0-9] Notes : characters. Future versions of comgt will be able to Notes : evaluate expressions. (Maybe) (This was written 6 Notes : years ago.) I-Function : verbose Description : Returns value of verbose setting. Syntax : let x=verbose() Notes : 0=off, 1=on. .nf . .SS String functions .PP .nf S-Function : basename Description : Returns basename part of path. Syntax : let $x=$basename($p) Notes : $basename("/usr/bin/more")="more" See Also : $dirname(). S-Function : baud Description : Returns string representation of current baud rate. Syntax : let $x=$baud() Notes : Defined by "set com" See Also : baud(), set com. S-Function : cwd Description : Returns current working directory pathname. Syntax : let $x=$cwd() See Also : cd. S-Function : dev Description : Returns current communication device pathname. Syntax : let $x=$dev() Notes : defined by "-d" command line argument or "open com" See Also : open com. S-Function : dirname Description : Returns directory name part of path. Syntax : let $x=$dirname($p) Notes : $dirname("/usr/bin/more")="/usr/bin" See Also : $basename(). S-Function : env Description : Returns content of an environment variable Syntax : let $x=$env("HOME") Notes : Non-existant variables return an empty string. See Also : putenv. S-Function : hex Description : Converts value to hexadecimal representation Syntax : let $x=$hex(x) Notes : Letters a-f in lowercase, no preceding "0x" See Also : $hexu(), $oct(). S-Function : hexu Description : Converts value to hexadecimal representation Syntax : let $x=$hex(x) Notes : Letters A-F in uppercase, no preceding "0x" See Also : $hex(), $oct(). S-Function : hms Description : Converts number of seconds into time string Syntax : let $x=$hms(x) Notes : Format is "HH:MM:SS". Useful for chronometer displays Notes : Use with "time()", do not try to increment a variable Notes : every second using "sleep 1". (See ISP script example) Notes : Format becomes "HHH:MM:SS" after 99 hours, 59 minutes, Notes : 59s... See Also : time(). S-Function : left Description : Returns left portion of a string Syntax : let $x=$left($s,l) Notes : $s=Source string, l=length Notes : l must be less than the length of the string. See Also : $right(), $mid(). S-Function : mid Description : Returns midsection of a string. Syntax : let $x=$mid($s,s,l) Notes : $s=Source string, s=start, l=length Notes : s must be less than the length of the string, l can be Notes : some huge number (9999) to return the right side of a Notes : string to the end. the first character of a string is Notes : position 0, not 1. See Also : $right(), $left(). S-Function : oct Description : Converts value to octal representation. Syntax : let $x=$oct(x) See Also : $hex(), $hexu(). S-Function : right Description : Returns right portion of a string. Syntax : let $x=$right($s,l) Notes : $s=Source string, l=length Notes : l must be less than the length of the string. See Also : $left(), $mid(). S-Function : rpipe Description : Returns the first line from a system piped command Syntax : let $x=$rpipe("/bin/ls |grep myfile") Notes : Not very useful unless used with head, tail, grep, Notes : etc... See Also : system. S-Function : time Description : Returns 24 character local time string Syntax : let $x=$time() See Also : time(). Notes : Time is in this format: Mon Apr 8 14:21:22 1996 012345678901234567890123 1 2 S-Function : tolower Description : Returns lowercase\'d string. Syntax : let $x=$tolower($y) S-Function : toupper Description : Returns uppercase\'d string. Syntax : let $x=$toupper($y) .fi . .SS Test operators .PP .nf Operator Description Example Result = equal if 1+2=3 yes != not equal if 1+2!=3 no <> not equal if 1+2<>3 no > Greater than if 1+3>3 yes < Less than if 1+3<3 no >= Greater or equal if 3>=3 yes <= Greater or equal if 2<=3 yes .nf .PP Strings can be compared using the same operators. .PP .nf "aaa" < "aab", "aaaa" > "aaa", "Test" != "test", "One" = "One", "A" > "a", "Fumble" <= "Fumigate", "Farsical" <> "Comedic" .fi .PP .B Note that "set ignorecase on" does NOT apply to string comparisons. . .SS Expression operators .PP .nf Operator Description Example Result + Addition let a=2+2 4 + Concatenation let $b="aa"+"bb" "aabb" - Substraction let e=2-5 -3 * Multiplication let f=11*2 22 / Division let g=34/11 3 & Bit-Wise AND let h=42&7 2 | Bit-Wise OR let a=42|5 47 ^ Bit-Wise XOR let a=42^7 45 .fi .PP Mixed expression examples: .PP .nf #Returns number of seconds since 00:00:00 let $t=$time() #Take a snapshot. let a=(val(mid$($t,11,2))*3600)+(val(mid$($t,14,2))*60)+val(mid$($t,17,2)) #Notice the extra sets of parenthesis because comgt\'s expression #evaluator is brain-dead. #For example, 5-2+1 should give you 4, right? Well, according to #getvalue(), it actually gives 2, because it does it somewhat from #right to left. #So to evaluate 5-2+1 correctly, use (5-2)+1. If you\'re using #simple, two-element calculations, don\'t worry about it. #5-2 will give you 3. .PP #Concatenation (Calls cu) exec "cu -l "+$dev()+" -s "+$baud()" .PP #In a test condition if a+c > strlen($c) goto toomuch .PP #String comparison let $t=$mid($time(),11,8) if $t > "19:59:59" print "Too late for that!\\n" goto toolate if $t < "08:00:00" print "Too early!\\n" goto tooearly if $t = "00:00:00" print "Oh god! It\'s Twinkee time!\\n" .fi . .SH KNOWN "FEATURES" The getvalue() parser. It makes me laugh so I think I\'ll leave it that way. - Daniel.Chouinard@pwc.utc.com . . .SH ENVIRONMENT VARIABLES .PP COMGTPIN - the 4 digit pin of the SIM for use by PIN script COMGTAPN - the APN to write to the data card, used by the APN script. . .SH AUTHORS .PP Daniel.Chouinard wrote the original .B dcon utility. .PP Paul Hardwick updated it for the latest compilers, provided the built-in script functionality and tested it against GPRS and 3G datacards. .PP Martin Gregorie wrote the original manpage for .B comgt from the .B dcon documentation and packaged .B comgt for distribution. . .SS History Daniel Chouinard wrote most (90%) of .B dcon back in 1989 when he started doing Unix Apps tech support mostly by modem to customer systems. He was tired of typing all those passwords and funny call-charging codes everytime he used cu. Also, the company he worked for needed a system that would log call times and estimated costs. Thus .B dcon was born. Six or seven years later (1996) and he was using pppd to connect to his ISP site. He was more or less happy with .B chat but found it lacked flow control and multiple response checks from "atdt...". He wanted it to do different things for "no carrier", "no dial tone", and "busy". Although he thought that .B chat would probably be enhanced someday, when he found dcon.c on one of his old 45M tapes he tried compiling it on his Linux box and, lo and behold, it did. In the end, he added a few things to it (kill, fork, wait, 1/100 sec. times) and left it at that. .PP A couple of years ago Paul Hardwick found the program, .B dcon 0.97, last modified in 1996. The purpose of this program was to run scripts that would control Linux serial ports. The implementation was very similar to something he had written for Windows. Anyway, rather than reinvent he contacted the author, Daniel Chouinard, and asked his permission to reuse the code. Happily he gave permission and a basic but useful utility called .B comgt was created. Paul takes no credit for the engine, apart from making it compatible with todays compilers. It is basically .B dcon repackaged. ./comgt.0.32/comgt.c0000755000175000001440000013005110516161012013036 0ustar paulusers/* * comgt version 0.31 - 3G/GPRS datacard management utility * * Copyright (C) 2003 Paul Hardwick * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * See comgt.doc for more configuration and usage information. * */ /*************************************************************************** * $Id: comgt.c,v 1.4 2006/10/20 14:30:19 pharscape Exp $ ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "comgt.h" #define MAXLABELS 3000 /* Maximum number of labels */ #define MAXGOSUBS 128 /* Max depth */ #define STRINGL 1024 /* String lengths. Also, max script line length */ #define MAXPATH 1024 /* Max filename length (less or equal to STRINGL) */ #define MAXTOKEN 20 /* Maximum token or label length */ #define GTDEVICE "/dev/modem" #define BOOL unsigned char #define NVARS 286 /* a-z, a0-z9 == 26*11 */ extern char *optarg; extern int optind, opterr; FILE *filep; char *script; int scriptspace; BOOL ifres; int lastpc,pc; /* program "counters" */ long resultcode=0; /* result code */ int ignorecase=1; /* no case sensitivity */ BOOL comecho=0; /* echo what's comin' in */ BOOL high_speed=0; long senddelay=0; /* 0/100th second character delay for sending */ long number; /* For getonearg() returning an long */ char **label; /* Index of labels for goto and gosub */ int *labelpc; /* Positions of said labels in script */ int labels; /* Number of labels found in script */ long intvars[NVARS]; /* [a-z][0-9] integer variables */ char string[STRINGL]; /* For getstring() returns and misc. use (misuse) */ char *stringvars[NVARS]; /* $[a-z][0-9] string variables */ char cspeed[10]; /* Ascii representation of baudrate */ int speed=B0; /* Set to B110, B150, B300,..., B38400 */ char device[MAXPATH]; /* Comm device. May be "-" */ char token[MAXTOKEN]; /* For gettoken() returns */ char scriptfile[MAXPATH]; /* Script file name */ char scriptfilepath[MAXPATH]; /* temp storage for full path */ BOOL verbose=0; /* Log actions */ struct termio cons, stbuf, svbuf; /* termios: svbuf=before, stbuf=while */ int comfd=0; /* Communication file descriptor. Defaults to stdin. */ char msg[STRINGL]; /* Massage messages here */ int preturn,returns[MAXGOSUBS]; int clocal=0; int parity=0, bits=CS8, stopbits=0; unsigned long hstart,hset; char NullString[]={ "" }; BOOL lastcharnl=1; /* Indicate that last char printed from getonebyte was a nl, so no new one is needed */ //"open com \"/dev/modem\"\nset com 38400n81\nset senddelay 0.05\nsend \"ATi^m\"\nget 2 \" ^m\" $s\nprint \"Response : \",$s,\"\\n\"\nget 2 \" ^m\" $s\nprint \"Response :\",$s,\"\\n\"\nget 2 \" ^m\" $s\nprint \"Response : \",$s,\"\\n\"\n\n"; /* Prototypes. */ unsigned long htime(void); void dormir(unsigned long microsecs); void dotestkey(void); void ext(long xtc); void vmsg(char *text); void skipline(void); void printwhere(void); void writecom(char *text); int getonebyte(void); void dodump(void); void serror(char *text, int exitcode); void skipspaces(void); void getopen(void); void getclose(void); int gettoken(void); void skiptoken(void); long getvalue(void); void getcomma(void); void gethardstring(void); void getstring(void); unsigned long getdvalue(void); void dolet(void); int dowaitquiet(void); int dowaitfor(void); BOOL getonoroff(void); void setcom(void); void doset(void); void dogoto(void); void dogosub(void); unsigned char getonearg(void); void doif(void); int getindex(void); int getintindex(void); int getstringindex(void); void doget(void); void doprint(int channel); void doclose(void); void opendevice(void); void doopen(void); int doscript(void); char GTdevice[4][20] = {"/dev/noz2", "/dev/ttyUSB2", "/dev/modem",""}; /* default device names to search for */ /* Returns hundreds of seconds */ unsigned long htime(void) { struct timeval timenow; gettimeofday(&timenow,NULL); return(100L*(timenow.tv_sec-hstart)+(timenow.tv_usec)/10000L-hset); } /* I use select() 'cause CX/UX 6.2 doesn't have usleep(). On Linux, usleep() uses select() anyway. */ void dormir(unsigned long microsecs) { struct timeval timeout; timeout.tv_sec=microsecs/1000000L; timeout.tv_usec=microsecs-(timeout.tv_sec*1000000L); select(1,0,0,0,&timeout); } /* Tests for ENTER key */ void dotestkey(void) { fd_set fds; struct timeval timeout; timeout.tv_sec=0L; timeout.tv_usec=10000L; FD_ZERO(&fds); FD_SET(0,&fds); /* Prepare to select() from stdin */ resultcode=select(1,&fds,0,0,&timeout); if(resultcode) getchar(); } /* Exit after resetting terminal settings */ void ext(long xtc) { ioctl(1, TCSETA, &cons); exit(xtc); } /* Log message if verbose is on */ void vmsg(char *text) { time_t t; char *ct; if(verbose) { if(lastcharnl==0) { fprintf(stderr,"\n"); lastcharnl=1; } t=time(0); ct=ctime(&t); fprintf(stderr,"comgt %c%c:%c%c:%c%c -> %s\n", ct[11],ct[12],ct[14],ct[15],ct[17],ct[18], text); } } /* Skip to next statement */ void skipline(void) { while(script[pc]!='\n' && script[pc]!=0) pc++; if(script[pc]) pc++; } void printwhere(void) { int a,b,c; sprintf(msg,"@%04d ",pc); a=pc; skipline(); b=pc-1; pc=a; c=strlen(msg); for(;a "); for(a=6;a' || script[pc]=='!') { token[0]=0; while(script[pc]=='=' || script[pc]=='<' || script[pc]=='>' || script[pc]=='!') { token[tokenp++]=script[pc++]; } token[tokenp]=0; return(0); } if(script[pc]=='#') { strcpy(token,"rem"); pc++; return(0); } if(script[pc]=='/' && script[pc+1]=='/') { strcpy(token,"rem"); pc+=2; return(0); } if(script[pc]==':') { strcpy(token,"label"); pc++; return(0); } while(script[pc]!=' ' && script[pc]!='\n' && script[pc]!='\t' && script[pc]!='(') { token[tokenp]=script[pc++]; if(token[tokenp]>='A' && token[tokenp]<='Z') { token[tokenp]=token[tokenp]-'A'+'a'; } if(tokenp++==MAXTOKEN-1) serror("Token too long",5); } token[tokenp]=0; if(strcmp(token,"then")==0) return(gettoken()); /* Ignore then for if */ return(0); } /* shitfaced recursive value parser. must write better one */ long getvalue(void) { unsigned long p=0; int goone=1; unsigned int a; int base,amode; skipspaces(); if(script[pc]=='(') { pc++; p=getvalue(); getclose(); } else if(script[pc]==')') { return(p); } else if(script[pc]=='"' || script[pc]=='\'' || script[pc]=='$' ) { serror("Did not expect a string",7); } else if( (script[pc]>='a' && script[pc]<='z' && script[pc+1]>='a' && script[pc+1]<='z') || (script[pc]>='A' && script[pc]<='Z' && script[pc+1]>='A' && script[pc+1]<='Z') ) { gettoken(); getopen(); if(strcmp(token,"len")==0) { char toto[STRINGL]; strcpy(toto,string); getstring(); p=strlen(string); strcpy(string,toto); } else if(strcmp(token,"htime")==0) { p=htime(); } else if(strcmp(token,"time")==0) { p=time(0); } else if(strcmp(token,"pid")==0) { p=getpid(); } else if(strcmp(token,"ppid")==0) { p=getppid(); } else if(strcmp(token,"verbose")==0) { p=verbose; } else if(strcmp(token,"isatty")==0) { p=isatty(getvalue()); } else if(strcmp(token,"baud")==0) { p=atol(cspeed); } else if(strcmp(token,"access")==0) { char toto[STRINGL]; char afile[STRINGL]; strcpy(toto,string); getstring(); strcpy(afile,string); getcomma(); getstring(); if(string[0]==0) serror("Missing access mode[s]",5); amode=0; for(a=0;a='a' && script[pc]<='z') || (script[pc]>='A' && script[pc]<='Z') ) { p=intvars[getintindex()]; } else if(script[pc]>='0' && script[pc]<='9') { base=10; if(script[pc]=='0') { base=8; pc++; if(script[pc]=='x' || script[pc]=='X') { base=16; pc++; } if(script[pc]=='%') { base=2; pc++; } } while((script[pc]>='0' && script[pc]<='9') || (script[pc]>='a' && script[pc]<='f') || (script[pc]>='A' && script[pc]<='F')) { if(script[pc]>='a' && script[pc]<='f') { p=p*base+script[pc++]-'a'+10; } else if(script[pc]>='A' && script[pc]<='F') { p=p*base+script[pc++]-'A'+10; } else { p=p*base+script[pc++]-'0'; } } } else { goone=0; } } return(p); } void getcomma(void) { skipspaces(); if(script[pc++]!=',') serror("Comma expected",5); } void gethardstring(void) { int a=0; skipspaces(); while(script[pc]!=0 && script[pc]!=' ' && script[pc]!='\t' && script[pc]!='\n') { string[a++]=script[pc++]; } string[a]=0; } /* Parse a string from script[pc] */ void getstring(void) { FILE *fp; time_t t; unsigned int a,b; int c,p=0; unsigned char ch,match; string[0]=0; skipspaces(); if(script[pc]!='"' && script[pc]!='\'' && script[pc]!='$' ) { serror("Expected a string",7); } while(script[pc]!=' ' && script[pc]!='\t' && script[pc]!='\n' && script[pc]!=',' && script[pc]!=')' && script[pc]!='=' && script[pc]!='<' && script[pc]!='>' && script[pc]!='!' ) { if(script[pc]=='+') pc++; skipspaces(); if( (script[pc]=='$' && script[pc+1]>='a' && script[pc+1]<='z' && script[pc+2]>='a' && script[pc+2]<='z') || (script[pc]=='$' && script[pc+1]>='A' && script[pc+1]<='Z' && script[pc+2]>='A' && script[pc+2]<='Z') ) { pc++; gettoken(); getopen(); if(strcmp(token,"time")==0) { t=time(0); strcat(string,ctime(&t)); string[strlen(string)-1]=0; } else if(strcmp(token,"rpipe")==0) { char toto[STRINGL]; strcpy(toto,string); getstring(); if((fp=popen(string,"r"))==NULL) serror("Could not popen!",4); fgets(string,STRINGL-1,fp); string[strlen(string)-1]=0; pclose(fp); strcat(toto,string); strcpy(string,toto); } else if(strcmp(token,"env")==0) { char toto[STRINGL]; strcpy(toto,string); getstring(); if(getenv(string)) strcat(toto,(char *)getenv(string)); strcpy(string,toto); } else if(strcmp(token,"hms")==0) { long sec,min,hour; sec=getvalue(); min=sec/60L; sec-=min*60L; hour=min/60L; min-=hour*60L; sprintf(string,"%s%02ld:%02ld:%02ld",string,hour,min,sec); } else if(strcmp(token,"dev")==0) { strcat(string,device); } else if(strcmp(token,"cwd")==0) { getcwd(string,STRINGL); } else if(strcmp(token,"baud")==0) { strcat(string,cspeed); } else if(strcmp(token,"str")==0 || strcmp(token,"ltoa")==0) { sprintf(string,"%s%ld",string,getvalue()); } else if(strcmp(token,"hexu")==0) { sprintf(string,"%s%lX",string,getvalue()); } else if(strcmp(token,"hex")==0) { sprintf(string,"%s%lx",string,getvalue()); } else if(strcmp(token,"oct")==0) { sprintf(string,"%s%lo",string,getvalue()); } else if(strcmp(token,"dirname")==0) { char toto[STRINGL]; strcpy(toto,string); getstring(); b=0; for(a=0;a='A' && string[a]<='Z' ) string[a]=string[a]-'A'+'a'; } strcat(toto,string); strcpy(string,toto); } else if(strcmp(token,"toupper")==0) { char toto[STRINGL]; strcpy(toto,string); getstring(); for(a=0;a='a' && string[a]<='z' ) string[a]=string[a]-'a'+'A'; } strcat(toto,string); strcpy(string,toto); } else if(strcmp(token,"basename")==0) { char toto[STRINGL]; strcpy(toto,string); getstring(); b=0; for(a=0;astrlen(string)) serror("String is shorter than second argument",7); c=strlen(toto); a=strlen(string)-b; while(b!=0 && string[a]!=0) { toto[c++]=string[a++]; b--; } toto[c]=0; strcpy(string,toto); } else if(strcmp(token,"left")==0) { char toto[STRINGL]; strcpy(toto,string); getstring(); getcomma(); b=getvalue(); if(b>strlen(string)) serror("String is shorter than second argument",7); c=strlen(toto); a=0; while(b!=0 && string[a]!=0) { toto[c++]=string[a++]; b--; } toto[c]=0; strcpy(string,toto); } else if(strcmp(token,"mid")==0) { char toto[STRINGL]; strcpy(toto,string); getstring(); getcomma(); a=getvalue(); getcomma(); b=getvalue(); if(a>strlen(string)) serror("String is shorter than second argument",7); c=strlen(toto); while(b!=0 && string[a]!=0) { toto[c++]=string[a++]; b--; } toto[c]=0; strcpy(string,toto); } else if(strcmp(token,"sex")==0) { strcat(string,"You're a naughty boy, you!"); } else serror("Invalid string funtion",5); getclose(); } else if(script[pc]=='$') { strcat(string,stringvars[getstringindex()]); } else if(script[pc]=='"' || script[pc]=='\'') { match=script[pc++]; while(script[pc]!=match) { ch=script[pc++]; if(ch==0) serror("Umatched quote.",5); if(ch=='\\') { if(script[pc]<='7' && script[pc]>='0' && script[pc+1]<='7' && script[pc+1]>='0' ) { ch=0; while(script[pc]>='0' && script[pc]<='7') { ch=8*ch+script[pc++]-'0'; } } else { switch(script[pc]) { case 'T' : case 't' : ch=9; break; case 'R' : case 'r' : ch=13; break; case 'N' : case 'n' : ch=10; break; case 'B' : case 'b' : ch=8; break; case 'F' : case 'f' : ch=12; break; case '"' : case '^' : case '\'' : case '\\' : ch=script[pc]; break; default : serror("Malformed escaped character",5); } pc++; } } else if(ch=='^') { ch=script[pc]; if(ch!='^' && ch!='"' && ch!='\'' && ch!='\\' ) { ch=ch&31; /* Control char */ } pc++; } p=strlen(string); string[p++]=ch; string[p]=0; } pc++; /* Space over quote */ } else { p=strlen(string); string[p++]=script[pc++]; string[p]=0; } } } /* Get a value, multiply by a hundred (for time values) */ unsigned long getdvalue(void) { float f; gettoken(); skipspaces(); sscanf(token,"%f",&f); f+=0.00001; /* Rounding errors */ return(100.0*f); } void dolet(void) { int index; BOOL svar=0; skipspaces(); if(script[pc]=='$') { svar=1; index=getstringindex(); } else index=getintindex(); skipspaces(); gettoken(); if(strcmp(token,"=")!=0) serror("Bad LET assignment, '=' missing",5); skipspaces(); if(svar) { getstring(); strcpy(stringvars[index],string); } else { intvars[index]=getvalue(); } } /* See documentation for doXXX() functions */ int dowaitquiet(void) { unsigned long timeout,timequiet,quiet,now; int c,quit; timeout=htime()+getdvalue(); quiet=getdvalue(); timequiet=htime()+quiet; quit=1; while(quit==1) { now=htime(); c=getonebyte(); if(c!= -1) timequiet=now+quiet; if(now>=timequiet) quit=0; if(now>=timeout) quit=255; } return(quit); } int dowaitfor(void) { char strings[20][80]; char buffer[128]; unsigned long timeout; unsigned int a; int b,c; b=0; buffer[127]=0; skipspaces(); timeout=htime()+getdvalue(); while(script[pc]==',' || script[pc]=='$' || script[pc]=='"' || script[pc]=='\'' ) { if(script[pc]==',') pc++; getstring(); skipspaces(); strcpy(strings[b],string); if(ignorecase) { for(a=0;a='A' && strings[b][a]<='Z') { strings[b][a]=strings[b][a]-'A'+'a'; } } } b++; } strings[b][0]=0; while(htime()='A' && c<='Z') c=c-'A'+'a'; } for(a=0;a<127;a++) buffer[a]=buffer[a+1]; //shuffle down buffer[126]=c; b=0; while(strings[b][0]) { c=strlen(strings[b]); if (strcmp(strings[b],&buffer[127-c]) == 0){ return(b); } b++; } } } return(-1); } /* Parse script for "on" or "off" wich are tokens, not strings */ BOOL getonoroff(void) { int a,b; b=pc; gettoken(); if(strcmp(token,"on")==0) return(1); if(strcmp(token,"off")==0) return(0); pc=b; a=getvalue(); if(a!=0 && a!=1) serror("Bad value (should be on or off, 1 or 0.)",5); return(a); } void setcom(void) { stbuf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | CLOCAL | PARENB); stbuf.c_cflag |= (speed | bits | CREAD | clocal | parity | stopbits ); if (ioctl(comfd, TCSETA, &stbuf) < 0) { serror("Can't ioctl set device",1); } } void doset(void) { struct termio console; int a,b; gettoken(); if(strcmp(token,"echo")==0) { a=0; if(getonoroff()) a=ECHO|ECHOE; if(ioctl(0, TCGETA, &console)<0) { serror("Can't ioctl FD zero!\n",2); } console.c_lflag &= ~(ECHO | ECHOE); console.c_lflag |= a; ioctl(0, TCSETA, &console); } else if(strcmp(token,"senddelay")==0) { senddelay=10000L*getdvalue(); } else if(strcmp(token,"clocal")==0) { clocal=0; if(getonoroff()) clocal=CLOCAL; setcom(); } else if(strcmp(token,"umask")==0) { umask(getvalue()&0777); } else if(strcmp(token,"verbose")==0) { verbose=getonoroff(); } else if(strcmp(token,"comecho")==0) { comecho=getonoroff(); } else if(strcmp(token,"ignorecase")==0) { ignorecase=getonoroff(); } else if(strcmp(token,"com")==0) { skipspaces(); if(script[pc]=='$' || script[pc]=='\'' || script[pc]=='"') { getstring(); strcpy(token,string); } else gettoken(); a=0; b=0; while(token[b]>='0' && token[b]<='9') { a=10*a+token[b++]-'0'; } if(token[b]) { switch(token[b]) { case 'n': parity=0; break; case 'e': parity=PARENB; break; case 'o': parity=PARENB|PARODD; break; default : serror("Parity can only ben E, N, or O",5); } b++; if(token[b]) { switch(token[b]) { case '5' : bits=CS5; break; case '6' : bits=CS6; break; case '7' : bits=CS7; break; case '8' : bits=CS8; break; default : serror("Bits can only be 5, 6, 7, or 8",5); } b++; if(token[b]) { switch(token[b]) { case '1': stopbits=0; break; case '2': stopbits=CSTOPB; break; default : serror("Stop bits can only be 1 or 2",5); } } } } sprintf(cspeed,"%d",a); switch(a) { case 0: speed = B0;break; case 50: speed = B50;break; case 75: speed = B75;break; case 110: speed = B110;break; case 150: speed = B150;break; case 300: speed = B300;break; case 600: speed = B600;break; case 1200: speed = B1200;break; case 2400: speed = B2400;break; case 4800: speed = B4800;break; case 9600: speed = B9600;break; case 19200: speed = B19200;break; case 38400: speed = B38400;break; case 57600: speed = B57600;break; case 115200: { if(high_speed == 0) speed = B115200; else speed = B57600; break; } case 460800: speed = B460800; break; default: serror("Invalid baudrate",1); } setcom(); } } void dogoto(void) { int a,originalpos; originalpos=pc; gettoken(); for(a=0;a=labels) { pc=originalpos; sprintf(msg,"Label \"%s\" not found",token); serror(msg,5); } else { pc=labelpc[a]; } } void dogosub(void) { int a; if(preturn==MAXGOSUBS) serror("Reached maximum GOSUB depth",3); a=pc; gettoken(); returns[preturn++]=pc; pc=a; dogoto(); } /* Gets arguments and returns 0 for a string, 1 for an int. Used with if */ BOOL getonearg(void) { if(script[pc]=='"' || script[pc]=='\'' || script[pc]=='$' ) { getstring(); return(0); } else { number=getvalue(); return(1); } } void doif(void) { char stringarg[STRINGL]; char tokencopy[MAXTOKEN]; int intarg; skipspaces(); ifres=0; if(getonearg()) { intarg=number; gettoken(); skipspaces(); if(getonearg()!=1) serror("Comparison mis-match",7); if(strcmp(token,"<")==0) { if(intarg")==0) { if(intarg>number) ifres=1; } else if(strcmp(token,">=")==0) { if(intarg>=number) ifres=1; } else if(strcmp(token,"<>")==0) { if(intarg!=number) ifres=1; } else if(strcmp(token,"!=")==0 || strcmp(token,"<>")==0) { if(intarg!=number) ifres=1; } } else { strcpy(stringarg,string); gettoken(); strcpy(tokencopy,token); skipspaces(); if(getonearg()!=0) serror("Comparison mis-match",7); if(strcmp(tokencopy,"<")==0) { if(strcmp(stringarg,string)<0) ifres=1; } if(strcmp(tokencopy,"<=")==0) { if(strcmp(stringarg,string)<=0) ifres=1; } else if(strcmp(tokencopy,"=")==0) { if(strcmp(stringarg,string)==0) ifres=1; } else if(strcmp(tokencopy,">")==0) { if(strcmp(stringarg,string)>0) ifres=1; } else if(strcmp(tokencopy,">=")==0) { if(strcmp(stringarg,string)>=0) ifres=1; } else if(strcmp(tokencopy,"!=")==0 || strcmp(tokencopy,"<>")==0) { if(strcmp(stringarg,string)!=0) ifres=1; } } if(!ifres) skipline(); } int getindex(void) { int index; index=script[pc++]; if(index>='A' && index<='Z') index=index-'A'+'a'; if(index>'z' || index<'a') serror("Malformed variable name",7); index=index-'a'; if(script[pc]>='0' && script[pc]<='9') { index=index+(1+script[pc++]-'0')*26; } return(index); } /* Parse script to find integer variable index */ int getintindex(void) { skipspaces(); if(script[pc]=='$') serror("Integer variable expected",7); return(getindex()); } /* Parse script to find string variable index and allocate memory for storage as needed. */ int getstringindex(void) { int index; skipspaces(); if(script[pc++]!='$') serror("String variable expected",7); index=getindex(); if(stringvars[index]==NullString) { stringvars[index]=(char *)malloc(STRINGL); if(stringvars[index]==NULL) serror("Could not malloc",3); stringvars[index][0]=0; } return(index); } void doget(void) { char terminators[STRINGL]; unsigned int a; int b,c,index; int goahead=1; unsigned long timeout; timeout=htime()+getdvalue(); getstring(); strcpy(terminators,string); index=getstringindex(); string[0]=0; b=0; resultcode=0; while(goahead && htime()= 0)break; dcount++; }while(strlen(GTdevice[dcount])); if (comfd < 0){ printf("Unable to locate default devices, try the -d option.\n"); ext(1); } } else { if ((comfd = open(device, O_RDWR|O_EXCL|O_NONBLOCK|O_NOCTTY)) <0) { //O_NONBLOCK|O_NOCTTY)) <0) {// sprintf(msg,"Can't open device %s.\n",device); printf(msg); ext(1); } } if (ioctl (comfd, TCGETA, &svbuf) < 0) { sprintf(msg,"Can't control %s, please try again.\n",device); serror(msg,1); } setenv("COMGTDEVICE",device,1); ioctl(comfd, TCGETA, &stbuf); speed=stbuf.c_cflag & CBAUD; if (high_speed == 0) strcpy(cspeed,"115200"); else strcpy(cspeed,"57600"); bits=stbuf.c_cflag & CSIZE; clocal=stbuf.c_cflag & CLOCAL; stopbits=stbuf.c_cflag & CSTOPB; parity=stbuf.c_cflag & (PARENB | PARODD); stbuf.c_iflag &= ~(IGNCR | ICRNL | IUCLC | INPCK | IXON | IXANY | IGNPAR ); stbuf.c_oflag &= ~(OPOST | OLCUC | OCRNL | ONLCR | ONLRET); stbuf.c_lflag &= ~(ICANON | XCASE | ECHO | ECHOE | ECHONL); stbuf.c_lflag &= ~(ECHO | ECHOE); stbuf.c_cc[VMIN] = 1; stbuf.c_cc[VTIME] = 0; stbuf.c_cc[VEOF] = 1; setcom(); dormir(200000); /* Wait a bit (DTR raise) */ sprintf(msg,"Opened %s as FD %d",device,comfd); vmsg(msg); } void opendevice(void) { if(strcmp(device,"-")!=0) { if ((comfd = open(device, O_RDWR|O_EXCL|O_NONBLOCK|O_NOCTTY)) <0) { //O_NONBLOCK|O_NOCTTY)) <0) {// sprintf(msg,"Can't open device %s.\n",device); printf(msg); ext(1); } } else comfd=0; if (ioctl (comfd, TCGETA, &svbuf) < 0) { sprintf(msg,"Can't ioctl get device %s.\n",device); serror(msg,1); } ioctl(comfd, TCGETA, &stbuf); speed=stbuf.c_cflag & CBAUD; switch(speed) { case B0: strcpy(cspeed,"0");break; case B50: strcpy(cspeed,"50");break; case B75: strcpy(cspeed,"75");break; case B110: strcpy(cspeed,"110");break; case B300: strcpy(cspeed,"300");break; case B600: strcpy(cspeed,"600");break; case B1200: strcpy(cspeed,"1200");break; case B2400: strcpy(cspeed,"2400");break; case B4800: strcpy(cspeed,"4800");break; case B9600: strcpy(cspeed,"9600");break; case B19200: strcpy(cspeed,"19200");break; case B38400: strcpy(cspeed,"38400");break; case B115200: { if (high_speed == 0) strcpy(cspeed,"115200"); else strcpy(cspeed,"57600"); break; } case B460800: strcpy(cspeed, "460800");break; } bits=stbuf.c_cflag & CSIZE; clocal=stbuf.c_cflag & CLOCAL; stopbits=stbuf.c_cflag & CSTOPB; parity=stbuf.c_cflag & (PARENB | PARODD); stbuf.c_iflag &= ~(IGNCR | ICRNL | IUCLC | INPCK | IXON | IXANY | IGNPAR ); stbuf.c_oflag &= ~(OPOST | OLCUC | OCRNL | ONLCR | ONLRET); stbuf.c_lflag &= ~(ICANON | XCASE | ECHO | ECHOE | ECHONL); stbuf.c_lflag &= ~(ECHO | ECHOE); stbuf.c_cc[VMIN] = 1; stbuf.c_cc[VTIME] = 0; stbuf.c_cc[VEOF] = 1; setcom(); dormir(200000); /* Wait a bit (DTR raise) */ sprintf(msg,"Opened %s as FD %d",device,comfd); vmsg(msg); } void doopen(void) { gettoken(); if(strcmp(token,"com")==0) { skipspaces(); if(script[pc]=='$' || script[pc]=='\'' || script[pc]=='"') { getstring(); } else gethardstring(); strcpy(device,string); opendevice(); } else if (strcmp(token,"file")==0) { if(filep!=NULL) serror("File already open",4); getstring(); if((filep=fopen(string,"a"))==NULL) serror("Could not open file",4); } else serror("OPEN only takes com or file argument",5); } int doscript(void) { int a,b; int exitcode=0; char line[STRINGL]; pc=0; while(script[pc]) { if(script[pc]=='\n') pc++; lastpc=pc; skipspaces(); if(verbose) printwhere(); if(gettoken()) serror("Could not gettoken()",5); if(strcmp(token,"rem")==0) { skipline(); } else if (strcmp(token,"label")==0) { skiptoken(); /* Get rid of keyword */ } else if(strcmp(token,"open")==0) { doopen(); } else if(strcmp(token,"opengt")==0) { opengt(); } else if(strcmp(token,"close")==0) { doclose(); } else if(strcmp(token,"exec")==0) { getstring(); strcpy(msg,"exec "); strcat(msg,string); /* Let sh do all the command line work! */ execl("/bin/sh","sh","-c",msg,(char *)0); serror("Could not execl /bin/sh!",8); } else if(strcmp(token,"exit")==0) { ext(getvalue()); } else if(strcmp(token,"testkey")==0) { dotestkey(); } else if(strcmp(token,"kill")==0) { a=getvalue(); resultcode=kill(getvalue(),a); } else if(strcmp(token,"fork")==0) { resultcode=fork(); } else if(strcmp(token,"hset")==0) { hset=0; hstart=time(0); hset=htime()-getvalue(); } else if(strcmp(token,"cd")==0) { getstring(); resultcode=chdir(string); } else if(strcmp(token,"putenv")==0) { getstring(); strcpy(line,string); resultcode=putenv(line); /* putenv can't read from global string[] */ } else if(strcmp(token,"wait")==0) { resultcode=wait(0); } else if(strcmp(token,"system")==0) { getstring(); system(string); } else if(strcmp(token,"input")==0) { FILE *infd = fdopen(0,"r"); fgets(stringvars[getstringindex()],1024,infd); //fclose(infd); } else if(strcmp(token,"get")==0) { doget(); } else if(strcmp(token,"print")==0) { doprint(1); } else if(strcmp(token,"eprint")==0) { doprint(2); } else if(strcmp(token,"lprint")==0) { doprint(3); } else if(strcmp(token,"fprint")==0) { doprint(4); } else if(strcmp(token,"if")==0) { doif(); } else if(strcmp(token,"else")==0) { if(ifres) skipline(); } else if(strcmp(token,"gosub")==0) { dogosub(); } else if(strcmp(token,"return")==0) { if(preturn==0) serror("RETURN without gosub",5); pc=returns[--preturn]; } else if(strcmp(token,"goto")==0) { dogoto(); } else if(strcmp(token,"waitfor")==0) { resultcode=dowaitfor(); } else if(strcmp(token,"waitquiet")==0) { resultcode=dowaitquiet(); } else if(strcmp(token,"set")==0) { doset(); } else if(strcmp(token,"dec")==0) { intvars[getintindex()]--; } else if(strcmp(token,"inc")==0) { intvars[getintindex()]++; } else if(strcmp(token,"let")==0) { dolet(); } else if(strcmp(token,"dump")==0) { dodump(); } else if(strcmp(token,"abort")==0) { vmsg("Aborting"); abort(); } else if(strcmp(token,"send")==0) { getstring(); writecom(string); } else if(strcmp(token,"flash")==0) { b=speed; speed=0; setcom(); a=getdvalue(); dormir(10000L*a); speed=b; setcom(); } else if(strcmp(token,"sleep")==0) { a=getdvalue(); if(a<10000) dormir(10000L*a); else sleep(a/100); /* I guess it's the same. Oh well, past 100 secs, use sleep instead. */ } else { /* Humour is the spice of life. */ switch(time(0)&7) { case 0 : serror("That's human mumbo-jumbo to me",5); break; case 1 : serror("Lovely but incomprehensible",5); break; case 2 : serror("What's that, governor?",5); break; case 3 : serror("Very funny. I don't get it",5); break; case 4 : serror("Huh?",5); break; case 5 : serror("comgt doesn't speak spanish",5); break; case 6 : serror("Mais, qu'est-ce que vous dites?",5); break; default: serror("%E-6837-% : Corrupted human data detected",5); break; } } skipspaces(); while(script[pc]=='\n') pc++; } return(exitcode); } int main(int argc,char **argv) { unsigned int a; int aa,b,i,skip_default; unsigned char ch; unsigned char terminator='\n'; char *devenv,line[STRINGL]; //Load up the COMGT device env variable if it exists devenv = getenv("COMGTDEVICE"); if (devenv != NULL && strlen(devenv)){ strcpy(device,devenv); } else strcpy(device,"-"); FILE *fp; hstart=time(0); hset=htime(); preturn=0; skip_default=0; filep=NULL; scriptspace=4096; ioctl(1, TCGETA, &cons); if((script=( char *)malloc(scriptspace))==NULL) { serror("Could not malloc()",3); } for(a=0;a * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ***************************************************************************/ /*************************************************************************** * $Id: comgt.h,v 1.4 2006/10/20 14:30:19 pharscape Exp $ ****************************************************************************/ #define COMGT_VERSION "0.32" #define YEARS "2005,2006" char _default_code[] = "opengt\n\ set com 115200n81\n\ set senddelay 0.05\n\ send \"AT+CFUN=1^m\"\n\ waitquiet 1 0.2\n\ :start\n\ flash 0.1\n\ send \"AT+CPIN?^m\"\n\ waitfor 30 \"SIM PUK\",\"SIM PIN\",\"READY\",\"ERROR\",\"ERR\"\n\ if % = -1 goto error\n\ if % = 0 goto ready\n\ if % = 1 goto getpin\n\ if % = 2 goto ready\n\ if % = 3 goto error\n\ if % = 4 goto error\n\ :error\n\ print $s,\" ***SIM ERROR***\n\"\n\ print \"Check device port configuration.\nCheck SIM is inserted\nTest SIM in a mobile phone?\n\"\n\ exit 1\n\ :getpin\n\ #handle case where original Vodafone 3G generates wrong response\n\ waitfor 1 \"2\"\n\ if % = 0 goto ready\n\ print \"\nEnter PIN number: \"\n\ input $x\n\ let a=len($x)\n\ if a<>5 goto getpin\n\ let c=0\n\ :test\n\ let $c=$mid($x,c,1)\n\ if $c<\"0\" goto getpin\n\ if $c>\"9\" goto getpin\n\ inc c\n\ if c<4 goto test\n\ let a=val($x)\n\ if a<0 goto getpin\n\ if a>9999 goto getpin\n\ let $c=$left($x,4)\n\ :enterpin\n\ send \"AT+CPIN=\\\"\"\n\ send $c\n\ send \"\\\"^m\"\n\ waitfor 20 \"OK\",\"ERR\"\n\ if % = -1 goto timeerror\n\ if % = 0 goto cont\n\ if % = 1 goto pinerror\n\ :pinerror\n\ :timeerror\n\ print \"ERROR entering PIN code\n\"\n\ print \"Caution! - entering the wrong PIN code three times will lock the SIM\n\"\n\ exit 1\n\ :ready\n\ print \"SIM ready\n\"\n\ :cont\n\ print \"Waiting for Registration..(120 sec max)\"\n\ let c = 0\n\ :waitreg\n\ send \"AT+CREG?^m\"\n\ waitfor 2 \"+CREG: 0,1\",\"+CREG: 0,5\"\n\ if % = -1 goto regagain\n\ if % = 0 goto homereg\n\ if % = 1 goto roamreg\n\ :regagain\n\ if c > 120 goto regtimeout\n\ let c=c+2\n\ print \".\"\n\ goto waitreg\n\ :regtimeout\n\ print \"\nFailed to register\n\"\n\ exit 1\n\ :homereg\n\ print \"\nRegistered on Home network: \"\n\ goto registered\n\ :roamreg\n\ print \"\nRegistered on Roaming network: \"\n\ goto registered\n\ :registered\n\ waitquiet 1 0.1\n\ send \"AT+COPS?^m\"\n\ get 2 \"^m\" $s\n\ get 2 \"^m\" $s\n\ let a=len($s)\n\ let b=a-12\n\ if b < 1 goto regtimeout\n\ let $c=$right($s,b)\n\ print $c,\"\n\"\n\ let c=0\n\ :signal\n\ waitquiet 1 0.1\n\ send \"AT+CSQ^m\"\n\ get 2 \"^m\" $s\n\ get 2 \"^m\" $s\n\ let a=len($s)\n\ let a=a-6\n\ let $s=$right($s,a)\n\ if $s <> \"0,0\" goto sigcont\n\ if c > 3 goto sigexit\n\ let c=c+1\n\ pause 1\n\ goto signal\n\ :sigexit\n\ print \"Signal strength measure 0,0 too low!\"\n\ exit 1\n\ :sigcont\n\ print \"Signal Quality:\",$s,\"\\n\"\n\ waitquiet 1 0.1\n"; char _info_code[] = "print \"##### Wireless WAN Modem Configuration #####\\n\"\n\ opengt\n\ set com 115200n81\n\ set senddelay 0.05\n\ waitquiet 2 0.5\n\ :name\n\ print \"Product text:\n====\n\"\n\ send \"ATi^m\"\n\ get 1 \" ^m\" $s\n\ :more\n\ get 1 \"^m\" $s\n\ let x=len($s)\n\ if $s=\"OK\n\" goto manf\n\ #dump\n\ if x<1 goto manf\n\ if $s=\"\n\" goto more\n\ print $s\n\ goto more\n\ :manf\n\ print \"\n====\n\"\n\ waitquiet 2 0.1\n\ print \"Manufacturer: \"\n\ send \"AT+cgmi^m\"\n\ get 1 \"^m\" $s\n\ get 1 \"^m\" $s\n\ let x=len($s)\n\ if x<1 goto imei_serial\n\ dec x\n\ let $s=$right($s,x)\n\ print $s,\"\\n\"\n\ :imei_serial\n\ waitquiet 5 0.1\n\ print \"IMEI and Serial Number: \"\n\ send \"AT+GSN^m\"\n\ get 2 \"^m\" $s\n\ get 2 \"^m\" $s\n\ let x=len($s)\n\ dec x\n\ let $s=$right($s,x)\n\ print ,$s,\"\\n\"\n\ :firmware\n\ waitquiet 5 0.1\n\ print \"Manufacturer\'s Revision: \"\n\ send \"AT+GMR^m\"\n\ get 2 \"^m\" $s\n\ get 2 \"^m\" $s\n\ let x=len($s)\n\ dec x\n\ dec x\n\ let $s=$left($s,x)\n\ print $s,\"\\n\"\n\ :hardware\n\ waitquiet 5 0.1\n\ print \"Hardware Revision: \"\n\ send \"AT_OHWV^m\"\n\ get 2 \" ^m\" $s\n\ get 2 \" ^m\" $s\n\ get 2 \" ^m\" $s\n\ print $s,\"\\n\"\n\ :networklock\n\ waitquiet 5 0.1\n\ print \"Network Locked: \"\n\ send \"AT+clck=\\\"PN\\\",2^m\"\n\ get 2 \" ^m\" $s\n\ get 2 \" ^m\" $s\n\ get 2 \" ^m\" $s\n\ print $s,\"\\n\"\n\ waitquiet 5 0.1\n\ :customized\n\ print \"Customisation: \"\n\ send \"AT_ocst^m\"\n\ get 2 \" ^m\" $s\n\ get 2 \" ^m\" $s\n\ get 2 \",^m\" $s\n\ print $s,\"\\n\"\n\ :bandsettings\n\ waitquiet 5 0.1\n\ print \"Band settings: \"\n\ send \"AT_OSBM?^m\"\n\ get 2 \" ^m\" $s\n\ get 2 \" ^m\" $s\n\ get 2 \" ^m\" $s\n\ if $s=\"4\" print \"Europe 900/1800MHz \"\n\ if $s=\"5\" print \"USA 900/1900MHz \"\n\ print \"(\",$s,\")\\n\" \n\ :apn\n\ waitquiet 5 0.1\n\ print \"APN: \"\n\ send \"AT+CGDCONT?^m\"\n\ get 2 \" ^m\" $s\n\ get 2 \" ^m\" $s\n\ get 2 \" ^m\" $s\n\ print $s,\"\\n\" \n\ waitquiet 5 0.1 \n\ print \"##### END #####\\n\"" ; char _USA_code[]= "print \"##### Band Change to USA operation #####\\n\"\n\ opengt\n\ set com 115200n81\n\ set senddelay 0.05\n\ waitquiet 2 0.5\n\ send \"AT_OSBM=5^m\"\n\ waitfor 10 \"OK\",\"ERR\"\n\ if % = -1 goto timeout\n\ if % = 0 goto cont\n\ if % = 1 goto error\n\ :timeout\n\ print \"Timeout Error communicating with device.\n\"\n\ exit 1\n\ :error\n\ print \"Error response from device.\n\"\n\ exit 1\n\ :cont\n\ print \"Complete\\n\"\n"; char _Europe_code[] = "print \"##### Band Change to European operation #####\\n\"\n\ opengt\n\ set com 115200n81\n\ set senddelay 0.05\n\ waitquiet 2 0.5\n\ send \"AT_OSBM=4^m\"\n\ waitfor 10 \"OK\",\"ERR\"\n\ if % = -1 goto timeout\n\ if % = 0 goto cont\n\ if % = 1 goto error\n\ :timeout\n\ print \"Timeout Error communicating with device.\n\"\n\ exit 1\n\ :error\n\ print \"Error response from device.\n\"\n\ exit 1\n\ :cont\n\ print \"Complete\\n\"\n"; char _sig_code[] = "opengt\n\ set com 115200n81\n\ set senddelay 0.05\n\ waitquiet 2 0.5\n\ let c=0\n\ :signal\n\ waitquiet 1 0.1\n\ send \"AT+CSQ^m\"\n\ get 2 \"^m\" $s\n\ get 2 \"^m\" $s\n\ let a=len($s)\n\ let a=a-6\n\ let $s=$right($s,a)\n\ if $s <> \"0,0\" goto sigcont\n\ if c > 3 goto sigexit\n\ let c=c+1\n\ pause 1\n\ goto signal\n\ :sigexit\n\ print \"Signal strength measure 0,0 too low!\"\n\ exit 1\n\ :sigcont\n\ print \"Signal Quality:\",$s,\"\\n\"\n\ waitquiet 1 0.1\n\ exit 0\n"; char _reg_code[] = "opengt\n\ set com 115200n81\n\ set senddelay 0.05\n\ waitquiet 2 0.5\n\ print \"Waiting for Registration\"\n\ let c = 0\n\ :waitreg\n\ send \"AT+CREG?^m\"\n\ waitfor 2 \"+CREG: 0,1\",\"+CREG: 0,5\"\n\ if % = -1 goto regagain\n\ if % = 0 goto homereg\n\ if % = 1 goto roamreg\n\ :regagain\n\ if c > 120 goto regtimeout\n\ let c=c+2\n\ print \".\"\n\ goto waitreg\n\ :regtimeout\n\ print \"\nFailed to register\n\"\n\ exit 1\n\ :homereg\n\ print \"\nRegistered on Home network: \"\n\ goto registered\n\ :roamreg\n\ print \"\nRegistered on Roaming network: \"\n\ goto registered\n\ :registered\n\ waitquiet 1 0.1\n\ send \"AT+COPS?^m\"\n\ get 2 \"^m\" $s\n\ get 2 \"^m\" $s\n\ let a=len($s)\n\ let b=a-12\n\ if b < 1 goto regtimeout\n\ let $c=$right($s,b)\n\ print $c,\"\n\"\n"; char _3G2G_mode_code[] = "opengt\n\ set com 115200n81\n\ set senddelay 0.05\n\ waitquiet 1 0.2\n\ send \"AT_OPSYS=3^m\"\n\ waitfor 10 \"OK\",\"ERR\"\n\ if % = -1 goto timeout\n\ if % = 0 goto cont\n\ if % = 1 goto error\n\ :timeout\n\ print \"Timeout Error communicating with device.\n\"\n\ exit 1\n\ :error\n\ print \"Error response from device.\n\"\n\ exit 1\n\ :cont\n\ print \"Set 3G preferred mode\\n\"\n"; char _3G_mode_code[] = "opengt\n\ set com 115200n81\n\ set senddelay 0.05\n\ waitquiet 1 0.2\n\ send \"AT_OPSYS=1^m\"\n\ waitfor 10 \"OK\",\"ERR\"\n\ if % = -1 goto timeout\n\ if % = 0 goto cont\n\ if % = 1 goto error\n\ :timeout\n\ print \"Timeout Error communicating with device.\n\"\n\ exit 1\n\ :error\n\ print \"Error response from device.\n\"\n\ exit 1\n\ :cont\n\ print \"Set 3G only mode\\n\"\n"; char _2G_mode_code[] = "opengt\n\ set com 115200n81\n\ set senddelay 0.05\n\ waitquiet 1 0.2\n\ send \"AT_OPSYS=0^m\"\n\ waitfor 10 \"OK\",\"ERR\"\n\ if % = -1 goto timeout\n\ if % = 0 goto cont\n\ if % = 1 goto error\n\ :timeout\n\ print \"Timeout Error communicating with device.\n\"\n\ exit 1\n\ :error\n\ print \"Error response from device.\n\"\n\ exit 1\n\ :cont\n\ print \"Set 2G only mode\\n\"\n"; char _GTEDGE_code[] = "opengt\n\ set com 57600n81\n\ send \"AT+CFUN=1^m\"\n\ waitquiet 5 0.2"; char _SETPIN_code[]= "opengt\n\ set com 115200n81\n\ set senddelay 0.05\n\ waitquiet 1 0.2\n\ :start\n\ flash 0.1\n\ send \"AT+CPIN?^m\"\n\ waitfor 30 \"SIM PUK\",\"SIM PIN\",\"READY\",\"ERROR\",\"ERR\"\n\ if % = -1 goto error\n\ if % = 0 goto ready\n\ if % = 1 goto getpin\n\ if % = 2 goto ready\n\ if % = 3 goto error\n\ if % = 4 goto error\n\ :error\n\ print $s,\" ***SIM ERROR***\n\"\n\ print \"Check device port configuration.\nCheck SIM is inserted\nTest SIM in a mobile phone?\n\"\n\ exit 1\n\ :getpin\n\ #handle case where original Vodafone 3G generates wrong response\n\ let $x=$env(\"COMGTPIN\")\n\ let a=len($x)\n\ if a=0 goto pinenverr\n\ if a<>4 goto pinerror\n\ let c=0\n\ :test\n\ let $c=$mid($x,c,1)\n\ if $c<\"0\" goto pinerror\n\ if $c>\"9\" goto pinerror\n\ inc c\n\ if c<4 goto test\n\ let a=val($x)\n\ if a<0 goto pinerror\n\ if a>9999 goto pinerror\n\ let $c=$left($x,4)\n\ :enterpin\n\ send \"AT+CPIN=\\\"\"\n\ send $c\n\ send \"\\\"^m\"\n\ waitfor 20 \"OK\",\"ERR\"\n\ if % = -1 goto timeerror\n\ if % = 0 goto ready\n\ if % = 1 goto pinerror\n\ :pinenverr\n\ print \"ERROR: The COMGTPIN env variable is not set\n\"\n\ exit 1\n\ :pinerror\n\ print \"ERROR: PIN code must be 4 decimal digits only\n\"\n\ print \"Caution! - entering the wrong PIN code three times will lock the SIM\n\"\n\ exit 1\n\ :timeerror\n\ print \"ERROR: timeout, device did not respond to PIN command entry.\n\"\n\ exit 1\n\ :ready\n\ print \"SIM ready\n\"\n"; char _SETAPN_code[]= "opengt\n\ set com 115200n81\n\ set senddelay 0.05\n\ waitquiet 1 0.2\n\ :start\n\ flash 0.1\n\ :getapn\n\ let $x=$env(\"COMGTAPN\")\n\ let a=len($x)\n\ if a=0 goto apnerror\n\ if a>32 goto apnerror\n\ :enterapn\n\ send \"AT+CGDCONT=1,\\\"IP\\\",\\\"\n\ send $c\n\ send \"\\\"^m\"\n\ waitfor 20 \"OK\",\"ERR\"\n\ if % = -1 goto timeerror\n\ if % = 0 goto OK\n\ if % = 1 goto apnerror\n\ :apnerror\n\ print \"ERROR entering APN\n\"\n\ print \"The COMGTAPN env variable is not set\n\"\n\ exit 1\n\ :timeerror\n\ print \"ERROR entering APN\n\"\n\ print \"The device timeout.\n\"\n\ exit 1\n\ :OK\n\ exit 0\n"; char _help_code[] =\ "print \"comgt Usage: \"\n\ print \"comgt [options] [built in script]'|[external script]\n\n\"\n\ print \"Built in scripts -\n\"\n\ print \" comgt [default] Checks SIM status (requests PIN if required),\n\"\n\ print \" registration and signal strength reported by\n\"\n\ print \" datacard.\n\"\n\ print \" comgt info Display configuration of datacard.\n\"\n\ print \" comgt sig Report Signal strength.\n\"\n\ print \" comgt reg Report Registration status.\n\"\n\ print \" comgt PIN Set PIN using COMGTPIN env variable.\n\"\n\ print \" comgt APN Set APN using COMGTAPN env variable.\n\"\n\ print \"\n Valid for GlobeTrotter GPRS only:\n\"\n\ print \" comgt USA Switch to 900/1900 MHz band for USA operation.\n\"\n\ print \" comgt Europe Switch to 900/1800 MHz band for Europen operation.\n\"\n\ print \"\n Valid for GlobeTrotter EDGE and Combo EDGE only:\n\"\n\ print \" comgt GTEDGE Switch on radio interface.\n\"\n\ print \"\n Valid for Vodafone 3G, GlobeTrotter Fusion, GT Max :\n\"\n\ print \" comgt 2G 2G networks only.\n\"\n\ print \" comgt 3G 3G networks only\n\"\n\ print \" comgt 3G2G 3G network preferred\n\"\n\ print \"\nCommand line options (must be before script name) - \\n\"\n\ print \" -d device Use alternative device. e.g -d /dev/ttyUSB0\n\"\n\ print \" -e Turn on communication echo.\n\"\n\ print \" -h Help.\n\"\n\ print \" -V Version.\n\"\n\ print \" -s Don't run internal 'default' script before running\n\"\n\ print \" external script.\n\"\n\ print \" -t=\"\\n\" Set alternative line terminator (default=\"\\n\").\n\"\n\ print \" -v Verbose mode. Print lots of trace info.\n\"\n\ print \" -x Speed exchange. 115200 replaced by 57600.\n\"\n\ print \" ***used for GlobeTrotter EDGE and Combo EDGE***\n\"\n\ print \"NOTES:\ncomgt assumes that the GlobeTrotter device is /dev/modem (create a logical link\n\"\n\ print \"to actual device or use -d switch). Unless you use the '-s' switch comgt will\n\"\n\ print \"run the internal 'default' script first before running an external script file.\n\"\n" ; char *get_code(char* name){ if(strlen(name)==0) return(_default_code); if (strcmp(name,"default")==0) return (_default_code); if (strcmp(name,"help")==0) return (_help_code); if (strcmp(name,"info")==0) return (_info_code); if (strcmp(name,"USA")==0) return (_USA_code); if (strcmp(name,"Europe")==0) return (_Europe_code); if (strcmp(name,"sig")==0) return (_sig_code); if (strcmp(name,"reg")==0) return (_reg_code); if (strcmp(name,"GTEDGE")==0) return (_GTEDGE_code); if (strcmp(name,"2G")==0) return (_2G_mode_code); if (strcmp(name,"3G")==0) return (_3G_mode_code); if (strcmp(name,"3G2G")==0) return (_3G2G_mode_code); if (strcmp(name,"PIN")==0) return (_SETPIN_code); if (strcmp(name,"APN")==0) return (_SETAPN_code); return(NULL); } ./comgt.0.32/Makefile0000755000175000001440000000346210516161012013226 0ustar paulusers# # Makefile - build and install the comgt package # Copyright (C) 2005 Martin Gregorie # Copyright (C) 2006 Paul Hardwick # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # martin@gregorie.org, paul@peck.org.uk # # $Id: Makefile,v 1.4 2006/10/20 14:30:19 pharscape Exp $ # # LIB = -L/usr/local/lib INC = -I/usr/local/include EXE = /usr/local/bin MAN = /usr/share/man/man1 CPROG = comgt SCRIPTPATH = /etc/comgt/ SCRIPTSRC = ./scripts/ BIN = $(CPROG) MANP = comgt.1 sigmon.1 CFLAGS = -c LDFLAGS = all: $(BIN) install: chmod a-w $(BIN) chmod u+rw $(BIN) chmod a+x $(BIN) cp $(BIN) $(EXE) chmod a-wx $(MANP) chmod u+rw $(MANP) chmod a+r $(MANP) cp $(MANP) $(MAN) -mkdir $(SCRIPTPATH) chmod a-w $(SCRIPTPATH) chmod u+rw $(SCRIPTPATH) chmod a+x $(SCRIPTPATH) cp -f $(SCRIPTSRC)* $(SCRIPTPATH) chmod a-w $(SCRIPTPATH)* chmod u+rw $(SCRIPTPATH)* chmod a+x $(SCRIPTPATH)* uninstall: cd $(EXE); rm $(BIN) cd $(MAN); rm $(MANP) -rm -r $(SCRIPTPATH) clean: -rm *.o -rm $(CPROG) -rm *~ -rm $(SCRIPTSRC)*~ comgt: comgt.o cc comgt.o $(LDFLAGS) -o comgt comgt.o: comgt.c comgt.h cc comgt.c $(CFLAGS) ./comgt.0.32/gprs.txt0000755000175000001440000000035210516161012013275 0ustar paulusers#Set GPRS only mode # $Id: gprs.txt,v 1.1.1.1 2006/08/16 21:21:31 pharscape Exp $ set com 115200n81 set senddelay 0.05 waitquiet 1 0.2 send "AT_OPSYS=0^m" print "Setting GPRS only mode\n" get 2 "^m" $s get 2 "^m" $s print $s ./comgt.0.32/umts.txt0000755000175000001440000000027610516161012013317 0ustar paulusers#Set UMTS only mode # $Id: umts.txt,v 1.1.1.1 2006/08/16 21:21:31 pharscape Exp $ set com 115200n81 set senddelay 0.05 waitquiet 1 0.2 send "AT_OPSYS=1^m" print "Setting UMTS only mode\n" ./comgt.0.32/sigmon.10000644000175000001440000000165410516161012013142 0ustar paulusers.\" Paul Hardwick .\" paul@peck.org.uk .TH sigmon 1 "22 January, 2005" .LO 1 .SH NAME sigmon \- Vodafone 3G/GPRS datacard signal strength monitor .SH SYNOPSIS .B sigmon -? .SH OPTIONS .in +5 .B \-? .in +10 gives brief usage details .in -10 .SH DESCRIPTION .B sigmon is a command line tool for monitoring the signal strength seen by a Vodafone 3G/GPRS datacard. Once started, it queries the datacard for the signal strength and displays it every 5 seconds. Use .I Ctrl/C to stop the signal strength display and exit from .B sigmon .SH BUGS .B sigmon is a simple script that assumes that the third port of the datacard is /dev/ttyUSB2. If the datacard is not the first USB device registered the script must be modified to correct the port name. Read /var/log/messages to find the correct port name. .SH DEPENDENCIES .B sigmon requires .I comgt to be installed so that it appears in the current search path when .B sigmon is run. ./comgt.0.32/scripts/0000755000175000001440000000000010516161012013245 5ustar paulusers./comgt.0.32/scripts/dump0000644000175000001440000000072610516161012014142 0ustar paulusers#################################################### # # dump - comgt script to dump modem settings # # Copyright (C) 2006 Paul Hardwick # ################################################### print "\nDumping Modem Settings\n\n" print "#################\n" opengt set com 115200n81 set senddelay 0.05 waitquiet 1 0.2 send "AT&VE1^m" get 1 "^m" $a :loop print $a get 1 "^m" $a let a=len($a) if a > 0 goto loop print "#################\n" ./comgt.0.32/scripts/command0000644000175000001440000000122610516161012014607 0ustar paulusers#################################################### # # command - comgt script for command interaction # # Copyright (C) 2006 Paul Hardwick # ################################################### print "\nType command at prompt.\n" print "Empty input terminates.\n" print "#################\n" opengt set com 115200n81 set senddelay 0.05 waitquiet 1 0.2 :loop1 print "Command: " input $x let c=len($x) if c=1 goto end let c=c-1 let $c=$left($x,c) send $x send "^m" :loop2 print $a get 1 "^m" $a let a=len($a) if a > 0 goto loop2 goto loop1 :end print "#################\n" ./comgt.0.32/scripts/README0000644000175000001440000000133310516161012014125 0ustar paulusers#################################################### # # comgt script files # To be placed in /etc/comgt # # Copyright (C) 2006 Paul Hardwick # ################################################### This directory contains scripts for execution by the comgt utility `man comgt` for more info on the syntax. The scripts provided: command - Provides an interactive session to let the user send AT commands manually dump - Prints the result of AT&V to the console - useful for debugging device configurations sigmon - Continuosly monitors the signal strength - `man sigmon` for more info operator - Gets a list of operators and allows the user to do a manual selection - useful for roaming abroad. ./comgt.0.32/scripts/sigmon0000755000175000001440000000253410516161012014473 0ustar paulusers# # sigmon - 3G/GPRS datacard signal strength monitor # # $Id: sigmon,v 1.1 2006/10/20 14:19:54 pharscape Exp $ # if [ $# -eq 1 ] then if [ "$1" == '-?' ] then echo "Syntax: sigmon" echo "Function: 3G/GPRS datacard signal strength monitor" echo "Options: none" else echo "Invalid option - $1" fi exit 1 else if [ $# -gt 1 ] then echo "Error: only one option permitted" exit 1 fi fi echo "Use Ctrl/C to terminate monitoring" while true do comgt -d /dev/ttyUSB2 sig sleep 5 done # # sigmon - use comgt to continuously monitor signal strength # Copyright (C) 2005 Martin Gregorie # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # martin@gregorie.org # ./comgt.0.32/scripts/operator0000755000175000001440000000574610516161012015042 0ustar paulusers############################################################################ # operator - a comgt script for viewing and selecting networks # # An example of how you might do operator selection when travelling # in a foreign country. # Big ToDo - improve the interface!!! # # Copyright (C) 2003 Paul Hardwick # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ########################################################################### ############################################################################ # $Id: operator,v 1.1 2006/10/20 14:19:54 pharscape Exp $ # $Log: operator,v $ # Revision 1.1 2006/10/20 14:19:54 pharscape # Added scripts directory - expected operational location will /etc/comgt/ # # Revision 1.1.1.1 2006/08/16 21:21:31 pharscape # intial CVS import # ############################################################################ opengt set com 115200n81 set senddelay 0.05 waitquiet 2 0.5 :operator send "AT+COPS=?^m" waitfor 20 "+COPS=?","Error" if % = -1 goto timeout if % = 0 goto getlist print "Error response from device\n" exit 1 :getlist let c=0 print "Getting Operator list: " :waiting print "." get 2 "^m" $s if % = -1 goto stillwaiting waitquiet 1 0.2 print "\n" print $s,"\n\n==============================================================\n" print "Format: (Access,Long Name, Short Name, Network ID [,Technology])\n" print "Access: 2 - Registered, 1 - Available, 3 - Forbidden\n" print "Technology: 0 - GSM/GPRS, 2 - UMTS (Not available on all cards)\n" print "\nEnter the Network ID to attempt manual registration\n [blank = automatic selection]:" input $a let a=len($a) dec a let $a=$left($a,a) if $a = "" goto automatic let $b="AT+COPS=1,2,\""+$a let $b=$b+"\"^m" send $b goto waitresult :automatic let $b="AT+COPS=0^m" send $b :waitresult waitfor 60 "OK","ERR" if % = -1 goto timeout if % = 2 goto failedreg print "Registration request accepted\n" print "Command was: ",$b,"\n" exit 0 :failedreg print "Registration request refused\n" print "Command was: ",$b,"\n" exit 1 :stillwaiting if c > 60 goto timeout let c=c+1 goto waiting :timeout print "Network Search Timeout\n" exit 1 ./comgt.0.32/COMPILING0000755000175000001440000000214110516161012013023 0ustar paulusersBuilding comgt ============= Switch to the directory where files from comgt.xxxx.tgz were unpacked. Run: make all You can run comgt immediately if your datacard is plugged in and you have the appropriate permissions to access the device. To install comgt, sigmon and their documentation, become root, make sure you're in the directory where comgt was compiled and run: make install This will install comgt and sigmon in /usr/local/bin and their manpages in /usr/local/man/man1. If this doesn't match your installation or you want to install the executables and manpages somewhere else, simply edit the EXE and MAN macro definitions on lines 3 and 4 of Makefile. To remove the executables and manpages, become root, make sure you're in the directory where comgt was compiled and run: make uninstall To tidy to after installing comgt, make sure you're logged in as the user who compiled comgt and in the directory where comgt was compiled. Then run: make clean The example scripts included in the distribution are left in the build directory. $Id: COMPILING,v 1.1.1.1 2006/08/16 21:21:31 pharscape Exp $./comgt.0.32/CHANGELOG0000755000175000001440000001071510516161012012777 0ustar paulusersChange log $Id: CHANGELOG,v 1.3 2006/10/20 14:30:19 pharscape Exp $ ========== Changes to comgt ================ Fri Oct. 20th 2006 Paul Hardwick - Scripts distributed with package are now located in scripts sub-directory - Install now copies scripts to /etc/comgt see scripts/README for list of scripts - comgt now implements search priority order for scripts - 1)internal, 2)working directory, 3)/etc/comgt - Added search path for device - /dev/noz2, /dev/ttyUSB2, /dev/modem so -d option is not needed in most cases - Added APN and PIN scripts which use environment variables to set these values - see man page Wed Aug 16 2006 Paul Hardwick - For copyright reasons Project and Application now called comgt - Adding CVS version control keywords in preparation for initial Sourceforge import - Added -V version command and moved version info into header. - Initial 0.31 Sourceforge tar. Changes to gcom =============== Tues Jan 03 2006 Paul Hardwick - Updated gcom for GT EDGE support and added many new built-in scripts - Re-wrote the header file to make it easier to maintain - Updated man-pages - Put it under version control since this utility will now be maintained. - http://peck.gotdns.com/svn/gcom Mon Jan 24 2005 Martin Gregorie - changed option handler to avoid reporting a NULL option when no arguments were supplied or when an invalid option was given. - changed the help display to fit neatly on a 25 x 80 telnet or ssh screen. - created the man page from dcon and previous gcom documentation. - created the COMPILING, CHANGELOG, MANIFEST and TODO files from pre-existing documentation. October 2003 Paul Hardwick 0 Minor changes to make dcon compile with current gcc without errors or warnings. 1 Added gcom.h which provides "built-in" scripts and a support routine of specific use to (Option) gsm type modems. 2 Modified script loading so that by default every script is pre-pended with an internal "default" script that opens the serial port correctly, checks if a PIN is required (prompting the user if needed) then checks registration status and signal strength. If you call the other built-in scripts then this default is not executed. 3 Added "-s" option to skip the internal default script. If this option is used then the user must manually open the serial port with the right baud rate. Changes to dcon, all done by Daniel.Chouinard --------------- Wed Jan 1 15:32:04 EST 1997 - Made it case independent. - Happy new year! - Indexed labels, major speed improvement. Mon Dec 30 21:10:46 EST 1996 not distributed - Fixed select() on comfd so that `pppd connect 'dcon script'` works again. Mon Dec 23 16:10:24 EST 1996 not distributed 22 hour session! - Added $right(), $left(), $dirname(), $basename(), $hex(), $hexu(), $oct(), $script(), $tolower(), $toupper(), and verbose() functions. - Added abort, flash, and dump commands. - Fixed #!/usr/local/bin/dcon support. - Fixed re-entrant getstring() bug. - Normalized gettoken() and getstring() - Used getopt() instead of if...else if...else if... - Added 0xffff (hex), 07777 (octal), 0%1111 (binary) notations. - Added [$]a0-z9 variable ranges and managed (Woohee!) to keep it compatible with old syntax. - Only allocate strings as needed. - Much better error reporting and exit code handling. - Pulled a groin muscle while sitting crooked. Go figure. - Created makescript. - Added automatic xterm call in ppp-ex.scr when in X. - Doc: Contents, syntax, error reporting, added new functions, etc... Wed Dec 11 18:30:42 EST 1996 - Changed my E-mail address in doc. - Added a fix to dogoto() so that the label gets printed in log (less confusing to see if a goto or gosub in test executed or not.) - Had lasagna for supper. Sometime a while ago before I moved (August 1996, I think) - Ansified code and Makefile, contributed by John Gotts. (You guys out there are such purists! :) Sat Jul 20 08:19:13 EDT 1996 V: 0.96 - Better error reporting. Fri Jul 19 22:29:37 EDT 1996 - Got a bug report from Glen Thigpen that dcon-0.91 reports "Token too long" errors. Found that dcon didn't deal with non-terminated last lines properly. Fixed. Mon Apr 29 21:38:04 EDT 1996 V: 0.95 - Got a bug report from J. Van Koll reporting that the included ppp-ex.scr had two lines that were truncated. Modified ppp-ex.scr ./comgt.0.32/gpl.txt0000755000175000001440000004313110516161012013106 0ustar paulusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ./comgt.0.32/MANIFEST0000644000175000001440000000015610516161012012711 0ustar paulusersCHANGELOG COMPILING comgt.1 comgt.c comgt.h gpl.txt gprs.txt Makefile MANIFEST sigmon.1 TODO umts.txt scripts