home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************/
- /* */
- /* (c) Copyright IBM Corporation 1997 - All rights reserved. */
- /* */
- /* This is a sample program that allows new clients to be defined to */
- /* a OS2PopS POP server via the Web. It is used within IBM on a */
- /* Web server running GoServe. */
- /* */
- /* As shipped this example will attempt to use the GoServe Web server */
- /* on the machine it is running on on port 81 instead of the normal */
- /* HTTP port 80. It also assumes that the OS2PopS POP server is on */
- /* the same machine and has been configured for remote administration */
- /* with at least 1 remote administrator defined. */
- /* */
- /**********************************************************************/
- /* */
- /* Change History: */
- /* */
- /* Change Date Int Description of change */
- /* ----------- --- -------------------------------------------------- */
- /* 08 May 1997 DJM First release as an example for the OS2POPS server */
- /* */
- /**********************************************************************/
- BaseURL = "http://127.0.0.1:81/response.html"
- LogFile = "E:\GoServe\WebReg.LogFile"
- server.!addr = '127.0.0.1'
- AdminID = "webserver"
- AdminPW = "webremotePW"
- images = "/images/"
- /**********************************************************************/
- trace "OFF"
- parse source . . ourname . /* get our name */
- ourname = translate(substr(ourname,lastpos('\',ourname)),'/','\')
- parse arg source , request , sel , tempfile /* get passed info */
- sel = translate(sel) /* upper case it to work with it */
- parse var sel . '/' function
- if CheckFunctions()
- then signal Exit_WebReg
- sockdom = 'AF_INET' /* constant */
- server.!family = 'AF_INET' /* constant */
- server.!port = 6110 /* the port we'll use to connect with */
- hex01 = "01"x
- crlf = "0D0A"x
- ok = "+OK"
- err = "-ERR"
- eod = "0D0A2E0D0A"x
- RawData = 0
- /**********************************************************************/
- /* Now get to work. */
- /**********************************************************************/
- if function == "INITIAL"
- then do
- call Initial_Page
- signal Exit_WebReg
- end
- 'read body var indata' /* get the incoming data */
- indata = translate(indata,' ','+')
- parse var indata 'userid=' uid '&' . ; uid = strip(packur(uid))
- parse var indata 'passw1=' pw1 '&' . ; pw1 = strip(packur(pw1))
- parse var indata 'passw2=' pw2 '&' . ; pw2 = strip(packur(pw2))
- select /* check the data that the user supplied */
- when uid == ''
- then do
- call Data_Missing
- signal Exit_WebReg /* that's all here folks */
- end
- when translate(pw1) \= translate(pw2) /* passwords don't match */
- then do
- call PassWord_MisMatch
- signal Exit_WebReg /* that's all here folks */
- end
- when translate(pw1) == translate(uid) /* pw = user id */
- then do
- call PassWord_UserID
- signal Exit_WebReg /* that's all here folks */
- end
- when length(pw1) < 6 /* password is too short */
- then do
- call PassWord_ToShort
- signal Exit_WebReg /* that's all here folks */
- end
- when pos(' ',pw1) > 0 /* password contains blanks */
- then do
- call PassWord_Blanks
- signal Exit_WebReg /* that's all here folks */
- end
- when pos('@',uid) > 0 /* can't have a @ in the POP user ID */
- then do
- call Invalid_POPID
- signal Exit_WebReg /* that's all here folks */
- end
- otherwise nop /* otherwise the raw data looks OK */
- end /* of select based on what the user entered */
- /**********************************************************************/
- /* If we get here we've got enough data to connect to the POP server */
- /* and find out if the requested POP User ID is available. */
- /**********************************************************************/
- if Server_LogIn()
- then signal Exit_WebReg
- if Check_UserID()
- then signal Exit_WebReg
- if ClientID \= "" /* ID requested is already taken */
- then do
- call UserID_Taken
- signal Exit_WebReg
- end
- if Server_LogIn()
- then signal Exit_WebReg
- if Add_Client()
- then signal Exit_WebReg
- call LogIt
- call UserID_Added
- Exit_WebReg: /* label for branch when we're leaving */
- return 'FILE ERASE TYPE text/html NAME' tempfile
- exit /* just in case though we'll never get here */
- /**********************************************************************/
- /* The mainline program ends here and the subroutines needed are next */
- /**********************************************************************/
- Server_LogIn: /* connect to the POP server */
- sendback = 0 /* assume there will be a problem just to be safe */
- sockit = SockSocket(sockdom,'Sock_Stream',0) /* get a socket */
- rc = SockConnect(sockit,'server.!') /* connect to the server */
- if rc \= 0 /* couldn't connect to server for some reason */
- then do
- call Unexpected_Error 'Socket connect failed with a return' ,
- 'code of' rc'.'
- signal Exit_Server_LogIn
- end /* of if rc \= 0 */
- databack = receive_data() /* get initial greeting */
- if Check_For_OK() /* first word must be +OK */
- then do
- call Unexpected_Error "POP server isn't ready to accept" ,
- "connections"
- signal Exit_Server_LogIn
- end /* of if \Check_For_OK */
- parse var databack . "<" ServerDigest ">"
- ServerDigest = "<" || ServerDigest || ">"
- if Send_Data("RADMIN" AdminID MD5Compute(ServerDigest || AdminPW))
- then signal Exit_Server_LogIn
- databack = receive_data() /* wait for server response */
- if databack == ""
- then signal Exit_Server_LogIn
- if Check_For_OK() /* first word must be +OK */
- then do
- call Unexpected_Error "Invalid admin User ID/Password"
- signal Exit_Server_LogIn
- end
- Exit_Server_LogIn:
- return sendback /* end of the Server_LogIn subroutine */
- /**********************************************************************/
- Check_UserID: /* ask server about the requested User ID */
- ClientID = ""
- ClientName = ""
- sendback = 0 /* assume there will be a problem just to be safe */
- do lp = 1 to length(uid) /* go through each letter of user ID */
- char = substr(uid,lp,1) /* extract a character */
- if datatype(char,"U") /* upper case letter? */
- then uid = overlay(bitor(char,"20"x),uid,lp) /* lower it */
- end /* of do lp = 1 to length(uid) */
- if Send_Data('USERDATA' uid) /* send over the user ID */
- then signal Exit_Check_UserID
- databack = receive_data() /* wait for server response */
- if sendback /* something drastic happened waiting to receive */
- then signal Exit_Check_UserID
- if \Check_For_OK() /* we got an OK response */
- then do
- RawData = 1
- databack = ""
- do forever until pos(eod,databack) \= 0
- databack = databack || receive_data() /* get response */
- end
- RawData = 0
- databack = substr(databack,1,length(databack) - 3) /* EOD */
- parse var databack ClientID (hex01) .
- end
- sendback = 0 /* reset error flag */
- junk = send_Data("QUIT") /* disconnect from the server now */
- Exit_Check_UserID:
- if datatype(sockit,"W") /* we still have a valid socket */
- then call SockClose sockit /* make sure we close our socket */
- return sendback /* end of the Check_UserID subroutine */
- /**********************************************************************/
- Add_Client:
- sendback = 0 /* assume there will be a problem just to be safe */
- ClientData = hex01 || ,
- uid || ,
- hex01 || ,
- pw1 || ,
- hex01 || ,
- "Client comment info goes here" || ,
- hex01
- if Send_Data("ADDCLIENT" ClientData)
- then signal Exit_Add_Client
- DataBack = Receive_Data()
- if databack == ""
- then signal Exit_Add_Client
- if Check_For_OK()
- then call Unexpected_Error "Error adding client to server"
- junk = Send_Data("QUIT") /* disconnect from the server now */
- call SockClose sockit /* make sure we close our socket */
- tuid = translate(uid) /* upper case requested POP user ID */
- Exit_Add_Client:
- return sendback /* end of the Add_Client subroutine */
- /**********************************************************************/
- Send_Data: procedure expose sockit crlf tempfile
- parse arg datatosend /* get data to send to the server */
- datatosend = datatosend || crlf /* add the crlf */
- sendback = 0 /* assume there will be a problem just to be safe */
- Send_Data_Again:
- datalong = length(datatosend) /* how much do we have here? */
- if wait_for_write() == 0 /* timed out waiting for the server */
- then do
- call Unexpected_Error 'Timeout waiting for server' ,
- 'receive enable on socket' sockit
- signal Exit_Send_Data
- end
- SendRC = SockSend(sockit,datatosend) /* send along the data */
- if SendRC == -1
- then do
- call Unexpected_Error 'Fatal error writing to server' ,
- 'socket' sockit', connection' ,
- 'closed.' errno
- signal Exit_Send_Data
- end
- if SendRC \= datalong /* not all of the data made it out */
- then do
- datatosend = substr(datatosend,SendRC + 1) /* get rest */
- signal Send_Data_Again /* and try to send it along */
- end /* of if SendRC \= datalong */
- Exit_Send_Data:
- return sendback /* end of the Send_Data subroutine */
- /**********************************************************************/
- Receive_Data: procedure expose sockit crlf RawData tempfile
- sdata = "" /* clear received data variable */
- sendback = 0 /* assume there will be a problem just to be safe */
- Wait_For_Data:
- if wait_for_receive() == 0 /* timed out waiting for the server */
- then do
- call Unexpected_Error 'Timeout waiting for server to' ,
- 'send data on socket' sockit
- signal Exit_Receive_Data
- end
- rc = SockRecv(sockit,'datain',4096)
- if rc == 0
- then do
- call Unexpected_Error 'Server using socket' sockit ,
- 'disconnected during conversation'
- signal Exit_Receive_Data
- end
- if rc == -1
- then do
- call Unexpected_Error 'Fatal error on server socket' ,
- sockit', connection closed.' errno
- signal Exit_Receive_Data
- end
- sdata = sdata || datain
- if pos(crlf,sdata) == 0
- then signal wait_for_data
- if RawData /* caller wants exactly what we get */
- then signal Exit_Receive_Data /* so give it back right now */
- parse var sdata sdata (crlf)
- Exit_Receive_Data:
- return sdata /* end of the Receive_Data subroutine */
- /**********************************************************************/
- Check_For_OK: /* see if the first word of response is +OK */
- if substr(DataBack,1,3) \= ok
- then SendBack = 1
- else SendBack = 0
- return SendBack /* end of the Check_For_OK subroutine */
- /**********************************************************************/
- WriteIt: procedure expose tempfile /* write a line to temp file */
- parse arg line2write
- call lineout tempfile,line2write
- return /* end of the WriteIt subroutine */
- /**********************************************************************/
- Unexpected_Error: /* common routine when server errors happen */
- parse arg ErrMsg
- call Response_Head "Unexpected Registration Error" /* resp header */
-
- call writeit "An unexpected error occurred trying to communicate" ,
- "with the POP server to add your POP User ID.<p>" ,
- "Please try again in a few minutes. If you receive" ,
- "another message like this please let us know.<p>" ,
- "The error message was:" ErrMsg "<hr>"
- call Response_Tail /* write common response trailer */
- sendback = 1 /* turn on the failure flag */
- return /* end of the Unexpected_Error subroutine */
- /**********************************************************************/
- Data_Missing: /* required data not entered; try again */
- call Response_Head "Missing Information" /* write response header */
- call writeit "You didn't complete all of the fields on the" ,
- "registration form.<p>Only forms with all of the" ,
- "fields completed may be processed.<p> Please" ,
- "try again.<hr>"
- call Response_Tail /* write common response trailer */
- return /* end of the Data_Missing subroutine */
- /**********************************************************************/
- PassWord_MisMatch: /* the passwords entered don't match */
- call Response_Head "Passwords Did Not Match" /* response header */
- call writeit "The passwords you entered did not match.<p>Please try" ,
- "again.<hr>"
- call Response_Tail /* write common response trailer */
- return /* end of the PassWord_MisMatch subroutine */
- /**********************************************************************/
- PassWord_UserID: /* the password and user ID match */
- call Response_Head "Password Equals User ID" /* write resp header */
- call writeit "The password you entered matches the user ID you" ,
- "selected.<p>For security reasons your password may" ,
- "not be the same as your POP user ID.<p>Please try" ,
- "again.<hr>"
- call Response_Tail /* write common response trailer */
- return /* end of the PassWord_UserID subroutine */
- /**********************************************************************/
- PassWord_ToShort: /* password must be at least 6 long */
- call Response_Head "Password Is To Short" /* write resp header */
- call writeit "The password you entered is less than 6 characters" ,
- "long.<p>For security reasons your password must" ,
- "be at least 6 characters long.<p>Please try" ,
- "again.<hr>"
- call Response_Tail /* write common response trailer */
- return /* end of the PassWord_ToShort subroutine */
- /**********************************************************************/
- PassWord_Blanks: /* password contains blanks */
- call Response_Head "Password Contains Blanks" /* write resp header */
- call writeit "The password you entered contains 1 or more blanks." ,
- "<p>Passwords may be up to 50 characters long but may" ,
- "not contain blanks.<p>Please try again.<hr>"
- call Response_Tail /* write common response trailer */
- return /* end of the PassWord_Blanks subroutine */
- /**********************************************************************/
- Invalid_POPID: /* POP ID contains a @ */
- call Response_Head "POP User ID Contains @" /* write resp header */
- call writeit "The POP user ID you entered contains a @ which is" ,
- "not valid as part of the POP user ID.<p>Please" ,
- "choose another POP user ID.<hr>"
- call Response_Tail /* write common response trailer */
- return /* end of the Invalid_POPID subroutine */
- /**********************************************************************/
- UserID_Taken: /* requested ID already taken */
- call Response_Head "User ID Already Taken" /* write resp header */
- call writeit "Sorry but somebody else is already using the" uid ,
- "User ID.<p>Please choose another User ID.<hr>"
- call Response_Tail /* write common response trailer */
- return /* end of the UserID_Taken subroutine */
- /**********************************************************************/
- UserID_Added: /* user ID was added to the server */
- call Response_Head "User ID Added Successfully"/* write resp header */
- call writeit "<center>User ID" uid "has been added to the POP server"
- call writeit "<p>Thank you for using our POP server.<p></center>"
- '</body></html>'
- call stream tempfile,'c','close' /* close temp file now */
- return /* end of the UserID_Added subroutine */
- /**********************************************************************/
- Response_Head: /* write common response heading */
- parse arg heading /* get header line to be used */
- call writeit "<html><head><title>Sample POP Registration -" || ,
- heading || "</title></head>"
- call writeit '<base href="' || BaseURL || '"></head>'
- call writeit '<body><em><hr>' || heading || '</h1><hr>'
- return /* end of the Response_Head subroutine */
- /**********************************************************************/
- Response_Tail: /* write common response trailer */
- call writeit '<a href="/popsreg.cmd/initial">Return to the POP' ,
- 'Registration Page</a></center></body></html>'
- call stream tempfile,'c','close' /* close temp file now */
- return /* end of the Response_Tail subroutine */
- /**********************************************************************/
- Wait_For_Receive: procedure expose sockit
- parse arg delay
- if delay == "" | \datatype(delay,'W')
- then delay = 45 /* 45 seconds by default */
- r.0 = 1
- r.1 = sockit
- return SockSelect('r.',,,delay)
- /**********************************************************************/
- Wait_For_Write: procedure expose sockit
- parse arg delay
- if delay == "" | \datatype(delay,'W')
- then delay = 45 /* 45 seconds by default */
- w.0 = 1
- w.1 = sockit
- return SockSelect(,'w.',,delay)
- /**********************************************************************/
- Initial_Page: /* show main registration page */
- call writeit "<html><head><title>Sample POP Server Registration" || ,
- "</title></head>"
- call writeit '<base href="' || BaseURL || '"></head>'
- call writeit '<body><center><h1>POP Server' ,
- 'Registration Form</h1></center><hr>'
- call writeit "<center><h2>Important Notes</h2></center><ul>"
- call writeit "<li>The user ID should always be lower case. ABC" ,
- "== abc<li>The POP server password is <em>CaSe" ,
- "SeNsItIvE</em>.<li><em>All</em> fields must be" ,
- "completed or your request can not be processed." ,
- "<li>Passwords may be any combination" ,
- "of upper and lower case characters but may" ,
- "<em>not</em> contain blanks. To maintain" ,
- "the security of your mail, choose something" ,
- "that includes numbers and characters or use a" ,
- "phrase. You may have a password that is up to" ,
- "50 characters long.<p></ul>"
- call writeit '<form ACTION="/WebReg.cmd/" METHOD=POST><center>'
- call writeit "<table width=750 cellspacing=10 cellpadding=0" ,
- "border=0>"
- call writeit "<tr><th colspan=2>POP server User ID" ,
- "<br>(may be up to 20 characters long)</th></tr>"
- call writeit '<tr><td colspan=2 align=center><input name="userid"' ,
- 'size="20" maxlength="20"></td></tr>'
- call writeit "<tr><th colspan=2 align=center>Passwords may be up" ,
- "to 50 characters long</th></tr>"
- call writeit "<tr><th>POP server password desired</th>"
- call writeit "<th>POP password again for verification</th></tr>"
- call writeit '<tr><td align=center><input name="passw1" size="20"' ,
- 'type="password" maxlength="50"></td>'
- call writeit '<td align=center><input name="passw2" size="20"' ,
- 'type="password" maxlength="50"></td></tr>'
- call writeit "<tr><th colspan=2><font size=+2>Please Note" ,
- "</font></th></tr>"
- call writeit '<tr><td colspan=2 align=center><font size=+2' ,
- 'color="Fuchsia">Processing of your request may' ,
- 'take up to 2 minutes. Please be patient</font>' ,
- '</td></tr>'
- call writeit '</table><p><input type="submit" value="Process' ,
- 'Request">'
- call writeit '<p><input type="reset" value="Clear Form"><p>'
- call writeit '<a href="os2pop.htm">Return to the POP Page</a>'
- call writeit "</center></FORM></body></html>"
- return /* end of the Initial_Page subroutine */
- /**********************************************************************/
- CheckFunctions:
- sendback = 0
- signal on syntax name Function_Load_Failed
- needed = 'SysFileSearch SysFileTree'
- do lp = 1 to words(needed) /* go through each function name we need */
- func = word(needed,lp) /* extract a function name */
- rc = RxFuncAdd(func,'RexxUtil',func) /* brute force load */
- end /* of do lp = 1 to words(needed) */
- rc = RxFuncAdd('SockLoadFuncs','rxsock','SockLoadFuncs')
- rc = SockLoadFuncs("QUIET")
- rc = RxFuncAdd("MD5LoadFuncs","rxmd5","MD5LoadFuncs")
- rc = MD5LoadFuncs("QUIET")
- signal off syntax
- return sendback /* end of the CheckFunctions subroutine */
- /**********************************************************************/
- Function_Load_Failed:
- call Response_Head "Fatal Error On Web Server" /* write header */
- call writeit "One or more Rexx or Socket functions did not load" ,
- "correctly on the Web server.<p>Please contact the" ,
- "Web server owner and let them know there is a" ,
- "problem.<p>Your request for a POP client can not" ,
- "be processed right now.<p>"
- call Response_Tail /* write common response trailer */
- sendback = 1
- return sendback /* end of the Function_Load_Failed subroutine */
- /**********************************************************************/
- LogIt: /* record transaction in our log file */
- call lineout LogFile,date("S") time("N") uid
- call stream LogFile,"C","Close"
- return /* end of the LogIt subroutine */
- /**********************************************************************/
-