#!/usr/local/rexx/rxx /* * modserver - modem allocation server * * Program runs as a daemon on the designated host. Accepts requests * from clients across the network for allocation of modems. * Uses modem configuration file to determine which modem satisfies * the particular specifications requested. * * At this time, the modem server does not actually connect the * requestor to the modem - it simply returns the device name and * hostname of an available modem that satisfies the current request. * * * Modification history: * * 12 Aug 93 pjt Initial implementation * 14 Sep 94 pjt Add solaris-specific code, commented out by * default * */ /* * Fork process to continue running as a daemon & exit parent process */ forkrc = _fork() if forkrc < 0 then call error 'fork' if forkrc <> 0 then do say 'Modem server daemon started: PID =' forkrc exit end /* * Process modem configuration file to get all modems into the * modem. stem */ modem_list = './modem.list' modem. = '' address command 'execio * diskr' modem_list '(stem modem.' /* * Open a socket */ sock1 = _socket(AF_INET, SOCK_STREAM) if sock1 < 0 then call error 'socket' /* * Socket address structure */ net.sa_family = AF_INET net.sin_port = 11111 /* * Bind socket to port */ bindrc = _bind(sock1, 'net.') if bindrc < 0 then call error 'bind' /* * Listen for connections from clients */ listenrc = _listen(sock1) if listenrc < 0 then call error 'listen' /* * Main communications/processing loop */ do forever /* Accept client connections */ sock2 = _accept(sock1) if sock2 < 0 then call error 'accept' /* Use the recvbuf function to receive length-prefixed message packet */ request = recvbuf(sock2) /* For solaris, call special version of recvbuf; comment out the line above and un-comment the line below */ /* request = recvbufsolaris(sock2) */ request = lower(request) /* this application needs msg in lowercase */ parse var request get_free rest select when get_free = 'get' then do /* For a "get" request, see */ parse var rest req_baud rest /* what kind of modem needed */ got_one = 0 /* & go through all not busy */ do i = 1 to modem.0 /* until you find one */ parse var modem.i max_baud hostname device init_str busy if req_baud <= max_baud then if busy = '' then do reply = hostname device init_str modem.i = modem.i 'busy' got_one = 1 end if got_one then leave end if \got_one then reply = 'No' req_baud 'modem available at this time' end when get_free = 'free' then do /* For a "free" request, see */ parse var rest free_host free_dev rest /* which host/device */ freed = 0 /* & go through until found. */ do i = 1 to modem.0 /* If marked busy, free it. */ parse var modem.i max_baud hostname device init_str busy if hostname = free_host then if device = free_dev then if busy = 'busy' then do modem.i = max_baud hostname device init_str reply = 'Modem free request processed' freed = 1 end if freed then leave end if \freed then reply = free_host free_dev 'not allocated - not freed' end otherwise /* Reqs that don't begin with get or free are invalid */ reply = get_free 'invalid; request must begin with "get" or "free"' end /* * Call sendbuf to create a length-prefixed message packet and send * the reply back to the client */ call sendbuf sock2, reply /* For solaris, call special version of sendbuf; comment out the line above and un-comment the line below */ /* call sendbufsolaris sock2, reply */ /* * Close client connection */ closerc = _closesocket(sock2) if closerc < 0 then call error 'close' end /* end of do forever loop */ /* * Close accepting connection */ closerc = _closesocket(sock1) if closerc < 0 then call error 'close' exit error: /* * Print function that failed, error number, and system error text. * Then call system exit function to really exit this process */ say arg(1) 'error' _errno()':' _sys_errlist(_errno()) call _exit(1)