home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / rxdynd06.zip / rxdyndns.cmd next >
OS/2 REXX Batch file  |  2003-03-07  |  10KB  |  204 lines

  1. /* REXX: simplified http://members.dyndns.org/nic.update? script, */
  2. /* needs RxSock.DLL (REXX sockets library from IBM), a dynamic IP */
  3. /* (i.e. a new dialup internet connection), and a DynDNS HOSTNAME */
  4. /* not already associated with this IP.                           */
  5.  
  6. /* Usage: RXDYNDNS.CMD  interface  hostname  username  password   */
  7. /* resp.: call RXDYNDNS interface, hostname, username, password   */
  8. /*  e.g.: call RXDYNDNS 'ppp0','test.dnsalias.org','test','test'  */
  9.  
  10. /* The result is either an error message (incl. DynDNS messages)  */
  11. /* or the message 'good a.b.c.d' after updating dyn. IP a.b.c.d . */
  12. /* Please change the COPYLEFT below if you modify this script...  */
  13.  
  14.    signal on novalue  name TRAP  ;  signal on syntax name TRAP
  15.    signal on failure  name TRAP  ;  signal on halt   name TRAP
  16.  
  17.    COPYLEFT = 'rxdyndns/0.6 frank.ellermann@t-online.de'
  18.    PEERNAME = 'members.dyndns.org'     /* HTTP server for members */
  19.    PEERPORT = 8245                     /* 80 works without proxy  */
  20.  
  21.    if arg() = 1                        /* i.e. if used as command */
  22.       then parse arg IFCONFIG  HOSTNAME  USERNAME  PASSWORD  N
  23.       else parse arg IFCONFIG, HOSTNAME, USERNAME, PASSWORD, N
  24.  
  25.    if strip( HOSTNAME USERNAME PASSWORD ) = ''  then do
  26.       HOSTNAME = 'test.dnsalias.org'   /* DynDns domain for tests */
  27.       USERNAME = 'test' ;  PASSWORD = 'test'
  28.    end
  29.    if right( strip( HOSTNAME ), 11 ) = '.orgdns.org' then do
  30.       PEERPORT = 80                    /* hardwired ORGDNS stuff: */
  31.       PEERNAME = 'members.orgdns.org'  /* HTTP server for members */
  32.    end
  33.    if sign( pos( left( IFCONFIG, 1 ), '?-/' ))  then return HELP()
  34.    if IFCONFIG = '' | HOSTNAME = '' | N <> ''   then return HELP()
  35.    if USERNAME = '' | PASSWORD = ''             then return HELP()
  36.  
  37.    SOCK = -1   ;  N = 'SockLoadFuncs'
  38.    if RxFuncQuery( N ) then            /* here FAIL throws a TRAP */
  39.       if RxFuncAdd( N, 'RXSOCK', N ) then
  40.          return FAIL( N 'in RXSOCK.DLL not found' )
  41.    call SockLoadFuncs 'N'
  42.  
  43.    if SockGetHostByName( PEERNAME, 'PEER.1' ) = 0
  44.       then return FAIL( 'unknown host' PEERNAME )
  45.    if SockGetHostByName( HOSTNAME, 'HOST.1' ) = 0
  46.       then return FAIL( 'unknown host' HOSTNAME )
  47.  
  48.    PASSWORD       = MIME( USERNAME || ':' || PASSWORD )
  49.    PEER.1FAMILY   = 'AF_INET' ;  CRLF = x2c( 0D0A )
  50.    PEER.1PORT     = PEERPORT  ;  MYIP = MYIP( IFCONFIG )
  51.  
  52.    do N = 1 to HOST.1ADDR.0
  53.       if MYIP = HOST.1ADDR.N then return FAIL( MYIP 'already set' )
  54.    end N
  55.  
  56.    TEXT = 'GET /nic/update?system=dyndns&hostname=' || HOSTNAME
  57.    TEXT = TEXT || '&myip=' || MYIP
  58.    TEXT = TEXT || '&wildcard=NOCHG&offline=NO HTTP/1.0'
  59.    TEXT = TEXT || CRLF     || 'Host:' || PEERNAME
  60.    TEXT = TEXT || CRLF     || 'Authorization: Basic' PASSWORD
  61.    TEXT = TEXT || CRLF     || 'Pragma: no-cache'
  62.    TEXT = TEXT || CRLF     || 'Connection: close'
  63.    TEXT = TEXT || CRLF     || 'User-Agent:' COPYLEFT
  64.    TEXT = TEXT || CRLF     || CRLF
  65.  
  66.    SOCK = SockSocket( 'AF_INET', 'SOCK_STREAM', 'IPPROTO_TCP' )
  67.    if SOCK = -1 then return FAIL( 'SockSocket() =' SOCK )
  68.  
  69.    signal on novalue  name SOCK  ;  signal on syntax name SOCK
  70.    signal on failure  name SOCK  ;  signal on halt   name SOCK
  71.  
  72.    if SockConnect( SOCK, 'PEER.1' ) <> 0 then
  73.       return FAIL( 'SockConnect' )
  74.    if SockSend( SOCK, TEXT ) = -1 then
  75.       return FAIL( 'SockSend' )
  76.    if SockShutDown( SOCK, 1 ) <> 0 then
  77.       return FAIL( 'SockShutDown' )
  78.  
  79.    TEXT = ''
  80.    do until N = 0
  81.       N = SockRecv( SOCK, 'MORE', 1024 )
  82.       if N = -1 then return FAIL( 'SockRecv' )
  83.       TEXT = TEXT || left( MORE, N )
  84.    end
  85.  
  86.    if SockClose( SOCK ) <> 0 then return FAIL( 'SockClose' )
  87.    signal on novalue  name TRAP  ;  signal on syntax name TRAP
  88.    signal on failure  name TRAP  ;  signal on halt   name TRAP
  89.  
  90.    do while TEXT <> ''                 /* get last line of result */
  91.       parse var TEXT MORE (CRLF) TEXT
  92.    end
  93.    if arg() <> 1  then  return MORE    /* else used as command... */
  94.    say HOSTNAME MORE ;  return 1 - abbrev( MORE, 'good' )
  95.  
  96. MYIP: procedure expose SOCK      /* get dynamic IP of interface:  */
  97.    Q = RxQueue( 'Get' )          /* use whatever actual RX queue, */
  98.    if queued() = 0 then do       /* empty queue set up by caller: */
  99.       address CMD '@ifconfig' arg( 1 ) '2>&1 | RxQueue' Q
  100.       if queued() = 2 then do
  101.          pull  ;  parse pull 'inet' Q .   ;  Q = strip( Q )
  102.          if verify( Q, '0.123456789' ) = 0 then return Q
  103.       end                        /* IP contains dots and digits,  */
  104.    end                           /* anything else is erroneous... */
  105.    exit FAIL( 'ifconfig' arg( 1 ) || ':' Q queued())
  106.  
  107. MIME: procedure                  /* encode authorization string:  */
  108.    SRC = x2b( c2x( arg( 1 )))
  109.    ADD = ''
  110.    DST =        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef'
  111.    DST = DST || 'ghijklmnopqrstuvwxyz0123456789+/'
  112.    do N = 0 until DST = '' ;  parse var DST C.N 2 DST ;  end N
  113.    do N = 1 to (( length( SRC ) // 24 ) / 4 ) // 3
  114.       ADD = ADD || '='  ;  SRC = SRC || '00'
  115.    end N
  116.    do while SRC <> ''
  117.       parse var SRC N 7 SRC
  118.       N = x2d( b2x( N ))
  119.       DST = DST || C.N
  120.    end
  121.    return DST || ADD
  122.  
  123. HELP: procedure                  /* show usage message and return */
  124.    parse source . . N
  125.    N = substr( N, 1 + lastpos( '\', N ))
  126.    N = substr( N, 1 + lastpos( '/', N ))
  127.    NN = ' e.g.:' N 'ppp0 test.dnsalias.org test test'
  128.    NN = 'usage:' N 'interface host login password' x2c( 0D0A ) || NN
  129.    say NN   ;  return NN         /* caller can show NN in PM win. */
  130.  
  131. FAIL: procedure expose SOCK      /* show a socket error on stderr */
  132.    NN = arg( 1 ) '(error' max( 0, SockSock_errno() - 10000 ) || ')'
  133.    call SockPSock_errno NN       /* REXX handles missing function */
  134.    call SockClose SOCK           /* as syntax TRAP exiting anyway */
  135.    return NN                     /* caller can show NN in PM win. */
  136.  
  137. /* -- TRAP handler managed by REXXTRAP.KEX ---------------------- */
  138.  
  139. SOCK:                            /* close socket and handle TRAP: */
  140.    call SockClose SOCK
  141.    if result <> 0 then call SockPSock_errno 'SockClose() =' result
  142.  
  143. TRAP:                            /* select REXX exception handler */
  144.    call trace 'O' ;  trace N           /* don't trace interactive */
  145.    parse source TRAP                   /* source on separate line */
  146.    TRAP = x2c( 0D ) || right( '+++', 10 ) TRAP || x2c( 0D0A )
  147.    TRAP = TRAP || right( '+++', 10 )   /* = standard trace prefix */
  148.    TRAP = TRAP strip( condition( 'c' ) 'trap:' condition( 'd' ))
  149.    select
  150.       when wordpos( condition( 'c' ), 'ERROR FAILURE' ) > 0 then do
  151.          if condition( 'd' ) > ''      /* need an additional line */
  152.             then TRAP = TRAP || x2c( 0D0A ) || right( '+++', 10 )
  153.          TRAP = TRAP '(RC' rc || ')'   /* any system error codes  */
  154.          if condition( 'c' ) = 'FAILURE' then rc = -3
  155.       end
  156.       when wordpos( condition( 'c' ), 'HALT SYNTAX'   ) > 0 then do
  157.          if condition( 'c' ) = 'HALT' then rc = 4
  158.          if condition( 'd' ) > '' & condition( 'd' ) <> rc then do
  159.             if condition( 'd' ) <> errortext( rc ) then do
  160.                TRAP = TRAP || x2c( 0D0A ) || right( '+++', 10 )
  161.                TRAP = TRAP errortext( rc )
  162.             end                        /* future condition( 'd' ) */
  163.          end                           /* may use errortext( rc ) */
  164.          else  TRAP = TRAP errortext( rc )
  165.          rc = -rc                      /* rc < 0: REXX error code */
  166.       end
  167.       when condition( 'c' ) = 'NOVALUE'  then rc = -2 /* dubious  */
  168.       when condition( 'c' ) = 'NOTREADY' then rc = -1 /* dubious  */
  169.       otherwise                        /* force non-zero whole rc */
  170.          if datatype( value( 'RC' ), 'W' ) = 0 then rc = 1
  171.          if rc = 0                             then rc = 1
  172.          if condition() = '' then TRAP = TRAP arg( 1 )
  173.    end                                 /* direct: TRAP( message ) */
  174.  
  175.    TRAP = TRAP || x2c( 0D0A ) || format( sigl, 6 )
  176.    signal on syntax name TRAP.SIGL     /* throw syntax error 3... */
  177.    if 0 < sigl & sigl <= sourceline()  /* if no handle for source */
  178.       then TRAP = TRAP '*-*' strip( sourceline( sigl ))
  179.       else TRAP = TRAP '+++ (source line unavailable)'
  180. TRAP.SIGL:                             /* ...catch syntax error 3 */
  181.    if abbrev( right( TRAP, 2 + 6 ), x2c( 0D0A )) then do
  182.       TRAP = TRAP '+++ (source line unreadable)'   ;  rc = -rc
  183.    end
  184.    select
  185.       when 0 then do                   /* in pipes STDERR: output */
  186.          parse version TRAP.REXX . .   /* REXX/Personal: \dev\con */
  187.          signal on syntax name TRAP.FAIL
  188.          if TRAP.REXX = 'REXXSAA'      /* fails if no more handle */
  189.             then call lineout 'STDERR'  , TRAP
  190.             else call lineout '\dev\con', TRAP
  191.       end
  192.       when 1 then do                   /* OS/2 PM: RxMessageBox() */
  193.          signal on syntax name TRAP.FAIL
  194.          call RxMessageBox ,           /* fails if not in PMREXX  */
  195.             translate( TRAP, ' ', x2c( 0D )), , 'CANCEL', 'WARNING'
  196.       end                              /* replace any CR by blank */
  197.       otherwise   say TRAP ; trace ?L  /* interactive Label trace */
  198.    end
  199.  
  200.    if condition() = 'SIGNAL' then signal TRAP.EXIT
  201. TRAP.CALL:  return rc                  /* continue after CALL ON  */
  202. TRAP.FAIL:  say TRAP ;  rc = 0 - rc    /* force TRAP error output */
  203. TRAP.EXIT:  exit   rc                  /* exit for any SIGNAL ON  */
  204.