Diff for /doc/gutshtml/SessionThree.html between versions 1.1 and 1.2

version 1.1, 2002/06/28 20:30:29 version 1.2, 2003/07/22 14:47:00
Line 1 Line 1
 <html> <head> <meta name=Title content=" Session Three: Roles and lonnet/loncommon useful functions (Guy)"> <meta http-equiv=Content-Type content="text/html; charset=macintosh"> <link rel=Edit-Time-Data href="Session%20Three_files/editdata.mso"> <title> Session Three: Roles and lonnet/loncommon useful functions (Guy)</title> <style><!-- .Section1 {page:Section1;} .Section2 {page:Section2;} --> </style> </head> <body bgcolor=#FFFFFF link=blue vlink=purple class="Normal" lang=EN-US> <div class=Section1><span style='font-size:12.0pt;font-family:Arial;'><b><i><br clear=ALL style='page-break-before:always'>  </i></b></span>  <h2><a name="_Toc421867053">Session Three: Roles and lonnet/loncommon useful    functions (Guy)</a></h2>  <h3><a name=name></a><a name="_Toc421867054">NAME</a></h3>  <p>Apache::lonnet - Subroutines to ask questions about things in the network.</p>  <div align=center style='text-align:center'>    <hr size=2 width="100%" align=center>  </div>  <h3><a name=synopsis></a><a name="_Toc421867055">SYNOPSIS</a></h3>  <p>Invoked by other LON-CAPA modules, when they need to talk to or about objects    in the network.</p>  <pre>&nbsp; &amp;Apache::lonnet::SUBROUTINENAME(ARGUMENTS);</pre>  <p>Common parameters:</p>  <ul type=disc>    <li>$uname : an internal username (if $cname expecting a course Id specifically)    </li>    <li>$udom : a domain (if $cdom expecting a course's domain specifically) </li>    <li>$symb : a resource instance identifier </li>    <li>$namespace : the name of a .db file that contains the data needed or being      set. </li>  </ul>  <div align=center style='text-align:center'>    <hr size=2 width="100%" align=center>  </div>  <h3><a name=introduction></a><a name="_Toc421867056">INTRODUCTION</a></h3>  <p>This module provides subroutines which interact with the lonc/lond (TCP)    network layer of LON-CAPA. And Can be used to ask about - classes - users    - resources</p>  <p>For many of these objects you can also use this to store data about them    or modify them in various ways.</p>  <p>This is part of the LearningOnline Network with CAPA project described at    <a href="http://www.lon-capa.org./">http://www.lon-capa.org.</a></p>  <div align=center style='text-align:center'>    <hr size=2 width="100%" align=center>  </div>  <h3><a name="return_messages"></a><a name="_Toc421867057">RETURN MESSAGES</a></h3>  <ul type=disc>    <li>con_lost : unable to contact remote host </li>    <li>con_delayed : unable to contact remote host, message will be delivered      when the connection is brought back up </li>    <li>con_failed : unable to contact remote host and unable to save message      for later delivery </li>    <li>error: : an error a occured, a description of the error follows the :    </li>    <li>no_such_host : unable to fund a host associated with the user/domain that      was requested </li>  </ul>  <div align=center style='text-align:center'>    <hr size=2 width="100%" align=center>  </div>  <h3><a name="session_environment_functions"></a><a name="_Toc421867058">Session    Environment Functions</a></h3>  <ul type=disc>    <li><code><span style='font-family:     Courier'>appenv(%hash)</span></code> : the value of %hash is written to the      user envirnoment file, and will be restored for each access this user makes      during this session, also modifies the %ENV for the current process </li>    <li><code><span style='font-family:     Courier'>delenv($regexp)</span></code> : removes all items from the session      environment file that matches the regular expression in $regexp. The values      are also delted from the current processes %ENV. </li>  </ul>  <h3><a name="user_information"></a><a name="_Toc421867059">User Information</a></h3>  <ul type=disc>    <li><code><span style='font-family:     Courier'>queryauthenticate($uname,$udom)</span></code> : try to determine      user's current authentication scheme </li>    <li><code><span style='font-family:     Courier'>authenticate($uname,$upass,$udom)</span></code> : try to authenticate      user from domain's lib servers (first use the current one), $upass should      be the users password </li>    <li><code><span style='font-family:     Courier'>homeserver($uname,$udom)</span></code> : find the server which has      the user's directory and files (there must be only one) . This caches the      answer and also caches if there is an error.</li>    <li><code><span style='font-family:     Courier'>idget($udom,@ids)</span></code> : find the usernames behind a list      of IDs (IDs are a unique resource in a domain, there must be only 1 ID per      username, and only 1 username per ID in a specific domain) (returns hash:      id=&gt;name,id=&gt;name) </li>    <li><code><span style='font-family:     Courier'>idrget($udom,@unames)</span></code> : find the IDs behind a list      of usernames (returns hash: name=&gt;id,name=&gt;id) </li>    <li><code><span style='font-family:     Courier'>idput($udom,%ids)</span></code> : store away a list of names and      associated IDs </li>    <li><code><span style='font-family:     Courier'>rolesinit($udom,$username,$authhost)</span></code> : get user privileges    </li>    <li><code><span style='font-family:     Courier'>usection($udom,$uname,$cname)</span></code> : finds the section      of student in the course $cname, return section name/number or '' for ``not      in course'' and '-1' for ``no section'' </li>    <li><code><span style='font-family:     Courier'>userenvironment($udom,$uname,@what)</span></code> : gets the values      of the keys passed in @what from the requested user's environment, returns      a hash </li>  </ul>  <h3><a name="user_roles"></a><a name="_Toc421867060">User Roles</a></h3>  <ul type=disc>    <li><code><span style='font-family:     Courier'>allowed($priv,$uri)</span></code> : check for a user privilege;      returns codes for allowed actions F: full access U,I,K: authentication modes      (cxx only) '': forbidden 1: user needs to choose course 2: browse allowed    </li>    <li><code><span style='font-family:     Courier'>definerole($rolename,$sysrole,$domrole,$courole)</span></code> :      define role; define a custom role rolename set privileges in format of lonTabs/roles.tab      for system, domain, and course level </li>    <li><code><span style='font-family:     Courier'>plaintext($short)</span></code> : return value in %prp hash (rolesplain.tab);      plain text explanation of a user role term </li>  </ul>  <h3><a name="user_modification"></a><a name="_Toc421867061">User Modification</a></h3>  <ul type=disc>    <li><code><span     style='font-family:Courier'>assignrole($udom,$uname,$url,$role,$end,$start)</span></code>      : assign role; give a role to a user for the level given by URL. Optional      start and end dates (leave empty string or zero for ``no date'') </li>    <li><span style='font-family:     "Courier New"'>changepass($uname,$udom,$currentpass,$newpass,$server):</span>      attempts to change a users, password, possible return values are: <span     style='font-family:"Courier New"'>ok, pwchange_failure, non_authorized, auth_mode_error,      unknown_user, refused</span></li>    <li><code><span     style='font-family:Courier'>modifyuserauth($udom,$uname,$umode,$upass)</span></code>      : modify user authentication </li>    <li><code><span     style='font-family:Courier'>modifyuser($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene)</span></code>      : modify user </li>    <li>modifystudent($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec,      $end,$start) : modify student </li>    <li><code><span     style='font-family:Courier'>assigncustomrole($udom,$uname,$url,$rdom,$rnam,$rolename,$end,$start)</span></code>      : assign custom role; give a custom role to a user for the level given by      URL. Specify name and domain of role author, and role name </li>    <li><code><span     style='font-family:Courier'>revokerole($udom,$uname,$url,$role)</span></code>      : revoke a role for url </li>    <li><code><span     style='font-family:Courier'>revokecustomrole($udom,$uname,$url,$role)</span></code>      : revoke a custom role </li>  </ul>  <h3><a name="course_infomation"></a><a name="_Toc421867062">Course Infomation</a></h3>  <ul type=disc>    <li><code><span style='font-family:     Courier'>coursedescription($courseid)</span></code> : course description    </li>    <li><span style='font-family:     "Courier New"'>courseresdata($coursenum,$coursedomain,@which) :</span> request      for current parameter setting for a specific course, @what should be a list      of parameters to ask about. This routine caches answers for 5 minutes.</li>  </ul>  <h3><a name="course_modification"></a><a name="_Toc421867063">Course Modification</a></h3>  <ul type=disc>    <li><code><span     style='font-family:Courier'>writecoursepref($courseid,%prefs)</span></code>      : write preferences (environment database) for a course </li>    <li><code><span     style='font-family:Courier'>createcourse($udom,$description,$url)</span></code>      : make/modify course </li>  </ul>  <h3><a name="resource_subroutines"></a><a name="_Toc421867064">Resource Subroutines</a></h3>  <ul type=disc>    <li><code><span style='font-family:     Courier'>subscribe($fname)</span></code> : subscribe to a resource, returns      URL if possible (probably should use repcopy instead) </li>    <li><code><span style='font-family:     Courier'>repcopy($filename)</span></code> : subscribes to the requested file,      and attempts to replicate from the owning library server, Might return HTTP_SERVICE_UNAVAILABLE,      HTTP_NOT_FOUND, FORBIDDEN, OK, or HTTP_BAD_REQUEST, also attempts to grab      the metadata for the resource. Expects the local filesystem pathname (/home/httpd/html/res/....)    </li>  </ul>  <h3><a name="resource_information"></a><a name="_Toc421867065">Resource Information</a></h3>  <ul type=disc>    <li>EXT($varname,$symb,$udom, $uname) : evaluates and returns the value of      a vairety of different possible values, $varname should be a request string,      and the other parameters can be used to specify who and what one is asking      about. </li>  </ul>  <p><span style='font-size:10.0pt'>Possible values for $varname are environment.lastname    (or other item from the environment hash), user.name (or someother aspect    about the user), resource.0.maxtries (or some other part and parameter of    a resource)</span></p>  <ul type=disc>    <li><code><span     style='font-family:Courier'>directcondval($number)</span></code> : get current      value of a condition; reads from a state string </li>    <li><code><span     style='font-family:Courier'>condval($condidx)</span></code> : value of condition      index based on state </li>    <li><code><span     style='font-family:Courier'>metadata($uri,$what,$liburi,$prefix,$depthcount)</span></code>      : request a resource's metadata, $what should be either a specific key,      or either 'keys' (to get a list of possible keys) or 'packages' to get a      list of packages that this resource currently uses, the last 3 arguments      are only used internally for recursive metadata. This function automatically      caches all requests</li>    <li><code><span     style='font-family:Courier'>metadata_query($query,$custom,$customshow)</span></code>      : make a metadata query against the network of library servers; returns      file handle of where SQL and regex results will be stored for query</li>    <li><code><span     style='font-family:Courier'>symbread($filename)</span></code> : return symbolic      list entry (filename argument optional); returns the data handle </li>    <li><span style='font-family:     "Courier New"'>symbverify($symb,$thisfn):</span> verifies that $symb actually      exists and is a possible symb for the URL in $thisfn, returns a 1 on success,      0 on failure, user must be in a course, as it assumes the existance of the      course init hash, and uses $ENV('request.course.id'}</li>    <li><span style='font-family:     "Courier New"'>symbclean($symb):</span> removes versions numbers from a symb,      returns the cleaned symb</li>    <li><span style='font-family:     "Courier New"'>is_on_map($uri) :</span> checks if the $uri is somewhere on      the current course map, user must be in a course for it to work</li>    <li><code><span     style='font-family:Courier'>numval($salt)</span></code> : return random seed      value (addend for rndseed) </li>    <li><code><span     style='font-family:Courier'>rndseed($symb,$courseid,$udom,$username)</span></code>      : create a random sum; returns a random seed, all arguments are optional,      if they aren't sent it uses the environment to derive them. Note: if symb      isn't sent and it can't get one from &amp;symbread it will use the current      time as its return value </li>    <li><code><span     style='font-family:Courier'>ireceipt($funame,$fudom,$fucourseid,$fusymb)</span></code>      : return unique, unfakeable, receipt </li>    <li><code><span     style='font-family:Courier'>receipt()</span></code> : API to ireceipt working      off of ENV values; given out to users </li>    <li><code><span     style='font-family:Courier'>countacc($url)</span></code> : count the number      of accesses to a given URL </li>    <li><code><span     style='font-family:Courier'>checkout($symb,$tuname,$tudom,$tcrsid)</span></code>      : creates a record of a user having looked at an item, most likely printed      out or otherwise using a resource </li>    <li><code><span     style='font-family:Courier'>checkin($token)</span></code> : updates that      a resource has beeen returned (a hard copy version for instance) and returns      the data that $token was Checkout with ($symb, $tuname, $tudom, and $tcrsid)    </li>    <li><code><span     style='font-family:Courier'>expirespread($uname,$udom,$stype,$usymb)</span></code>      : set expire date for spreadsheet </li>    <li><code><span     style='font-family:Courier'>devalidate($symb)</span></code> : devalidate      temporary spreadsheet calculations, forcing spreadsheet to reevaluate the      resource scores next time. </li>  </ul>  <h3><a name="storing/retreiving_data"></a><a name="_Toc421867066"><span style='"storing\/retreiving_data"'>Storing/Retrieving Data</span></a></h3>  <ul type=disc>    <li><code><span     style='font-family:Courier'>store($storehash,$symb,$namespace,$udom,$uname)</span></code>      : stores hash permanently for this url; hashref needs to be given and should      be a \%hashname; the remaining args aren't required and if they aren't passed      or are '' they will be derived from the ENV </li>    <li><code><span     style='font-family:Courier'>cstore($storehash,$symb,$namespace,$udom,$uname)</span></code>      : same as store but uses critical subroutine </li>    <li><code><span     style='font-family:Courier'>restore($symb,$namespace,$udom,$uname)</span></code>      : returns hash for this symb; all args are optional </li>    <li><code><span     style='font-family:Courier'>tmpstore($storehash,$symb,$namespace,$udom,$uname)</span></code>      : storage that works very similar to store/cstore, but all data is stored      in a temporary location and can be reset using tmpreset, $storehash should      be a hash reference, returns nothing on success </li>    <li><code><span     style='font-family:Courier'>tmprestore($symb,$namespace,$udom,$uname)</span></code>      : storage that works very similar to restore, but all data is stored in      a temporary location and can be reset using tmpreset. Returns a hash of      values on success, error string otherwise. </li>    <li><code><span     style='font-family:Courier'>tmpreset($symb,$namespace,$udom,$uname)</span></code>      : temporary storage reset, deltes all keys for $symb form the temporary      storage hash. </li>    <li><code><span     style='font-family:Courier'>get($namespace,$storearr,$udom,$uname)</span></code>      : returns hash with keys from array reference filled in from namesp ($udomain      and $uname are optional) </li>    <li><code><span     style='font-family:Courier'>del($namespace,$storearr,$udom,$uname)</span></code>      : deletes keys out of array from namesp ($udomain and $uname are optional)    </li>    <li><code><span     style='font-family:Courier'>dump($namespace,$udom,$uname,$regexp)</span></code>      : dumps the complete (or key matching regexp) namespace into a hash ($udomain,      $uname and $regexp are optional) </li>    <li><code><span     style='font-family:Courier'>put($namespace,$storehash,$udomain,$uname)</span></code>      : stores hash in namesp ($udomain and $uname are optional) </li>    <li><code><span     style='font-family:Courier'>cput($namespace,$storehash,$udomain,$uname)</span></code>      : critical put ($udomain and $uname are optional) </li>    <li><code><span     style='font-family:Courier'>eget($namespace,$storearr,$udomain,$uname)</span></code>      : returns hash with keys from array reference filled in from namesp (encrypts      the return communication) ($udomain and $uname are optional) </li>    <li><code><span     style='font-family:Courier'>log($udom,$name,$home,$message)</span></code>      : write to permanent log for user; use critical subroutine </li>  </ul>  <h3><a name="network_status_functions"></a><a name="_Toc421867067">Network Status    Functions</a></h3>  <ul type=disc>    <li><code><span     style='font-family:Courier'>dirlist($uri)</span></code> : return directory      list based on URI </li>    <li><code><span     style='font-family:Courier'>spareserver()</span></code> : find server with      least workload from spare.tab </li>  </ul>  <h3><a name="apache_request"></a><a name="_Toc421867068">Apache Request</a></h3>  <ul type=disc>    <li><code><span     style='font-family:Courier'>ssi($url,%hash)</span></code> : server side include,      does a complete request cycle on url to localhost, posts hash </li>  </ul>  <h3><a name="data_to_string_to_data"></a><a name="_Toc421867069">Data to String    to Data</a></h3>  <ul type=disc>    <li><code><span     style='font-family:Courier'>hash2str(%hash)</span></code> : convert a hash      into a string complete with escaping and '=' and '&amp;' separators, supports      elements that are arrayrefs and hashrefs </li>    <li><code><span     style='font-family:Courier'>hashref2str($hashref)</span></code> : convert      a hashref into a string complete with escaping and '=' and '&amp;' separators,      supports elements that are arrayrefs and hashrefs </li>    <li><code><span     style='font-family:Courier'>arrayref2str($arrayref)</span></code> : convert      an arrayref into a string complete with escaping and '&amp;' separators,      supports elements that are arrayrefs and hashrefs </li>    <li><code><span     style='font-family:Courier'>str2hash($string)</span></code> : convert string      to hash using unescaping and splitting on '=' and '&amp;', supports elements      that are arrayrefs and hashrefs </li>    <li><code><span     style='font-family:Courier'>str2array($string)</span></code> : convert string      to hash using unescaping and splitting on '&amp;', supports elements that      are arrayrefs and hashrefs </li>  </ul>  <h3><a name="logging_routines"></a><a name="_Toc421867070">Logging Routines</a></h3>  <p>These routines allow one to make log messages in the lonnet.log and lonnet.perm    logfiles.</p>  <ul type=disc>    <li><code><span     style='font-family:Courier'>logtouch()</span></code> : make sure the logfile,      lonnet.log, exists </li>    <li><code><span     style='font-family:Courier'>logthis()</span></code> : append message to the      normal lonnet.log file, it gets preiodically rolled over and deleted. </li>    <li><code><span     style='font-family:Courier'>logperm()</span></code> : append a permanent      message to lonnet.perm.log, this log file never gets deleted by any automated      portion of the system, only messages of critical importance should go in      here. </li>  </ul>  <h3><a name="general_helper_routines"></a><a name="_Toc421867071">General File    Helper Routines</a></h3>  <ul type=disc>    <li><code><span     style='font-family:Courier'>getfile($file)</span></code> : serves up a file,      returns the contents of a file or -1; replicates and subscribes to the file    </li>    <li><code><span     style='font-family:Courier'>filelocation($dir,$file)</span></code> : returns      file system location of a file based on URI; meant to be ``fairly clean''      absolute reference, $dir is a directory that relative $file lookups are      to looked in ($dir of /a/dir and a file of ../bob will become /a/bob) </li>    <li><code><span     style='font-family:Courier'>hreflocation($dir,$file)</span></code> : returns      file system location or a URL; same as filelocation except for hrefs </li>    <li><code><span     style='font-family:Courier'>declutter()</span></code> : declutters URLs (remove      docroot, beginning slashes, 'res' etc) </li>  </ul>  <h3><a name="_Toc421867072">HTTP Helper Routines</a></h3>  <ul type=disc>    <li><code><span     style='font-family:Courier'>escape()</span></code> : unpack non-word characters      into CGI-compatible hex codes </li>    <li><code><span     style='font-family:Courier'>unescape()</span></code> : pack CGI-compatible      hex codes into actual non-word ASCII character </li>  </ul> </div> <h1>&nbsp;</h1> <h3><a name="underlying_communication_routines_(shoul"></a><a name="_Toc421867073">Private: Underlying communication routines (Shouldn't call)</a></h3> <ul type=disc>  <li><code><span style='font-family:     Courier'>subreply()</span></code> : tries to pass a message to lonc, returns    con_lost if incapable </li>  <li><code><span style='font-family:     Courier'>reply()</span></code> : uses subreply to send a message to remote    machine, logs all failures </li>  <li><code><span style='font-family:     Courier'>critical()</span></code> : passes a critical message to another    server; if cannot get through then place message in connection buffer directory    and returns con_delayed, if incapable of saving message, returns con_failed  </li>  <li><code><span style='font-family:     Courier'>reconlonc()</span></code> : tries to reconnect lonc client processes.  </li> </ul> <h3><a name="resource_access_logging"></a><a name="_Toc421867074">Private: Resource  Access Logging</a></h3> <ul type=disc>  <li><code><span style='font-family:     Courier'>flushcourselogs()</span></code> : flush (save) buffer logs and access    logs </li>  <li><code><span style='font-family:     Courier'>courselog($what)</span></code> : save message for course in hash  </li>  <li><code><span style='font-family:     Courier'>courseacclog($what)</span></code> : save message for course using    &amp;courselog(). Perform special processing for specific resource types (problems,    exams, quizzes, etc). </li>  <li><code><span style='font-family:     Courier'>goodbye()</span></code> : flush course logs and log shutting down;    it is called in srm.conf as a PerlChildExitHandler </li> </ul> <h3><a name=other></a><a name="_Toc421867075">Private: Other</a></h3> <p><code><span style='font-family:"Courier New"'>symblist($mapname,%newhash)</span></code><span style='font-family:"Courier New"'> :</span> update symbolic storage links </p> <h3><a name="_Toc421867076">Coding Guidelines</a></h3> <p class=H5><span style='layout-grid-mode: both'>Things to keep in mind while coding handlers for LON-CAPA </span></p> <p><span style='font-size:14.0pt'>1.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;  </span></span><span style='font-size:14.0pt'>DON'T write to Access machine disks  with permanent data, use store/restore </span></p> <p><span style='font-size:14.0pt'>2.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;  </span></span><span style='font-size:14.0pt'>DON'T </span><span style='font-size:14.0pt;font-family:"Courier New"'>use print()</span><span style='font-size:14.0pt'>, use </span><span style='font-size:14.0pt;font-family: "Courier New"'>$request-&gt;print()</span><span style='font-size:14.0pt'> </span></p> <p><span style='font-size:14.0pt'>3.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;  </span></span><span style='font-size:14.0pt'>DON'T launch children </span></p> <p><span style='font-size:14.0pt'>4.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;  </span></span><span style='font-size:14.0pt'>DO use </span><span style='font-size:14.0pt;font-family:"Courier New"'>$Apache::lonnet::perlvar{'lonDaemons'}/tmp</span><span style='font-size:14.0pt'> for temporary data. </span></p> <p><span style='font-size:14.0pt'>5.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;  </span></span><span style='font-size:14.0pt'>DO query the return value of every  file operation. </span></p> <p><span style='font-size:14.0pt'>6.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;  </span></span><span style='font-size:14.0pt'>DO </span><span style='font-size: 14.0pt;font-family:"Courier New"'>use strict;</span><span style='font-size: 14.0pt'> </span></p> <p><span style='font-size:14.0pt'>7.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;  </span></span><span style='font-size:14.0pt'>DO </span><span style='font-size: 14.0pt;font-family:"Courier New"'>use strict;</span><span style='font-size: 14.0pt'> </span></p> <p><span style='font-size:14.0pt'>8.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;  </span></span><span style='font-size:14.0pt'>DO familiarize your self with the  functions in </span><span style='font-size:14.0pt;font-family:"Courier New"'>lonnet.pm</span><span style='font-size:14.0pt'> and use them to communicate with other servers and when  you handler needs to ask questions. </span></p> <p>9.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp; </span><span style='font-size:14.0pt'>DON'T use </span><span style='font-size:14.0pt; font-family:"Courier New"'>&amp;Apache::lonnet::reply()</span><span style='font-size:14.0pt'> </span></p> <br clear=ALL style='page-break-before:always;'> <div class=Section2> </div> </body> </html>  
   
   <html>
   <head>
   <meta name=Title
   content=" Session Three: Roles and lonnet/loncommon useful functions (Guy)">
   <meta http-equiv=Content-Type content="text/html; charset=macintosh">
   <link rel=Edit-Time-Data href="Session%20Three_files/editdata.mso">
   <title> Session Three: Roles and lonnet/loncommon useful functions (Guy)</title>
   <style><!--
   .Section1
    {page:Section1;}
   .Section2
    {page:Section2;}
   -->
   </style>
   </head>
   <body bgcolor=#FFFFFF link=blue vlink=purple class="Normal" lang=EN-US>
   <div class=Section1><span style='font-size:12.0pt;font-family:Arial;'><b><i><br clear=ALL style='page-break-before:always'>
     </i></b></span> 
     <h2><a name="_Toc421867053">Session Three: Roles and lonnet/loncommon useful 
       functions (Guy)</a></h2>
     <h3><a name=name></a><a name="_Toc421867054">NAME</a></h3>
     <p>Apache::lonnet - Subroutines to ask questions about things in the network.</p>
     <div align=center style='text-align:center'> 
       <hr size=2 width="100%" align=center>
     </div>
     <h3><a name=synopsis></a><a name="_Toc421867055">SYNOPSIS</a></h3>
     <p>Invoked by other LON-CAPA modules, when they need to talk to or about objects 
       in the network.</p>
     <pre>&nbsp; &amp;Apache::lonnet::SUBROUTINENAME(ARGUMENTS);</pre>
     <p>Common parameters:</p>
     <ul type=disc>
       <li>$uname : an internal username (if $cname expecting a course Id specifically) 
       </li>
       <li>$udom : a domain (if $cdom expecting a course's domain specifically) </li>
       <li>$symb : a resource instance identifier </li>
       <li>$namespace : the name of a .db file that contains the data needed or being 
         set. </li>
     </ul>
     <div align=center style='text-align:center'> 
       <hr size=2 width="100%" align=center>
     </div>
     <h3><a name=introduction></a><a name="_Toc421867056">INTRODUCTION</a></h3>
     <p>This module provides subroutines which interact with the lonc/lond (TCP) 
       network layer of LON-CAPA. And Can be used to ask about - classes - users 
       - resources</p>
     <p>For many of these objects you can also use this to store data about them 
       or modify them in various ways.</p>
     <p>This is part of the LearningOnline Network with CAPA project described at 
       <a
   href="http://www.lon-capa.org./">http://www.lon-capa.org.</a></p>
     <div align=center style='text-align:center'> 
       <hr size=2 width="100%" align=center>
     </div>
     <h3><a name="return_messages"></a><a name="_Toc421867057">RETURN MESSAGES</a></h3>
     <ul type=disc>
       <li>con_lost : unable to contact remote host </li>
       <li>con_delayed : unable to contact remote host, message will be delivered 
         when the connection is brought back up </li>
       <li>con_failed : unable to contact remote host and unable to save message 
         for later delivery </li>
       <li>error: : an error a occured, a description of the error follows the : 
       </li>
       <li>no_such_host : unable to fund a host associated with the user/domain that 
         was requested </li>
     </ul>
     <div align=center style='text-align:center'> 
       <hr size=2 width="100%" align=center>
     </div>
     <h3><a name="session_environment_functions"></a><a name="_Toc421867058">Session 
       Environment Functions</a></h3>
     <ul type=disc>
       <li><code><span style='font-family:
        Courier'>appenv(%hash)</span></code> : the value of %hash is written to the 
         user envirnoment file, and will be restored for each access this user makes 
         during this session, also modifies the %ENV for the current process </li>
       <li><code><span style='font-family:
        Courier'>delenv($regexp)</span></code> : removes all items from the session 
         environment file that matches the regular expression in $regexp. The values 
         are also delted from the current processes %ENV. </li>
     </ul>
     <h3><a name="user_information"></a><a name="_Toc421867059">User Information</a></h3>
     <ul type=disc>
       <li><code><span style='font-family:
        Courier'>queryauthenticate($uname,$udom)</span></code> : try to determine 
         user's current authentication scheme </li>
       <li><code><span style='font-family:
        Courier'>authenticate($uname,$upass,$udom)</span></code> : try to authenticate 
         user from domain's lib servers (first use the current one), $upass should 
         be the users password </li>
       <li><code><span style='font-family:
        Courier'>homeserver($uname,$udom)</span></code> : find the server which has 
         the user's directory and files (there must be only one) . This caches the 
         answer and also caches if there is an error.</li>
       <li><code><span style='font-family:
        Courier'>idget($udom,@ids)</span></code> : find the usernames behind a list 
         of IDs (IDs are a unique resource in a domain, there must be only 1 ID per 
         username, and only 1 username per ID in a specific domain) (returns hash: 
         id=&gt;name,id=&gt;name) </li>
       <li><code><span style='font-family:
        Courier'>idrget($udom,@unames)</span></code> : find the IDs behind a list 
         of usernames (returns hash: name=&gt;id,name=&gt;id) </li>
       <li><code><span style='font-family:
        Courier'>idput($udom,%ids)</span></code> : store away a list of names and 
         associated IDs </li>
       <li><code><span style='font-family:
        Courier'>rolesinit($udom,$username,$authhost)</span></code> : get user privileges 
       </li>
       <li><code><span style='font-family:
        Courier'>usection($udom,$uname,$cname)</span></code> : finds the section 
         of student in the course $cname, return section name/number or '' for ``not 
         in course'' and '-1' for ``no section'' </li>
       <li><code><span style='font-family:
        Courier'>userenvironment($udom,$uname,@what)</span></code> : gets the values 
         of the keys passed in @what from the requested user's environment, returns 
         a hash </li>
     </ul>
     <h3><a name="user_roles"></a><a name="_Toc421867060">User Roles</a></h3>
     <ul type=disc>
       <li><code><span style='font-family:
        Courier'>allowed($priv,$uri)</span></code> : check for a user privilege; 
         returns codes for allowed actions F: full access U,I,K: authentication modes 
         (cxx only) '': forbidden 1: user needs to choose course 2: browse allowed 
       </li>
       <li><code><span style='font-family:
        Courier'>definerole($rolename,$sysrole,$domrole,$courole)</span></code> : 
         define role; define a custom role rolename set privileges in format of lonTabs/roles.tab 
         for system, domain, and course level </li>
       <li><code><span style='font-family:
        Courier'>plaintext($short)</span></code> : return value in %prp hash (rolesplain.tab); 
         plain text explanation of a user role term </li>
     </ul>
     <h3><a name="user_modification"></a><a name="_Toc421867061">User Modification</a></h3>
     <ul type=disc>
       <li><code><span
        style='font-family:Courier'>assignrole($udom,$uname,$url,$role,$end,$start)</span></code> 
         : assign role; give a role to a user for the level given by URL. Optional 
         start and end dates (leave empty string or zero for ``no date'') </li>
       <li><span style='font-family:
        "Courier New"'>changepass($uname,$udom,$currentpass,$newpass,$server):</span> 
         attempts to change a users, password, possible return values are: <span
        style='font-family:"Courier New"'>ok, pwchange_failure, non_authorized, auth_mode_error, 
         unknown_user, refused</span></li>
       <li><code><span
        style='font-family:Courier'>modifyuserauth($udom,$uname,$umode,$upass)</span></code> 
         : modify user authentication </li>
       <li><code><span
        style='font-family:Courier'>modifyuser($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene)</span></code> 
         : modify user </li>
       <li>modifystudent($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec, 
         $end,$start) : modify student </li>
       <li><code><span
        style='font-family:Courier'>assigncustomrole($udom,$uname,$url,$rdom,$rnam,$rolename,$end,$start)</span></code> 
         : assign custom role; give a custom role to a user for the level given by 
         URL. Specify name and domain of role author, and role name </li>
       <li><code><span
        style='font-family:Courier'>revokerole($udom,$uname,$url,$role)</span></code> 
         : revoke a role for url </li>
       <li><code><span
        style='font-family:Courier'>revokecustomrole($udom,$uname,$url,$role)</span></code> 
         : revoke a custom role </li>
     </ul>
     <h3><a name="course_infomation"></a><a name="_Toc421867062">Course Infomation</a></h3>
     <ul type=disc>
       <li><code><span style='font-family:
        Courier'>coursedescription($courseid)</span></code> : course description 
       </li>
       <li><span style='font-family:
        "Courier New"'>courseresdata($coursenum,$coursedomain,@which) :</span> request 
         for current parameter setting for a specific course, @what should be a list 
         of parameters to ask about. This routine caches answers for 5 minutes.</li>
     </ul>
     <h3><a name="course_modification"></a><a name="_Toc421867063">Course Modification</a></h3>
     <ul type=disc>
       <li><code><span
        style='font-family:Courier'>writecoursepref($courseid,%prefs)</span></code> 
         : write preferences (environment database) for a course </li>
       <li><code><span
        style='font-family:Courier'>createcourse($udom,$description,$url)</span></code> 
         : make/modify course </li>
     </ul>
     <h3><a name="resource_subroutines"></a><a name="_Toc421867064">Resource Subroutines</a></h3>
     <ul type=disc>
       <li><code><span style='font-family:
        Courier'>subscribe($fname)</span></code> : subscribe to a resource, returns 
         URL if possible (probably should use repcopy instead) </li>
       <li><code><span style='font-family:
        Courier'>repcopy($filename)</span></code> : subscribes to the requested file, 
         and attempts to replicate from the owning library server, Might return HTTP_SERVICE_UNAVAILABLE, 
         HTTP_NOT_FOUND, FORBIDDEN, OK, or HTTP_BAD_REQUEST, also attempts to grab 
         the metadata for the resource. Expects the local filesystem pathname (/home/httpd/html/res/....) 
       </li>
     </ul>
     <h3><a name="resource_information"></a><a name="_Toc421867065">Resource Information</a></h3>
     <ul type=disc>
       <li>EXT($varname,$symb,$udom, $uname) : evaluates and returns the value of 
         a vairety of different possible values, $varname should be a request string, 
         and the other parameters can be used to specify who and what one is asking 
         about. </li>
     </ul>
     <p><span style='font-size:10.0pt'>Possible values for $varname are environment.lastname 
       (or other item from the environment hash), user.name (or someother aspect 
       about the user), resource.0.maxtries (or some other part and parameter of 
       a resource)</span></p>
     <ul type=disc>
       <li><code><span
        style='font-family:Courier'>directcondval($number)</span></code> : get current 
         value of a condition; reads from a state string </li>
       <li><code><span
        style='font-family:Courier'>condval($condidx)</span></code> : value of condition 
         index based on state </li>
       <li><code><span
        style='font-family:Courier'>metadata($uri,$what,$liburi,$prefix,$depthcount)</span></code> 
         : request a resource's metadata, $what should be either a specific key, 
         or either 'keys' (to get a list of possible keys) or 'packages' to get a 
         list of packages that this resource currently uses, the last 3 arguments 
         are only used internally for recursive metadata. This function automatically 
         caches all requests</li>
       <li><code><span
        style='font-family:Courier'>metadata_query($query,$custom,$customshow)</span></code> 
         : make a metadata query against the network of library servers; returns 
         file handle of where SQL and regex results will be stored for query</li>
       <li><code><span
        style='font-family:Courier'>symbread($filename)</span></code> : return symbolic 
         list entry (filename argument optional); returns the data handle </li>
       <li><span style='font-family:
        "Courier New"'>symbverify($symb,$thisfn):</span> verifies that $symb actually 
         exists and is a possible symb for the URL in $thisfn, returns a 1 on success, 
         0 on failure, user must be in a course, as it assumes the existance of the 
         course init hash, and uses $ENV('request.course.id'}</li>
       <li><span style='font-family:
        "Courier New"'>symbclean($symb):</span> removes versions numbers from a symb, 
         returns the cleaned symb</li>
       <li><span style='font-family:
        "Courier New"'>is_on_map($uri) :</span> checks if the $uri is somewhere on 
         the current course map, user must be in a course for it to work</li>
       <li><code><span
        style='font-family:Courier'>numval($salt)</span></code> : return random seed 
         value (addend for rndseed) </li>
       <li><code><span
        style='font-family:Courier'>rndseed($symb,$courseid,$udom,$username)</span></code> 
         : create a random sum; returns a random seed, all arguments are optional, 
         if they aren't sent it uses the environment to derive them. Note: if symb 
         isn't sent and it can't get one from &amp;symbread it will use the current 
         time as its return value </li>
       <li><code><span
        style='font-family:Courier'>ireceipt($funame,$fudom,$fucourseid,$fusymb)</span></code> 
         : return unique, unfakeable, receipt </li>
       <li><code><span
        style='font-family:Courier'>receipt()</span></code> : API to ireceipt working 
         off of ENV values; given out to users </li>
       <li><code><span
        style='font-family:Courier'>countacc($url)</span></code> : count the number 
         of accesses to a given URL </li>
       <li><code><span
        style='font-family:Courier'>checkout($symb,$tuname,$tudom,$tcrsid)</span></code> 
         : creates a record of a user having looked at an item, most likely printed 
         out or otherwise using a resource </li>
       <li><code><span
        style='font-family:Courier'>checkin($token)</span></code> : updates that 
         a resource has beeen returned (a hard copy version for instance) and returns 
         the data that $token was Checkout with ($symb, $tuname, $tudom, and $tcrsid) 
       </li>
       <li><code><span
        style='font-family:Courier'>expirespread($uname,$udom,$stype,$usymb)</span></code> 
         : set expire date for spreadsheet </li>
       <li><code><span
        style='font-family:Courier'>devalidate($symb)</span></code> : devalidate 
         temporary spreadsheet calculations, forcing spreadsheet to reevaluate the 
         resource scores next time. </li>
     </ul>
     <h3><a name="storing/retreiving_data"></a><a name="_Toc421867066"><span
   style='"storing\/retreiving_data"'>Storing/Retrieving Data</span></a></h3>
     <ul type=disc>
       <li><code><span
        style='font-family:Courier'>store($storehash,$symb,$namespace,$udom,$uname)</span></code> 
         : stores hash permanently for this url; hashref needs to be given and should 
         be a \%hashname; the remaining args aren't required and if they aren't passed 
         or are '' they will be derived from the ENV </li>
       <li><code><span
        style='font-family:Courier'>cstore($storehash,$symb,$namespace,$udom,$uname)</span></code> 
         : same as store but uses critical subroutine </li>
       <li><code><span
        style='font-family:Courier'>restore($symb,$namespace,$udom,$uname)</span></code> 
         : returns hash for this symb; all args are optional </li>
       <li><code><span
        style='font-family:Courier'>tmpstore($storehash,$symb,$namespace,$udom,$uname)</span></code> 
         : storage that works very similar to store/cstore, but all data is stored 
         in a temporary location and can be reset using tmpreset, $storehash should 
         be a hash reference, returns nothing on success </li>
       <li><code><span
        style='font-family:Courier'>tmprestore($symb,$namespace,$udom,$uname)</span></code> 
         : storage that works very similar to restore, but all data is stored in 
         a temporary location and can be reset using tmpreset. Returns a hash of 
         values on success, error string otherwise. </li>
       <li><code><span
        style='font-family:Courier'>tmpreset($symb,$namespace,$udom,$uname)</span></code> 
         : temporary storage reset, deltes all keys for $symb form the temporary 
         storage hash. </li>
       <li><code><span
        style='font-family:Courier'>get($namespace,$storearr,$udom,$uname)</span></code> 
         : returns hash with keys from array reference filled in from namesp ($udomain 
         and $uname are optional) </li>
       <li><code><span
        style='font-family:Courier'>del($namespace,$storearr,$udom,$uname)</span></code> 
         : deletes keys out of array from namesp ($udomain and $uname are optional) 
       </li>
       <li><code><span
        style='font-family:Courier'>dump($namespace,$udom,$uname,$regexp)</span></code> 
         : dumps the complete (or key matching regexp) namespace into a hash ($udomain, 
         $uname and $regexp are optional) </li>
       <li><code><span
        style='font-family:Courier'>put($namespace,$storehash,$udomain,$uname)</span></code> 
         : stores hash in namesp ($udomain and $uname are optional) </li>
       <li><code><span
        style='font-family:Courier'>cput($namespace,$storehash,$udomain,$uname)</span></code> 
         : critical put ($udomain and $uname are optional) </li>
       <li><code><span
        style='font-family:Courier'>eget($namespace,$storearr,$udomain,$uname)</span></code> 
         : returns hash with keys from array reference filled in from namesp (encrypts 
         the return communication) ($udomain and $uname are optional) </li>
       <li><code><span
        style='font-family:Courier'>log($udom,$name,$home,$message)</span></code> 
         : write to permanent log for user; use critical subroutine </li>
     </ul>
     <h3><a name="network_status_functions"></a><a name="_Toc421867067">Network Status 
       Functions</a></h3>
     <ul type=disc>
       <li><code><span
        style='font-family:Courier'>dirlist($uri)</span></code> : return directory 
         list based on URI </li>
       <li><code><span
        style='font-family:Courier'>spareserver()</span></code> : find server with 
         least workload from spare.tab </li>
     </ul>
     <h3><a name="apache_request"></a><a name="_Toc421867068">Apache Request</a></h3>
     <ul type=disc>
       <li><code><span
        style='font-family:Courier'>ssi($url,%hash)</span></code> : server side include, 
         does a complete request cycle on url to localhost, posts hash </li>
     </ul>
     <h3><a name="data_to_string_to_data"></a><a name="_Toc421867069">Data to String 
       to Data</a></h3>
     <ul type=disc>
       <li><code><span
        style='font-family:Courier'>hash2str(%hash)</span></code> : convert a hash 
         into a string complete with escaping and '=' and '&amp;' separators, supports 
         elements that are arrayrefs and hashrefs </li>
       <li><code><span
        style='font-family:Courier'>hashref2str($hashref)</span></code> : convert 
         a hashref into a string complete with escaping and '=' and '&amp;' separators, 
         supports elements that are arrayrefs and hashrefs </li>
       <li><code><span
        style='font-family:Courier'>arrayref2str($arrayref)</span></code> : convert 
         an arrayref into a string complete with escaping and '&amp;' separators, 
         supports elements that are arrayrefs and hashrefs </li>
       <li><code><span
        style='font-family:Courier'>str2hash($string)</span></code> : convert string 
         to hash using unescaping and splitting on '=' and '&amp;', supports elements 
         that are arrayrefs and hashrefs </li>
       <li><code><span
        style='font-family:Courier'>str2array($string)</span></code> : convert string 
         to hash using unescaping and splitting on '&amp;', supports elements that 
         are arrayrefs and hashrefs </li>
     </ul>
     <h3><a name="logging_routines"></a><a name="_Toc421867070">Logging Routines</a></h3>
     <p>These routines allow one to make log messages in the lonnet.log and lonnet.perm 
       logfiles.</p>
     <ul type=disc>
       <li><code><span
        style='font-family:Courier'>logtouch()</span></code> : make sure the logfile, 
         lonnet.log, exists </li>
       <li><code><span
        style='font-family:Courier'>logthis()</span></code> : append message to the 
         normal lonnet.log file, it gets preiodically rolled over and deleted. </li>
       <li><code><span
        style='font-family:Courier'>logperm()</span></code> : append a permanent 
         message to lonnet.perm.log, this log file never gets deleted by any automated 
         portion of the system, only messages of critical importance should go in 
         here. </li>
     </ul>
     <h3><a name="general_helper_routines"></a><a name="_Toc421867071">General File 
       Helper Routines</a></h3>
     <ul type=disc>
       <li><code><span
        style='font-family:Courier'>getfile($file)</span></code> : serves up a file, 
         returns the contents of a file or -1; replicates and subscribes to the file 
       </li>
       <li><code><span
        style='font-family:Courier'>filelocation($dir,$file)</span></code> : returns 
         file system location of a file based on URI; meant to be ``fairly clean'' 
         absolute reference, $dir is a directory that relative $file lookups are 
         to looked in ($dir of /a/dir and a file of ../bob will become /a/bob) </li>
       <li><code><span
        style='font-family:Courier'>hreflocation($dir,$file)</span></code> : returns 
         file system location or a URL; same as filelocation except for hrefs </li>
       <li><code><span
        style='font-family:Courier'>declutter()</span></code> : declutters URLs (remove 
         docroot, beginning slashes, 'res' etc) </li>
     </ul>
     <h3><a name="_Toc421867072">HTTP Helper Routines</a></h3>
     <ul type=disc>
       <li><code><span
        style='font-family:Courier'>escape()</span></code> : unpack non-word characters 
         into CGI-compatible hex codes </li>
       <li><code><span
        style='font-family:Courier'>unescape()</span></code> : pack CGI-compatible 
         hex codes into actual non-word ASCII character </li>
     </ul>
   </div>
   <h1>&nbsp;</h1>
   <h3><a name="underlying_communication_routines_(shoul"></a><a
   name="_Toc421867073">Private: Underlying communication routines (Shouldn't call)</a></h3>
   <ul type=disc>
     <li><code><span style='font-family:
        Courier'>subreply()</span></code> : tries to pass a message to lonc, returns 
       con_lost if incapable </li>
     <li><code><span style='font-family:
        Courier'>reply()</span></code> : uses subreply to send a message to remote 
       machine, logs all failures </li>
     <li><code><span style='font-family:
        Courier'>critical()</span></code> : passes a critical message to another 
       server; if cannot get through then place message in connection buffer directory 
       and returns con_delayed, if incapable of saving message, returns con_failed 
     </li>
     <li><code><span style='font-family:
        Courier'>reconlonc()</span></code> : tries to reconnect lonc client processes. 
     </li>
   </ul>
   <h3><a name="resource_access_logging"></a><a name="_Toc421867074">Private: Resource 
     Access Logging</a></h3>
   <ul type=disc>
     <li><code><span style='font-family:
        Courier'>flushcourselogs()</span></code> : flush (save) buffer logs and access 
       logs </li>
     <li><code><span style='font-family:
        Courier'>courselog($what)</span></code> : save message for course in hash 
     </li>
     <li><code><span style='font-family:
        Courier'>courseacclog($what)</span></code> : save message for course using 
       &amp;courselog(). Perform special processing for specific resource types (problems, 
       exams, quizzes, etc). </li>
     <li><code><span style='font-family:
        Courier'>goodbye()</span></code> : flush course logs and log shutting down; 
       it is called in srm.conf as a PerlChildExitHandler </li>
   </ul>
   <h3><a name=other></a><a name="_Toc421867075">Private: Other</a></h3>
   <p><code><span style='font-family:"Courier New"'>symblist($mapname,%newhash)</span></code><span
   style='font-family:"Courier New"'> :</span> update symbolic storage links </p>
   <h3><a name="_Toc421867076">Coding Guidelines</a></h3>
   <p class=H5><span style='layout-grid-mode:
   both'>Things to keep in mind while coding handlers for LON-CAPA </span></p>
   <p><span
   style='font-size:14.0pt'>1.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp; 
     </span></span><span style='font-size:14.0pt'>DON'T write to Access machine disks 
     with permanent data, use store/restore </span></p>
   <p><span
   style='font-size:14.0pt'>2.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp; 
     </span></span><span style='font-size:14.0pt'>DON'T </span><span
   style='font-size:14.0pt;font-family:"Courier New"'>use print()</span><span
   style='font-size:14.0pt'>, use </span><span style='font-size:14.0pt;font-family:
   "Courier New"'>$request-&gt;print()</span><span style='font-size:14.0pt'> </span></p>
   <p><span
   style='font-size:14.0pt'>3.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp; 
     </span></span><span style='font-size:14.0pt'>DON'T launch children </span></p>
   <p><span
   style='font-size:14.0pt'>4.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp; 
     </span></span><span style='font-size:14.0pt'>DO use </span><span
   style='font-size:14.0pt;font-family:"Courier New"'>$Apache::lonnet::perlvar{'lonDaemons'}/tmp</span><span
   style='font-size:14.0pt'> for temporary data. </span></p>
   <p><span
   style='font-size:14.0pt'>5.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp; 
     </span></span><span style='font-size:14.0pt'>DO query the return value of every 
     file operation. </span></p>
   <p><span
   style='font-size:14.0pt'>6.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp; 
     </span></span><span style='font-size:14.0pt'>DO </span><span style='font-size:
   14.0pt;font-family:"Courier New"'>use strict;</span><span style='font-size:
   14.0pt'> </span></p>
   <p><span
   style='font-size:14.0pt'>7.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp; 
     </span></span><span style='font-size:14.0pt'>DO </span><span style='font-size:
   14.0pt;font-family:"Courier New"'>use strict;</span><span style='font-size:
   14.0pt'> </span></p>
   <p><span
   style='font-size:14.0pt'>8.<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp; 
     </span></span><span style='font-size:14.0pt'>DO familiarize your self with the 
     functions in </span><span style='font-size:14.0pt;font-family:"Courier New"'>lonnet.pm</span><span
   style='font-size:14.0pt'> and use them to communicate with other servers and when 
     you handler needs to ask questions. </span></p>
   <p>9.<span
   style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp; </span><span
   style='font-size:14.0pt'>DON'T use </span><span style='font-size:14.0pt;
   font-family:"Courier New"'>&amp;Apache::lonnet::reply()</span><span
   style='font-size:14.0pt'> </span></p>
   <br
   clear=ALL style='page-break-before:always;'>
   <div class=Section2> </div>
   </body>
   </html>

Removed from v.1.1  
changed lines
  Added in v.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>