Annotation of doc/handout.DOC, revision 1.1

1.1     ! www         1: ࡱ>	MGJ&% !"#$%&'()*+,-./0123456789:;<=>?@HT"""""""&c	&&&jbjbSS	"j11A]<<<<8t$&<G&`(v*$.,&ׄ`200021`1110F0116}3\&	/<<X1NThe Guts of LON-CAPA
Workshop

Michigan State University
May 22nd-24th, 2001



&






This project is funded in part by the
National Science Foundation under ITR 0085921,
with additional support by the
Andrew W. Mellon and Alfred P. Sloan foundations.
 HYPERLINK "http://www.lon-capa.org/" &http://www.lon-capa.org/
(517) 432-5468

Guy Albertelli,  HYPERLINK "mailto:albertel@msu.edu" &albertel@msu.edu
Scott Harrison,  HYPERLINK "mailto:harris41@msu.edu" &harris41@msu.edu
Gerd Kortemeyer,  HYPERLINK "mailto:korte@lon-capa.org" &korte@lon-capa.org

Project Manager: Helen Keefe,  HYPERLINK "mailto:helen@loncapa.org" &helen@loncapa.org
LON-CAPA Coordinator: Felicia Berryman,  HYPERLINK "mailto:felicia@lon-capa.org" &felicia@lon-capa.org

 TOC \o "1-3" 
Day 1	 PAGEREF _Toc515088236 \h &6
Session One: Network Infrastructure	 PAGEREF _Toc515088237 \h &6
Overview	 PAGEREF _Toc515088238 \h &7
Example of Transactions	 PAGEREF _Toc515088239 \h &7
lonc/lond/lonnet	 PAGEREF _Toc515088240 \h &7
Scalability and Performance Analysis	 PAGEREF _Toc515088241 \h &10
Dynamic Resource Replication	 PAGEREF _Toc515088242 \h &12
Session Two: Handlers, URL-driven Processing	 PAGEREF _Toc515088243 \h &16
Server Content Resource Areas	 PAGEREF _Toc515088244 \h &16
Apache Request Cycle and Handlers	 PAGEREF _Toc515088245 \h &16
Handler Definition	 PAGEREF _Toc515088246 \h &17
Functions in lonnet	 PAGEREF _Toc515088247 \h &19
Coding Guidelines	 PAGEREF _Toc515088248 \h &20
Session Three: Authentication, Access Handlers, Environment	 PAGEREF _Toc515088249 \h &21
Authentication Overview	 PAGEREF _Toc515088250 \h &21
Authentication Mechanisms, User Data, Passwords	 PAGEREF _Toc515088251 \h &21
Environment	 PAGEREF _Toc515088252 \h &22
Session 4: Roles/Data Storage/Parameters	 PAGEREF _Toc515088253 \h &25
Domains	 PAGEREF _Toc515088254 \h &25
Userdata	 PAGEREF _Toc515088255 \h &25
Courses	 PAGEREF _Toc515088256 \h &26
Roles	 PAGEREF _Toc515088257 \h &26
Custom Roles	 PAGEREF _Toc515088258 \h &27
Choose a Role, Role Privileges	 PAGEREF _Toc515088259 \h &27
Role Initialization	 PAGEREF _Toc515088260 \h &29
Day 2	 PAGEREF _Toc515088261 \h &31
Session 1: Publication/Content Maps/Course Maps	 PAGEREF _Toc515088262 \h &31
Publication of a Resource	 PAGEREF _Toc515088263 \h &31
Content Re-usage and Granularity	 PAGEREF _Toc515088264 \h &31
Maps	 PAGEREF _Toc515088265 \h &32
Curriculum Adaptivity	 PAGEREF _Toc515088266 \h &32
Resource Assembly Tool	 PAGEREF _Toc515088267 \h &33
Map Representation and Storage Format	 PAGEREF _Toc515088268 \h &35
Example of Nested Maps	 PAGEREF _Toc515088269 \h &36
Initialization of a Course for a Learner	 PAGEREF _Toc515088270 \h &39
Evaluation of the Map Structure for a Course	 PAGEREF _Toc515088271 \h &40
Paths and Path Conditions	 PAGEREF _Toc515088272 \h &44
Multivalued Boolean Evaluation of Link Priorities	 PAGEREF _Toc515088273 \h &47
Session 2: SQL Metadata Database	 PAGEREF _Toc515088274 \h &48
Q&A	 PAGEREF _Toc515088275 \h &49
Current status of implementation	 PAGEREF _Toc515088276 \h &49
Purpose within LON-CAPA	 PAGEREF _Toc515088277 \h &50
Dependencies	 PAGEREF _Toc515088278 \h &50
Installation	 PAGEREF _Toc515088279 \h &51
Configuration (automated)	 PAGEREF _Toc515088280 \h &51
Manual configuration	 PAGEREF _Toc515088281 \h &51
The Perl API	 PAGEREF _Toc515088282 \h &51
LONSQL	 PAGEREF _Toc515088283 \h &53
LOND enabling of MySQL requests	 PAGEREF _Toc515088284 \h &55
Session 3: XML Files/Style Files	 PAGEREF _Toc515088285 \h &55
XML Files	 PAGEREF _Toc515088286 \h &55
Style Files	 PAGEREF _Toc515088287 \h &57
Session 4: What a Problem looks like/What a Problem does	 PAGEREF _Toc515088288 \h &58
Tags	 PAGEREF _Toc515088289 \h &58
<script> Functions	 PAGEREF _Toc515088290 \h &61
<script> Variables	 PAGEREF _Toc515088291 \h &61
Symbs	 PAGEREF _Toc515088292 \h &62
Store / Restore	 PAGEREF _Toc515088293 \h &62
Mandatory Homework Data	 PAGEREF _Toc515088294 \h &64
Sample Problems	 PAGEREF _Toc515088295 \h &65
Internal Structure Homework Handler	 PAGEREF _Toc515088296 \h &68
Session 5: Spreadsheet/Messaging	 PAGEREF _Toc515088297 \h &68
Spreadsheets	 PAGEREF _Toc515088298 \h &68
Messaging	 PAGEREF _Toc515088299 \h &72
Day 3	 PAGEREF _Toc515088300 \h &73
Session 1: Installation/CVS/Review Mechanism	 PAGEREF _Toc515088301 \h &73
Understanding the Files	 PAGEREF _Toc515088302 \h &73
Source repository summary	 PAGEREF _Toc515088303 \h &73
The "one file" information strategy	 PAGEREF _Toc515088304 \h &73
Categorizing the files	 PAGEREF _Toc515088305 \h &73
Special treatment of the "conf" category	 PAGEREF _Toc515088306 \h &74
The entire file space	 PAGEREF _Toc515088307 \h &74
A note on dependencies	 PAGEREF _Toc515088308 \h &75
A note on the installation CD	 PAGEREF _Toc515088309 \h &75
LON-CAPA Installation Instructions	 PAGEREF _Toc515088310 \h &75
Setting yourself up for CVS	 PAGEREF _Toc515088311 \h &79
CVS Upgrade	 PAGEREF _Toc515088312 \h &80
RPM Upgrade	 PAGEREF _Toc515088313 \h &81
Viewing the status of your machine	 PAGEREF _Toc515088314 \h &82
Submitting software patches	 PAGEREF _Toc515088315 \h &82
General Guidelines	 PAGEREF _Toc515088316 \h &82
Example Scenario	 PAGEREF _Toc515088317 \h &83
Session 2: Worktime	 PAGEREF _Toc515088318 \h &86
Session 3: Projects	 PAGEREF _Toc515088319 \h &86
Glossary	 PAGEREF _Toc515088320 \h &89
Technical Presentation (January 2001)	 PAGEREF _Toc515088321 \h &90

Day 1
Session One: Network Infrastructure
&Fig. 1.1.1  Overview of Network
Overview

Physically, the Network consists of relatively inexpensive upper-PC-class server machines which are linked through the commodity internet in a load-balancing, dynamically content-replicating and failover-secure way. Fig. 1.1.1 shows an overview of this network.

All machines in the Network are connected with each other through two-way persistent TCP/IP connections. Clients (B, F, G and H in Fig. 1.1.1) connect to the servers via standard HTTP. There are two classes of servers, Library Servers (A and E in Fig. 1.1.1) and Access Servers (C, D, I and J in Fig. 1.1.1). Library Servers are used to store all personal records of a set of users, and are responsible for their initial authentication when a session is opened on any server in the Network. For Authors, Library Servers also hosts their construction area and the authoritative copy of the current and previous versions of every resource that was published by that author. Library servers can be used as backups to host sessions when all access servers in the Network are overloaded. Otherwise, for learners, access servers are used to host the sessions. Library servers need to be strong on I/O, while access servers can generally be cheaper hardware. The network is designed so that the number of concurrent sessions can be increased over a wide range by simply adding additional Access Servers before having to add additional Library Servers. Preliminary tests showed that a Library Server could handle up to 10 Access Servers fully parallel.

The Network is divided into so-called domains, which are logical boundaries between participating institutions. These domains can be used to limit the flow of personal user information across the network, set access privileges and enforce royalty schemes.

Example of Transactions

Fig. 1.1.1 also depicts examples for several kinds of transactions conducted across the Network. 

An instructor at client B modifies and publishes a resource on her Home Server A. Server A has a record of all server machines currently subscribed to this resource, and replicates it to servers D and I. However, server D is currently offline, so the update notification gets buffered on A until D comes online again. Servers C and J are currently not subscribed to this resource. 

Learners F and G have open sessions on server I, and the new resource is immediately available to them. 

Learner H tries to connect to server I for a new session, however, the machine is not reachable, so he connects to another Access Server J instead. This server currently does not have all necessary resources locally present to host learner H, but subscribes to them and replicates them as they are accessed by H. 

Learner H solves a problem on server J. Library Server E is Hs Home Server, so this information gets forwarded to E, where the records of H are updated. 
lonc/lond/lonnet

Fig. 1.1.2 elaborates on the details of this network infrastructure. 

Fig. 1.1.2A depicts three servers (A, B and C, Fig. 1.1.2A) and a client who has a session on server C.

As C accesses different resources in the system, different handlers, which are incorporated as modules into the child processes of the web server software, process these requests.

Our current implementation uses mod_perl inside of the Apache web server software. As an example, server C currently has four active web server software child processes. The chain of handlers dealing with a certain resource is determined by both the server content resource area (see below) and the MIME type, which in turn is determined by the URL extension. For most URL structures, both an authentication handler and a content handler are registered.

Handlers use a common library lonnet to interact with both locally present temporary session data and data across the server network. For example, lonnet provides routines for finding the home server of a user, finding the server with the lowest loadavg, sending simple command-reply sequences, and sending critical messages such as a homework completion, etc. For a non-critical message, the routines reply with a simple connection lost if the message could not be delivered. For critical messages, lonnet tries to re-establish connections, re-send the command, etc. If no valid reply could be received, it answers connection deferred and stores the message in buffer space to be sent at a later point in time. Also, failed critical messages are logged.

The interface between lonnet and the Network is established by a multiplexed UNIX domain socket, denoted DS in Fig. 1.1.2A. The rationale behind this rather involved architecture is that httpd processes (Apache children) dynamically come and go on the timescale of minutes, based on workload and number of processed requests. Over the lifetime of an httpd child, however, it has to establish several hundred connections to several different servers in the Network.

On the other hand, establishing a TCP/IP connection is resource consuming for both ends of the line, and to optimize this connectivity between different servers, connections in the Network are designed to be persistent on the timescale of months, until either end is rebooted. This mechanism will be elaborated on below.

Establishing a connection to a UNIX domain socket is far less resource consuming than the establishing of a TCP/IP connection. lonc is a proxy daemon that forks off a child for every server in the Network. . Which servers are members of the Network is determined by a lookup table, which Fig. 1.1.2B is an example of. In order, the entries denote an internal name for the server, the domain of the server, the type of the server, the host name and the IP address.

The lonc parent process maintains the population and listens for signals to restart or shutdown, as well as USR1. Every child establishes a multiplexed UNIX domain socket for its server and opens a TCP/IP connection to the lond daemon (discussed below) on the remote machine, which it keeps alive. If the connection is interrupted, the child dies, whereupon the parent makes several attempts to fork another child for that server. 

When starting a new child (a new connection), first an init-sequence is carried out, which includes receiving the information from the remote lond which is needed to establish the 128-bit encryption key  the key is different for every connection. Next, any buffered (delayed) messages for the server are sent.

In normal operation, the child listens to the UNIX socket, forwards requests to the TCP connection, gets the reply from lond, and sends it back to the UNIX socket. Also, lonc takes care to the encryption and decryption of messages.

lonc was build by putting a non-forking multiplexed UNIX domain socket server into a framework that forks a TCP/IP client for every remote lond.

lond is the remote end of the TCP/IP connection and acts as a remote command processor. It receives commands, executes them, and sends replies. In normal operation, a lonc child is constantly connected to a dedicated lond child on the remote server, and the same is true vice versa (two persistent connections per server combination). 

lond  listens to a TCP/IP port (denoted P in Fig. 1.1.2A) and forks off enough child processes to have one for each other server in the network plus two spare children. The parent process maintains the population and listens for signals to restart or shutdown. Client servers are authenticated by IP.

&

Fig. 1.1.2A  Overview of Network Communication

When a new client server comes online, lond sends a signal USR1 to lonc, whereupon lonc tries again to reestablish all lost connections, even if it had given up on them before  a new client connecting could mean that that machine came online again after an interruption.

The gray boxes in Fig. 1.1.2A denote the entities involved in an example transaction of the Network. The Client is logged into server C, while server B is her Home Server. Server C can be an Access Server or a Library Server, while server B is a Library Server. She submits a solution to a homework problem, which is processed by the appropriate handler for the MIME type problem. Through lonnet, the handler writes information about this transaction to the local session data. To make a permanent log entry, lonnet establishes a connection to the UNIX domain socket for server B. lonc receives this command, encrypts it, and sends it through the persistent TCP/IP connection to the TCP/IP port of the remote lond. lond decrypts the command, executes it by writing to the permanent user data files of the client, and sends back a reply regarding the success of the operation. If the operation was unsuccessful, or the connection would have broken down, lonc would write the command into a FIFO buffer stack to be sent again later. lonc now sends a reply regarding the overall success of the operation to lonnet via the UNIX domain port, which is eventually received back by the handler.

Scalability and Performance Analysis

The scalability was tested in a test bed of servers between different physical network segments, Fig. 1.1.2B shows the network configuration of this test.

msul1:msu:library:zaphod.lite.msu.edu:35.8.63.51
msua1:msu:access:agrajag.lite.msu.edu:35.8.63.68
msul2:msu:library:frootmig.lite.msu.edu:35.8.63.69
msua2:msu:access:bistromath.lite.msu.edu:35.8.63.67
hubl14:hub:library:hubs128-pc-14.cl.msu.edu:35.8.116.34
hubl15:hub:library:hubs128-pc-15.cl.msu.edu:35.8.116.35
hubl16:hub:library:hubs128-pc-16.cl.msu.edu:35.8.116.36
huba20:hub:access:hubs128-pc-20.cl.msu.edu:35.8.116.40
huba21:hub:access:hubs128-pc-21.cl.msu.edu:35.8.116.41
huba22:hub:access:hubs128-pc-22.cl.msu.edu:35.8.116.42
huba23:hub:access:hubs128-pc-23.cl.msu.edu:35.8.116.43
hubl25:other:library:hubs128-pc-25.cl.msu.edu:35.8.116.45
huba27:other:access:hubs128-pc-27.cl.msu.edu:35.8.116.47
Fig. 1.1.2B  Example of Hosts Lookup Table /home/httpd/lonTabs/hosts.tab

In the first test, the simple ping command was used. The ping command is used to test connections and yields the server short name as reply.  In this scenario, lonc was expected to be the speed-determining step, since lond at the remote end does not need any disk access to reply.  The graph Fig. 1.1.2C shows number of seconds till completion versus number of processes issuing 10,000 ping commands each against one Library Server (450 MHz Pentium II in this test, single IDE HD). For the solid dots, the processes were concurrently started on the same Access Server and the time was measured till the processes finished  all processes finished at the same time. One Access Server (233 MHz Pentium II in the test bed) can process about 150 pings per second, and as expected, the total time grows linearly with the number of pings.

The gray dots were taken with up to seven processes concurrently running on different machines and pinging the same server  the processes ran fully concurrent, and each process finished as if the other ones were not present (about 1000 pings per second). Execution was fully parallel.

In a second test, lond was the speed-determining step  10,000 put commands each were issued first from up to seven concurrent processes on the same machine, and then from up to seven processes on different machines. The put command requires data to be written to the permanent record of the user on the remote server.

In particular, one "put" request meant that the process on the Access Server would connect to the UNIX domain socket dedicated to the library server, lonc would take the data from there, shuffle it through the persistent TCP connection, lond on the remote library server would take the data, write to disk (both to a dbm-file and to a flat-text transaction history file), answer "ok", lonc would take that reply and send it to the domain socket, the process would read it from there and close the domain-socket connection.
&
Fig. 1.1.2C  Benchmark on Parallelism of Server-Server Communication (no disk access)

The graph Fig. 1.1.2D shows the results. Series 1 (solid black diamond) is the result of concurrent processes on the same server  all of these are handled by the same server-dedicated lond-child, which lets the total amount of time grow linearly.

&

Fig. 2D  Benchmark on Parallelism of Server-Server Communication (with disk access as in Fig. 2A)


Series 2 through 8 were obtained from running the processes on different Access Servers against one Library Server, each series goes with one server. In this experiment, the processes did not finish at the same time, which most likely is due to disk-caching on the Library Server  lond-children whose datafile was (partly) in disk cache finished earlier. With seven processes from seven different servers, the operation took 255 seconds till the last process was finished for 70,000 put commands (270 per second)  versus 530 seconds if the processes ran on the same server (130 per second).

Dynamic Resource Replication

Since resources are assembled into higher order resources simply by reference, in principle it would be sufficient to retrieve them from the respective Home Servers of the authors. However, there are several problems with this simple approach: since the resource assembly mechanism is designed to facilitate content assembly from a large number of widely distributed sources, individual sessions would depend on a large number of machines and network connections to be available, thus be rather fragile. Also, frequently accessed resources could potentially drive individual machines in the network into overload situations.

Finally, since most resources depend on content handlers on the Access Servers to be served to a client within the session context, the raw source would first have to be transferred across the Network from the respective Library Server to the Access Server, processed there, and then transferred on to the client.

To enable resource assembly in a reliable and scalable way, a dynamic resource replication scheme was developed. Fig. 1.1.3 shows the details of this mechanism.

Anytime a resource out of the resource space is requested, a handler routine is called which in turn calls the replication routine (Fig. 1.1.3A). As a first step, this routines determines whether or not the resource is currently in replication transfer (Fig. 1.1.3A, Step D1a). During replication transfer, the incoming data is stored in a temporary file, and Step D1a checks for the presence of that file. If transfer of a resource is actively going on, the controlling handler receives an error message, waits for a few seconds, and then calls the replication routine again. If the resource is still in transfer, the client will receive the message Service currently not available.

In the next step (Fig. 1.1.3A, Step D1b), the replication routine checks if the URL is locally present. If it is, the replication routine returns OK to the controlling handler, which in turn passes the request on to the next handler in the chain.

If the resource is not locally present, the Home Server of the resource author (as extracted from the URL) is determined (Fig. 1.1.3A, Step D2). This is done by contacting all library servers in the authors domain (as determined from the lookup table, see Fig. 1.1.2B). In Step D2b a query is sent to the remote server whether or not it is the Home Server of the author (in our current implementation, an additional cache is used to store already identified Home Servers (not shown in the figure)). In Step D2c, the remote server answers the query with True or False. If the Home Server was found, the routine continues, otherwise it contacts the next server (Step D2a). If no server could be found, a File not Found error message is issued. In our current implementation, in this step the Home Server is also written into a cache for faster access if resources by the same author are needed again (not shown in the figure). 

 
&

Fig. 1.1.3A  Dynamic Resource Replication, subscription


&

Fig. 1.1.3B  Dynamic Resource Replication, modification

In Step D3a, the routine sends a subscribe command for the URL to the Home Server of the author. The Home Server first determines if the resource is present, and if the access privileges allow it to be copied to the requesting server (Fig. 1.1.3A, Step D3b). If this is true, the requesting server is added to the list of subscribed servers for that resource (Step D3c). The Home Server will reply with either OK or an error message, which is determined in Step D4. If the remote resource was not present, the error message File not Found will be passed on to the client, if the access was not allowed, the error message Access Denied is passed on. If the operation succeeded, the requesting server sends an HTTP request for the resource out of the /raw server content resource area of the Home Server.

The Home Server will then check if the requesting server is part of the network, and if it is subscribed to the resource (Step D5b). If it is, it will send the resource via HTTP to the requesting server without any content handlers processing it (Step D5c). The requesting server will store the incoming data in a temporary data file (Step D5a)  this is the file that Step D1a checks for. If the transfer could not complete, and appropriate error message is sent to the client (Step D6). Otherwise, the transferred temporary file is renamed as the actual resource, and the replication routine returns OK to the controlling handler (Step D7). 

Fig. 1.1.3B  depicts the process of modifying a resource. When an author publishes a new version of a resource, the Home Server will contact every server currently subscribed to the resource (Fig. 1.1.3B, Step U1), as determined from the list of subscribed servers for the resource generated in Fig. 1.1. 3A, Step D3c. The subscribing servers will receive and acknowledge the update message (Step U1c). The update mechanism finishes when the last subscribed server has been contacted (messages to unreachable servers are buffered).

Each subscribing server will check if the resource in question had been accessed recently, that is, within a configurable amount of time (Step U2). 

If the resource had not been accessed recently, the local copy of the resource is deleted (Step U3a) and an unsubscribe command is sent to the Home Server (Step U3b). The Home Server will check if the server had indeed originally subscribed to the resource (Step U3c) and then delete the server from the list of subscribed servers for the resource (Step U3d).

If the resource had been accessed recently, the modified resource will be copied over using the same mechanism as in Step D5a through D7 of Fig. 1.1.3A (Fig. 1.1.3B, Steps U4a through U6).

Load Balancing
lond provides a function to query the servers current loadavg. As a configuration parameter, one can determine the value of loadavg, which is to be considered 100%, for example, 2.00. 

Access servers can have a list of spare access servers, /home/httpd/lonTabs/spares.tab, to offload sessions depending on own workload. This check happens is done by the login handler. It re-directs the login information and session to the least busy spare server if itself is overloaded. An additional round-robin IP scheme possible. See Fig. 1.1.4 for an example of a load-balancing scheme.

&


Fig. 1.1.4  Example of Load Balancing 
Session Two: Handlers, URL-driven Processing
Server Content Resource Areas
Internally, all resources are identified primarily by their URL.  Different logical areas of the server are distinguished by the beginning part of the URL: 

/adm: publicly available content, logos, manual pages, etc.

/res/domainname/authorname/..: the resource area, holding course maps, HTML pages, homework, movies, applets, etc. Access to these files is restricted by the cookie-based authentication mechanism. Content in this area will be served by type-dependent handlers, for example, one handlers to serve homework problems, and another one for TeX resources. The structure of this area of the server is exactly the same on every server, even though not all resources might be present everywhere.

/raw/domainname/authorname/..: internally, this is just a symbolic link to the res directory, however, no content handlers are called when serving a resource and access is controlled by IP rather than cookies. This structure is used for replication of resources between servers.

/~authorname/.., /priv/authorname: the content construction space. This is normal UNIX filespace, which however can only by viewed on the web by the authors themselves through the cookie based authentication. Content handlers are active for this space. This space can be mounted on other UNIX machines, as well as AppleShare and Windows. Below the authorname, this directory has the same structure as the resource space of the author.

/lon-status/..: LON-CAPA status information  behind basic http authentication so it is not dependent on system functions

Authors can only write-access the /~authorname/ space. They can copy resources into the resource area through the publication step, and move them back through a retrieve step. Authors do not have direct write-access to their resource space.

                 Construction space ( Publication Step ( Resource space
                                                   ( Retrieve (    
Fig. 1.2.1  Construction Space versus Resource Space

During the publication step, several events will be triggered. Metadata is gathered, where a wizard manages default entries on a hierarchical per-directory base: The wizard imports the metadata (including access privileges and royalty information) from the most recent published resource in the current directory, and if that is not available, from the next directory above, etc. LON-CAPA keeps all previous versions of a resource and makes them available by explicit version number. Servers subscribing (see below) to a changed resource are notified that a new version is available.
Apache Request Cycle and Handlers
The standard mode in which the Apache web server is used is that a URL corresponds to some static file on the file system, which then more or less gets sent out as-is. Slight deviations from that simple principle are however already the directory listing function, virtual servers, and the cgi-bin directory. In the latter case, Apache executes the file in a new process and provides both the input to the process in the environment, and routes the output to the client. Other deviations are the error messages.

In a more general view, URLs to Apache are URIs (Uniform Resource Identifiers), which may are may not correspond to a physical file, which in turn may or may not be sent out as-is.

As a request for a URI gets sent to the Apache server, it goes through several phases. At each phase (stage) along the process, handler modules can be defined to deal with the request. Details about these phases are given in the Eagle book Chapter 3 (page 60).

These handler modules are not like cgi-scripts executed in a separate process, but are dynamically linked into the Apache child processes themselves  they run inside of Apache. The mod_perl mechanism in addition links the Perl interpreter into the Apache child process. Modules are pre-interpreted (compiled) by the Perl interpreter when they are first loaded, and the pre-interpreted code stays permanently in the memory allocated to that Apache child process. The result is a significant speed-up, and through the flexible mechanism of module registration and different stages of the process, a high degree of customizability.

LON-CAPA does not use Apache::Registry, and so in addition avoids the unnecessary overhead of emulating a cgi-environment within the handlers. Instead, it makes direct use of the Apache Perl API (Chapter 9, Eagle book).  
Handler Definition
Which chain of handler deals with which kind of resource is defined in /etc/httdp/conf/srm.conf. LON-CAPA only defines handlers at the (in order) header-parser, access control, and response phase (figure 3-3 Eagle book). In the header-parser phase, the replication handler is run, and in the access-control phase, the various access-handlers. Future handlers will mostly be implemented in the response phase. Fig 1.2.2 shows excerpts of the configuration script /etc/httpd/srm.conf for these modules.

# ------------------------------------------------------------- Access Handlers

<LocationMatch "^/res.*">
PerlAccessHandler       Apache::lonacc
PerlHeaderParserHandler Apache::lonrep
ErrorDocument     403 /adm/login
ErrorDocument     404 /adm/notfound.html
ErrorDocument     406 /adm/roles
ErrorDocument     500 /adm/errorhandler
</LocationMatch>

<LocationMatch "^/priv.*">
PerlAccessHandler Apache::loncacc
SetHandler        perl-script
PerlHandler       Apache::lonconstruct
ErrorDocument     403 /adm/login
ErrorDocument     404 /adm/notfound.html
ErrorDocument     406 /adm/unauthorized.html
ErrorDocument     500 /adm/errorhandler
</LocationMatch>

<LocationMatch "^/raw.*">
PerlAccessHandler Apache::lonracc
</LocationMatch>

<LocationMatch "^/\~.*">
PerlAccessHandler Apache::loncacc
ErrorDocument     403 /adm/login
ErrorDocument     404 /adm/notfound.html
ErrorDocument     406 /adm/unauthorized.html
ErrorDocument     500 /adm/errorhandler
AllowOverride None
</LocationMatch>

# --------------------------------------------- Resource Space Content Handlers

<LocationMatch "^/res/.*/$">
SetHandler perl-script
PerlHandler Apache::lonindexer
</LocationMatch>

<LocationMatch "^/res/.*\.tex$">
SetHandler perl-script
PerlHandler Apache::lontex
</LocationMatch>

<LocationMatch "^/res/.*\.page$>
SetHandler perl-script
PerlHandler Apache::lonpage
</LocationMatch>

<LocationMatch "^/(res|\~).*\.(xml|html|htm|xhtml|xhtm)$">
SetHandler perl-script
PerlHandler Apache::lonxml
</LocationMatch>

<LocationMatch "^/(res|\~).*\.(problem|exam|quiz|assess|survey|form)$">
SetHandler perl-script
PerlHandler Apache::lonhomework
</LocationMatch>


# -------------------------------------------------------------- Admin Programs

<Location /adm/roles>
PerlAccessHandler       Apache::lonacc
SetHandler perl-script
PerlHandler Apache::lonroles
ErrorDocument     403 /adm/login
ErrorDocument     500 /adm/errorhandler
</Location>

<Location /adm/login>
SetHandler perl-script
PerlHandler Apache::lonlogin
</Location>

<Location /adm/annotations>
PerlAccessHandler       Apache::lonacc
SetHandler perl-script
PerlHandler Apache::admannotations
ErrorDocument     403 /adm/login
ErrorDocument     500 /adm/errorhandler
</Location>
 etc 

Fig. 1.2.2  Excerpts of srm.conf
Functions in lonnet
# Functions for use by content handlers:
#
# metadata_query(sql-query-string,custom-metadata-regex) :
#                                    returns file handle of where sql and
#                                    regex results will be stored for query
# plaintext(short)   : plain text explanation of short term
# fileembstyle(ext)  : embed style in page for file extension
# filedescription(ext) : descriptor text for file extension
# allowed(short,url) : 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
# definerole(rolename,sys,dom,cou) : define a custom role rolename
#                      set privileges in format of lonTabs/roles.tab for
#                      system, domain and course level,
# assignrole(udom,uname,url,role,end,start) : 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")
# assigncustomrole (udom,uname,url,rdom,rnam,rolename,end,start) : give a
#                      custom role to a user for the level given by url.
#                      Specify name and domain of role author, and role name
# revokerole (udom,uname,url,role) : Revoke a role for url
# revokecustomrole (udom,uname,url,rdom,rnam,rolename) : Revoke a custom role
# appenv(hash)       : adds hash to session environment
# delenv(varname)    : deletes all environment entries starting with varname
# store(hashref,symb,courseid,udom,uname,homeserver)
#                    : 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
# cstore(hashref,symb,courseid,udom,uname,homeserver)
#                    : same as store but uses the critical interface to
#                      guarentee a store
# restore(symb,courseid,udom,uname,homeserver)
#                    : returns hash for this symb, all args are optional
#                      if they aren't given they will be derived from the current
#                      enviroment
# eget(namesp,array) : returns hash with keys from array filled in from namesp
# get(namesp,array)  : returns hash with keys from array filled in from namesp
# del(namesp,array)  : deletes keys out of array from namesp
# put(namesp,hash)   : stores hash in namesp
# cput(namesp,hash)  : critical put
# dump(namesp)       : dumps the complete namespace into a hash
# ssi(url,hash)      : does a complete request cycle on url to localhost, posts
#                      hash
# coursedescription(id) : returns and caches course description for id
# repcopy(filename)  : replicate file
# dirlist(url)       : gets a directory listing
# directcondval(index) : reading condition value of single condition from
#                        state string
# condval(index)     : value of condition index based on state
# EXT(name)          : value of a variable
# symblist(map,hash) : Updates symbolic storage links
# symbread([filename]) : returns the data handle (filename optional)
# rndseed()          : returns a random seed
# receipt()          : returns a receipt to be given out to users
# getfile(filename)  : returns the contents of filename, or a -1 if it can't
#                      be found, replicates and subscribes to the file
# filelocation(dir,file) : returns a fairly clean absolute reference to file
#                          from the directory dir
# hreflocation(dir,file) : same as filelocation, but for hrefs
# log(domain,user,home,msg) : write to permanent log for user
# usection(domain,user,courseid) : output of section name/number or '' for
#                                  "not in course" and '-1' for "no section"
# userenvironment(domain,user,what) : puts out any environment parameter
#                                     for a user
# idput(domain,hash) : writes IDs for users from hash (name=>id,name=>id)
# idget(domain,array): returns hash with usernames (id=>name,id=>name) for
#                      an array of IDs
# idrget(domain,array): returns hash with IDs for usernames (name=>id,...) for
#                       an array of names
# metadata(file,entry): returns the metadata entry for a file. entry='keys'
#                       returns a comma separated list of keys
Coding Guidelines
Things to keep in mind while coding handlers for LON-CAPA 

DON'T write to Access machine disks with permanent data, use store/restore 
DON'T use print(), use $request->print() 
DON'T launch children 
DO use $Apache::lonnet::perlvar{'lonDaemons'}/tmp for temporary data. 
DO query the return value of every file operation. 
DO use strict; 
DO use strict; 
DO familiarize your self with the functions in lonnet.pm and use them to communicate with other servers and when you handler needs to ask questions. 
DON'T use &Apache::lonnet::reply() 
Session Three: Authentication, Access Handlers, Environment
Authentication Overview

A user can log into any server in the network and run sessions. The server responsible for initially authenticating the user is the users homeserver.

When a user first accesses a server within a browser session, he or she is challenged to provide authentication information in the form of username, password and domain  this is done by lonlogin, which is the error_document for lonacc and loncacc (the normal authentication handlers). When the server receives that information, it asks all library servers in the domain that the user specified to validate the information  this is done by lonauth. 

The users home server will answer with authorized or non_authorized, all others with unknown_user. If one server authorizes the user, a cookie is returned to the user by lonauth and the session is initialized on the local server by establishing the session environment file. If a server sends non_authorized, the user is rejected.  Fig. 1.3.1 illustrates this process.


                                                                                                                     Domain
                                                                      ( username, password ( Library Server
                                                                    |    ( unknown_user (
                                                                    |
                                                                    | ( username, password ( Library Server
                                                                    |       ( authorized (
                                                                    |
User ( username,password,domain ( Server 
                ( cookie (                                store session information for valid cookies

Fig. 1.3.1  Illustration of Authentication Mechanism

At all subsequent interactions, the client sends the cookie back to the server  if the cookie is missing or invalid, the user is re-challenged for login information. Handlers are lonacc and loncacc. Cookies expire by closing the browser and are invalidated when the user logs out or logs in a second time into the same machine from another browser.
Authentication Mechanisms, User Data, Passwords

On the library servers, it is a routine in lond that does the authentication. It checks if this is the users homeserver, checks the password, and answers with unknown_user, authorized or non_authorized. 

Determination if this is the users homeserver is done by the presence of his or her password file in

 /home/httpd/lonUsers/domain/1.char/2.char/3.char/username/passwd

for example

 /home/httpd/lonUsers/msu/s/m/i/smith/passwd

The password is stored in the format mechanism:info, where mechanism can currently be unix, krb4 or internal. For krb4, the info is the Kerberos domain, for internal it is the crypt password itself. unix simply authenticates against /etc/passwd. 

Environment

The access handlers  coming early in the Apache request cycle  also set up the session environment. The cookie received from the web client is a pointer to the session profiles, which are stored in a directory for temporary files (/home/httpd/lonIDs/). 

Standard Components

These are the standard components of the environment added by Apache and the shell.

AUTH_TYPE ---- Basic
DOCUMENT_ROOT ---- /home/httpd/html
GATEWAY_INTERFACE ---- CGI-Perl/1.1
HTTP_ACCEPT ---- image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
HTTP_ACCEPT_CHARSET ---- iso-8859-1,*,utf-8
HTTP_ACCEPT_ENCODING ---- gzip
HTTP_ACCEPT_LANGUAGE ---- en,pdf
HTTP_CONNECTION ---- Keep-Alive
HTTP_COOKIE ---- SITESERVER=ID=cbc6695505253a2ff0e7bb7110574d90; lonID=kortemey_990461714_msu_msul1
HTTP_HOST ---- zaphod.lite.msu.edu
HTTP_REFERER ---- 
HTTP_USER_AGENT ---- Mozilla/4.75 (Macintosh; U; PPC)
MOD_PERL ---- mod_perl/1.21
PATH ---- /sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bi
QUERY_STRING ---- 
REMOTE_ADDR ---- 35.8.63.7
REMOTE_PORT ---- 1844
REMOTE_USER ---- lonadm
REQUEST_METHOD ---- GET
REQUEST_URI ---- /adm/test
SCRIPT_FILENAME ---- /home/httpd/html/adm/test
SCRIPT_NAME ---- /adm/test
SERVER_ADDR ---- 35.8.63.51
SERVER_ADMIN ---- korte@lite.msu.edu
SERVER_NAME ---- zaphod.lite.msu.edu
SERVER_PORT ---- 80
SERVER_PROTOCOL ---- HTTP/1.0
SERVER_SIGNATURE ---- 
SERVER_SOFTWARE ---- Apache/1.3.9 (Unix) (Red Hat/Linux) mod_perl/1.21

Resource Access Control
The following values are set by traceroute at the initialization of the course and are used by access handlers to check if a resource can be served to a user.

acc.cond.msu_12679c3ed543a25msul1.0 ---- 0
acc.cond.msu_12679c3ed543a25msul1.1 ---- 0
acc.res.msu_12679c3ed543a25msul1. ---- &:1&
acc.res.msu_12679c3ed543a25msul1.msu/mmp ---- &welcome267.htm:1&welcomelbs267.htm:0&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/applist/Spectrum ---- &s.htm:1&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/applist/chain ---- &chain.htm:1&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/applist/coulomb ---- &orbit.htm:1&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/applist/induct ---- &faraday.htm:1&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/conversions ----
&conv_area.htm:1&prefixes.htm:1&conv_power.htm:1&intro.htm:1&conv_temperature.htm:1&conv_time.htm:1&conv_velocity.htm:1&conversions.sequence:1&conv_length.htm:1&conv_mass.htm:1&conv_pressure.htm:1&conv_volume.htm:1&conv_energy.htm:1&conv_angle.htm:1&sibaseunits.htm:1&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/kap13 ---- &cd371.htm:1&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/kap16 ----
&cd427.htm:1&cd424.htm:1&Stable.htm:1&cd421.htm:1&Constants.htm:1&cd425.htm:1&cd422.htm:1&kap16.sequence:1&cd426.htm:1&cd423.htm:1&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/kap17 ----
&cd436.htm:1&kap17.sequence:1&cd433.htm:1&cd430.htm:1&cd437.htm:1&cd434.htm:1&cd428.htm:1&cd431.htm:1&cd435.htm:1&cd429.htm:1&geometry.htm:1&cd432.htm:1&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/kap17/calculus ---- &calc.htm:1&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/kap18 ----
&RR440.htm:1&RR449b.htm:1&RR446b.htm:1&cd473.htm:1&RR453.htm:1&RR447.htm:1&RR443b.htm:1&RR449a.htm:1&RR450.htm:1&RR452a.htm:1&RR444.htm:1&RR446a.htm:1&sum18a.htm:1|1&RR441.htm:1&RR443a.htm:1&eField.htm:1&RR454.htm:1&RR444b.htm:1&RR448.htm:1&RR447app.htm:1&RR451.htm:1&RR445.htm:1&RR453a.htm:1&kap18.sequence:1&RR439.htm:1&RR447a.htm:1&RR442.htm:1&RR450a.htm:1&RR444a.htm:1&RR448b.htm:1&RR445newch.htm:1&RR4460app.htm:1&RR455.htm:1&RR441a.htm:1&RR449.htm:1&RR452.htm:1&cd438.htm:1&RR446.htm:1&RR454a.htm:1&sum18.htm:1|1&RR446c.htm:1&RR448a.htm:1&RR451a.htm:1&RR443.htm:1&RR445answer.htm:0&RR445a.htm:1&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/kap18/demo ----
&vid440.htm:0&vid440sm.htm:0&vid449.htm:0&vid449-a.htm:0&vid441.htm:0&vid449sm.htm:0&vid455.htm:0&egun.htm:0&egunsm.htm:0&vid441sm.htm:0&vid449-asm.htm:0&vid455sm.htm:0&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/kap18/problems ----
&cd460b.problem:1&cd458.problem:1&cd462.problem:1&cd457.problem:1&cd461.problem:1&cd460.problem:1&cd464.problem:1&cd459.problem:1&cd463.problem:1&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/kap18a ---- &kap18a.sequence:1&
acc.res.msu_12679c3ed543a25msul1.msu/mmp/kap18a/problems ----
&cd465.problem:1&cd472.problem:1&cd466.problem:1&cd467.problem:1&cd470.problem:1&cd468.problem:1&cd471.problem:1&cd469.problem:1&

 etc for all resources in the course 

Browser Information

browser.mathml ---- 
browser.os ---- mac
browser.type ---- netscape
browser.version ---- 4.75

Cached Information about Courses and their Description

course.msu_12679c3ed543a16msul1.description ---- lbs267L Lab SS01
course.msu_12679c3ed543a16msul1.domain ---- msu
course.msu_12679c3ed543a16msul1.home ---- msul1
course.msu_12679c3ed543a16msul1.last_cache ---- 990461725
course.msu_12679c3ed543a16msul1.num ---- 12679c3ed543a16msul1
course.msu_12679c3ed543a16msul1.url ---- msu/mmp/lbs267l.sequence
course.msu_12679c3ed543a25msul1.description ---- lbs267 Lecture SS01
course.msu_12679c3ed543a25msul1.domain ---- msu
course.msu_12679c3ed543a25msul1.home ---- msul1
course.msu_12679c3ed543a25msul1.last_cache ---- 990461728
course.msu_12679c3ed543a25msul1.num ---- 12679c3ed543a25msul1
course.msu_12679c3ed543a25msul1.url ---- msu/mmp/lbs267.sequence
course.msu_12679c3ed543a37msul1.description ---- Demo Course
course.msu_12679c3ed543a37msul1.domain ---- msu
course.msu_12679c3ed543a37msul1.home ---- msul1
course.msu_12679c3ed543a37msul1.last_cache ---- 990461725
course.msu_12679c3ed543a37msul1.num ---- 12679c3ed543a37msul1
course.msu_12679c3ed543a37msul1.url ---- msu/korte/demo.sequence

Information Imported from the Environment Database File of the User

environment.favorite.cake ---- Cheese Cake
environment.favorite.color ---- green
environment.firstname ---- Gerd
environment.id ---- z12345678
environment.lastname ---- Kortemeyer

Information about the Request

httpref./res/msu/mmp/ ---- /res/msu/mmp/welcome267.htm
request.ambiguous ---- adm/pages/index.html
request.course.fn ---- /home/httpd/perl/tmp/kortemey_msu_12679c3ed543a25msul1
request.course.id ---- msu_12679c3ed543a25msul1
request.course.sec ---- 
request.course.uri ---- msu/mmp/lbs267.sequence
request.filename ---- /home/httpd/html/adm/test
request.host ---- zaphod.lite.msu.edu
request.role ---- cc./msu/12679c3ed543a25msul1
request.state ---- published

Information about the User

user.domain ---- msu
user.environment ---- /home/httpd/lonIDs/kortemey_990461714_msu_msul1.id
user.home ---- msul1
user.login.time ---- 990461714
user.name ---- kortemey

Information about User Roles and Privileges

user.priv.au./msu/./ ---- :sma&F:gan&F
user.priv.au./msu/./msu/ ---- :cca&IK:are&F:bre&F:cre&F:ere&F
user.priv.ca./msu/korte./ ---- :sma&F:gan&F
user.priv.ca./msu/korte./msu/ ---- :are&F:bre&F:cre&F:ere&F
user.priv.ca./msu/korte./msu/korte ---- 
user.priv.cc./msu/12679c3ed543a16msul1./ ---- :sma&F:bre&F:mcr&F
user.priv.cc./msu/12679c3ed543a16msul1./msu/ ---- 
user.priv.cc./msu/12679c3ed543a16msul1./msu/12679c3ed543a16msul1 ---- :opa&F:srm&F:gan&F:are&F:ccr&IK:cep&IK:cta&IK:cre&F:cst&IK:cin&IK:ere&F:vgr&F
user.priv.cc./msu/12679c3ed543a25msul1./ ---- :sma&F:bre&F:mcr&F
user.priv.cc./msu/12679c3ed543a25msul1./msu/ ---- 
user.priv.cc./msu/12679c3ed543a25msul1./msu/12679c3ed543a25msul1 ---- :opa&F:srm&F:gan&F:cta&IK:cep&IK:ccr&IK:are&F:cin&IK:cst&IK:cre&F:ere&F:vgr&F
user.priv.cc./msu/12679c3ed543a37msul1./ ---- :sma&F:mcr&F:bre&F
user.priv.cc./msu/12679c3ed543a37msul1./msu/ ---- 
user.priv.cc./msu/12679c3ed543a37msul1./msu/12679c3ed543a37msul1 ---- :opa&F:srm&F:gan&F:are&F:ccr&IK:cep&IK:cta&IK:cre&F:cst&IK:cin&IK:ere&F:vgr&F
user.priv.cm./ ---- :sma&F:mcr&F:gan&F:bre&F
user.priv.cm./msu/ ---- :mau&F:cca&IK:cad&UIK:ccc&U:cst&UIK:cdg&UIK:are&F:cli&UIK:cta&UIK:cep&UIK:ccr&UIK:bre&F:cau&U:cre&F:cin&UIK:ere&F
user.priv.cm./msu/12679c3ed543a16msul1 ---- :opa&F:srm&F:gan&F:are&F:ccr&IK:cep&IK:cta&IK:cre&F:cst&IK:cin&IK:ere&F:vgr&F
user.priv.cm./msu/12679c3ed543a25msul1 ---- :opa&F:srm&F:gan&F:are&F:ccr&IK:cep&IK:cta&IK:cre&F:cst&IK:cin&IK:ere&F:vgr&F
user.priv.cm./msu/12679c3ed543a37msul1 ---- :opa&F:cst&IK:vgr&F:srm&F:gan&F:are&F:ccr&IK:cep&IK:cta&IK:cre&F:cin&IK:ere&F
user.priv.cm./msu/korte ---- 
user.priv.dc./msu/./ ---- :sma&F
user.priv.dc./msu/./msu/ ---- :mau&F:cad&UIK:ccr&UIK:cep&UIK:cta&UIK:cli&UIK:ccc&U:cau&U:cst&UIK:cin&UIK:cdg&UIK
user.role.au./msu/ ---- 964531839.0
user.role.ca./msu/korte ---- .
user.role.cc./msu/12679c3ed543a16msul1 ---- 964531839.0
user.role.cc./msu/12679c3ed543a25msul1 ---- 964531839.0
user.role.cc./msu/12679c3ed543a37msul1 ---- 964531839.0
user.role.dc./msu/ ---- 964531839.0
Session 4: Roles/Data Storage/Parameters
Domains
Every user in LON-CAPA is member of one domain. A domain can be institutional and "open", for example "msu" or "wscc" - open means that in it there can be students, authors and other users. A domain can also be functional, for example "timss_tests" or "smith_publishers. Physically, every domain needs at least one dedicated library server.
Userdata
Every user in the system has one library server, which is their home server. It stores the authoritative copy of all of their records. Internally, this data is stored in a directory 

 /home/httpd/lonUsers/domain/1.char/2.char/3.char/username/

for example
 /home/httpd/lonUsers/msu/s/m/i/smith/
ls -alF /home/httpd/lonUsers/msu/k/o/r/kortemey

-rw-r--r--   1 www      users       13006 May 15 12:21 activity.log
-rw-r-----   1 www      users       12413 Oct 26  2000 coursedescriptions.db
-rw-r--r--   1 www      users       11361 Oct 26  2000 coursedescriptions.hist
-rw-r-----   1 www      users       13576 Apr 19 17:45 critical.db
-rw-r--r--   1 www      users        1302 Apr 19 17:45 critical.hist
-rw-r-----   1 www      users       13512 Apr 19 17:45 email_status.db
-rw-r--r--   1 www      users        1496 Apr 19 17:45 email_status.hist
-rw-r--r--   1 www      users       12373 Apr 19 17:45 environment.db
-rw-r--r--   1 www      users         169 Apr 19 17:45 environment.hist
-rw-r-----   1 www      users       12315 Oct 25  2000 junk.db
-rw-r--r--   1 www      users        1590 Nov  4  1999 junk.hist
-rw-r-----   1 www      users       23626 Apr 19 17:45 msu_12679c3ed543a25msul1.db
-rw-r--r--   1 www      users        3363 Apr 19 17:45 msu_12679c3ed543a25msul1.hist
-rw-r-----   1 www      users       17242 Nov 13  2000 msu_1827338c7d339a3msul1.db
-rw-r--r--   1 www      users        1986 Nov 13  2000 msu_1827338c7d339a3msul1.hist
-rw-r-----   1 www      users       18497 Dec 21 11:25 msu_1827338c7d339b4msul1.db
-rw-r--r--   1 www      users        3801 Dec 21 11:25 msu_1827338c7d339b4msul1.hist
-rw-r-----   1 www      users       12470 Apr 19 17:45 nohist_annotations.db
-rw-r-----   1 www      users       13395 Nov 15  2000 nohist_bookmarks.db
-rw-r-----   1 www      users      104264 Apr 19 17:45 
			nohist_calculatedsheets_msu_12679c3ed543a25msul1.db
-rw-r-----   1 www      users       13248 Apr  5 17:18 
			nohist_calculatedsheets_msu_1827338c7d339b4msul1.db
-rw-r-----   1 www      users       12568 Oct 28  2000 nohist_coursedescriptions.db
-rw-r-----   1 www      users      765954 Apr 19 17:45 nohist_email.db
-rw-r--r--   1 www      users      710631 Apr 19 17:45 nohist_email.hist
-rw-r--r--   1 www      users          13 Apr 19 17:45 passwd
-rw-r--r--   1 www      users       12802 May  3 13:08 roles.db
-rw-r--r--   1 www      users        1316 Apr 12 16:05 roles.hist
Fig. 1.4.1  Directory listing of users home directory

Files ending on .db are GDBM files, files ending on .hist are logs of entries to these files. Filenames starting with nohist do not keep history files. passwd stores the login mechanism and password (if applicable). 

environment stores name-value pairs that are automatically added to the session environment at login time, for example the full name, etc. 

roles stores the userroles.

critical, nohist_email, and email_status are used by the messaging mechanisms

Files with a course-ID as name, for example msu_12679c3ed543a25msul1.db, store performance data for that student in the course, as stored by store and restore in lonnet.

Other files are caches, for example for previously calculated spreadsheets, etc.

Courses
Courses are assigned to users, not vice versa. Internally, courses are handled like users without login privileges. The username is a unique ID, for example msu_12679c3ed543a25msul1  every course in every semester has a unique ID, there is no semester transition. The userdata of the course includes the full name of the course, a pointer to its top-level resource map (course map), and any associated deadlines, spreadsheets, etc., as well as a course enrollment list. The latter is somewhat redundant, since in principle, this list could be produced by going through the roles of all users, and looking for the valid role of being student in that course.

ls -alF /home/httpd/lonUsers/msu/1/2/6/12679c3ed543a25msul1/

-rw-r-----   1 www      users       17155 Apr 25 16:20 classlist.db
-rw-r--r--   1 www      users       60912 Apr 25 16:20 classlist.hist
-rw-r-----   1 www      users       12354 Jan  4 16:40 environment.db
-rw-r--r--   1 www      users          82 Jan  4 16:40 environment.hist
-rw-r-----   1 www      users      103030 May 15 14:47 nohist_calculatedsheets.db
-rw-r-----   1 www      users       13050 May  9 21:04 nohist_expirationdates.db
-rw-r--r--   1 www      users           6 Jan  4 16:40 passwd
-rw-r-----   1 www      users       17457 May  9 21:04 resourcedata.db
-rw-r--r--   1 www      users        8888 May  9 21:04 resourcedata.hist
Fig. 1.4.2  Directory listing of courses home directory

classlist is this list of students in the course, environment includes the courses full name, etc, and resourcedata are deadlines, etc (parameters for homework).
Roles
Users keep their login, data, preferences, etc, over their complete tenure. Every user can have several roles, and the roles can change over the lifetime of a username. For example, over the course of studies, a student username assumes the role of "student" in different courses. Roles can have start and expiration dates.

Example: User smith at msuInstructormsu_12679c3ed543a25msul1Course Coordinatormsu_12679c3ed543a25msul1From July 1st, 2001 to December 30th, 2001Instructormsu_18879c3ed543a25msul2From Jan 1st, 2001 to June 30th, 2001Resource AuthormsuFrom Aug 15th, 2000Studentmsu_82679c3gd543a35msul1From July 1st, 2001 to December 30th, 2001Fig. 1.4.3  Sample Instructor Roles

Example: User jones at msuCustom Role "Helproom TA (smith at msu)"msu_82679c3gd543a35msul1From July 1st, 2001 to December 30th, 2001Studentmsu_02679c3gq543a35msul1From Jan 1st, 2001 to June 30th, 2001Studentumn_82679c3gd543a35umnl2From July 1st, 2001 to December 30th, 2001Exam Proctormsu_82679c3gd543a35msul1Feb 21st, 2001, 1pm to 3pmFig. 1.4.4  Sample Student Roles
Custom Roles

Course Coordinators are able to define named "Custom Roles" for their courses within a pre-defined set of capabilities. In addition to these custom roles, there are three standard course faculty/staff roles defined, Instructor, Exam Proctor and TA. The instructor of record in a small class is likely to be "Course Coordinator" and "Instructor" during the term when the course is running, and might remain course coordinator afterwards. Course coordinator can assign themselves new roles for their course anytime.

Custom role definitions are stored in the roles.db file of the role author.

Choose a Role, Role Privileges
lonroles is a handler that allows a user to switch roles in mid-session. LON-CAPA attempts to work with No Role Specified as widely as possible, but certain handlers for example need specification which course they should act on, etc. Both in this scenario, and when the handler determines via lonnets &allowed function that a certain action is not allowed, lonroles is used as errorhandler. lonroles can also be accessed via the CRS button in the Remote Control. Fig 1.4.5 shows a sample output of lonroles.


&
Fig. 1.4.5  Sample Roles Choice in lonroles.pm
System: /
Browse resources
Generate anonymous statistics
Create a Course Custom Role
Send internal email
Domain: msu
Assemble resources
Browse resources
Grant/revoke role of Administrator (UNIX authenticated, Internally authenticated, Kerberos authenticated)
Grant/revoke role of Author (UNIX authenticated)
Grant/revoke role of Co-Author (Internally authenticated, Kerberos authenticated)
Grant/revoke role of Course Coordinator (UNIX authenticated)
Grant/revoke Course Custom Role (UNIX authenticated, Internally authenticated, Kerberos authenticated)
Grant/revoke role of Domain Guest (UNIX authenticated, Internally authenticated, Kerberos authenticated)
Grant/revoke role of Exam Proctor (UNIX authenticated, Internally authenticated, Kerberos authenticated)
Grant/revoke role of Instructor (UNIX authenticated, Internally authenticated, Kerberos authenticated)
Grant/revoke role of Librarian (UNIX authenticated, Internally authenticated, Kerberos authenticated)
Copy resources
Grant/revoke role of Student (UNIX authenticated, Internally authenticated, Kerberos authenticated)
Grant/revoke role of Teaching Assistant (UNIX authenticated, Internally authenticated, Kerberos authenticated)
Create, edit, modify and publish resources
Modify authentication mechanism and data for a user
Course: lbs267L Lab SS01
Assemble resources
Grant/revoke Course Custom Role (Internally authenticated, Kerberos authenticated)
Grant/revoke role of Exam Proctor (Internally authenticated, Kerberos authenticated)
Grant/revoke role of Instructor (Internally authenticated, Kerberos authenticated)
Copy resources
Grant/revoke role of Student (Internally authenticated, Kerberos authenticated)
Grant/revoke role of Teaching Assistant (Internally authenticated, Kerberos authenticated)
Create, edit, modify and publish resources
Generate anonymous statistics
Set assessment parameters
Send broadcast and receipt-required email
View grades
Course: lbs267 Lecture SS01
Assemble resources
Grant/revoke Course Custom Role (Internally authenticated, Kerberos authenticated)
Grant/revoke role of Exam Proctor (Internally authenticated, Kerberos authenticated)
Grant/revoke role of Instructor (Internally authenticated, Kerberos authenticated)
Copy resources
Grant/revoke role of Student (Internally authenticated, Kerberos authenticated)
Grant/revoke role of Teaching Assistant (Internally authenticated, Kerberos authenticated)
Create, edit, modify and publish resources
Generate anonymous statistics
Set assessment parameters
Send broadcast and receipt-required email
View grades
Course: Demo Course
Assemble resources
Grant/revoke Course Custom Role (Internally authenticated, Kerberos authenticated)
Grant/revoke role of Exam Proctor (Internally authenticated, Kerberos authenticated)
Grant/revoke role of Instructor (Internally authenticated, Kerberos authenticated)
Copy resources
Grant/revoke role of Student (Internally authenticated, Kerberos authenticated)
Grant/revoke role of Teaching Assistant (Internally authenticated, Kerberos authenticated)
Create, edit, modify and publish resources
Generate anonymous statistics
Set assessment parameters
Send broadcast and receipt-required email
View grades
Construction Space: User: korte, Domain: msu
Fig. 1.4.6  Sample Set of Privileges

Fig. 1.4.6 shows a common set of privileges for the user roles in Fig. 1.4.5. The plain text explanations of the various roles and the extent of them is drawn from /home/httpd/rolesplain.tab, see Fig. 1.4.7.

[www@zaphod www]$ more /home/httpd/lonTabs/rolesplain.tab
s:system wide
d:domain wide
c:course wide
U:UNIX authenticated
I:Internally authenticated
K:Kerberos authenticated
C:according to course preferences
S:according to custom role settings
R:according to resource settings
L:unless locked
X:according to user session state
F:no restrictions
cm:No Role, Cumulative Privileges
su:Superuser
dc:Domain Coordinator
cc:Course Coordinator
in:Instructor
ta:Teaching Assistant
ep:Exam Proctor
cr:Course Custom Role
st:Student
ad:Administrator
li:Librarian 
au:Author
dg:Domain Guest
ca:Co-Author
csu:Grant/revoke role of Superuser
cdc:Grant/revoke role of Domain Coordinator
ccc:Grant/revoke role of Course Coordinator
cin:Grant/revoke role of Instructor
cta:Grant/revoke role of Teaching Assistant
cep:Grant/revoke role of Exam Proctor
ccr:Grant/revoke Course Custom Role
cst:Grant/revoke role of Student
cad:Grant/revoke role of Administrator
cli:Grant/revoke role of Librarian
cau:Grant/revoke role of Author
cdg:Grant/revoke role of Domain Guest
cca:Grant/revoke role of Co-Author
mcr:Create a Course Custom Role
mau:Modify authentication mechanism and data for a user
bre:Browse resources
are:Assemble resources
cre:Copy resources
ere:Create, edit, modify and publish resources
mme:Modify metadata for a resource 
vgr:View grades
mgr:Modify grades
gan:Generate anonymous statistics
dcm:Disable all communication among students
sma:Send internal email
srm:Send broadcast and receipt-required email
pch:Post to chatrooms and bulletin boards
dch:Delete messages from bulletin boards
pac:Post anonymously
rin:Get identity behind anonymous postings
las:Lock and unlock assessments
opa:Set assessment parameters
ain:Assume a student's identity 

Fig. 1.4.7  Explanation of Privilege Shorthands

Role Initialization
The privileges for a user are established at login time and stored in the session environment. A consequence is that a new role does not become active till the next login. Handlers are able to query for privileges using lonnets &allowed function. When a user first logs in, their role is the common role, which means that they have the sum of all of their privileges. During a session it might become necessary to choose a particular role, which as a consequence also limits the user to only the privileges in that particular role.

[www@zaphod www]$ more /home/httpd/lonTabs/roles.tab
su:s csu&U:sma:mau:cdc&U
dc:s sma
dc:d cli&UIK:cau&U:cdg&UIK:mau:ccc&U:cin&UIK:cta&UIK:cep&UIK:ccr&UIK:cst&UIK:cad&UIK
cc:s bre:sma:mcr
cc:c cin&IK:cta&IK:cep&IK:ccr&IK:cst&IK:are:cre:ere:vgr:gan:srm:opa
in:s sma
in:d bre
in:c vgr:mgr:gan:dcm:srm:pch:dch:pac:rin:las:opa
ta:d sma
ta:c bre&RL:vgr&CR:mgr&CR:srm:pch:dch:pac
ep:d sma
ep:c bre&R:mgr&R:dcm:las
cr:d sma
cr:c bre&R:vgr&SCR:mgr&SCR:gan&SCR:dcm&SC:srm&SC:pch:dch&S:pac:rin&S:las&SR:opa&SR
st:d sma&L
st:c bre&RXL:pch&L:pac&CL
ad:d sma
ad:c bre:gan:vgr:srm
li:s gan:sma
li:d mme
au:s gan:sma
au:d bre:are:cre:ere:cca&IK
ca:s gan:sma
ca:d bre:are:cre:ere
dg:d bre&R
Fig. 1.4.8  Privileges by roles and extent

Role Assignment

&
Fig. 1.4.9  Assigning privileges to a user

loncreateuser.pm  allows users to within their own privileges (cxx privileges) create users and give them roles (Fig. 1.4.9) 
londropadd.pm allows course coordinators to upload courselists in different formats, and automatically create users (if they do not exist already), assign them the role of student in a course, and add them to the classlist. 
loncreatecourse.pm allows domain coordinators to create new courses and assign course coordinators.
Day 2
Session 1: Publication/Content Maps/Course Maps
Publication of a Resource

Authors can only write-access the /~authorname/ space. They can copy resources into the resource area through the publication step, and move them back through a recover step. Authors do not have direct write-access to their resource space. 

During the publication step, several events will be triggered. Metadata is gathered, where a wizard manages default entries on a hierarchical per-directory base: The wizard imports the metadata (including access privileges and royalty information) from the most recent published resource in the current directory, and if that is not available, from the next directory above, etc. The Network keeps all previous versions of a resource and makes them available by an explicit version number, which is inserted between the file name and extension, for example foo.2.html, while the most recent version does not carry a version number (foo.html). Servers subscribing to a changed resource are notified that a new version is available.

Content Re-usage and Granularity

Any faculty participating in the Network can publish their own learning resources into the common pool. To that end, the Network provides a construction space which is only accessible to the author, and a publication process, which transfers the material to the shared pool  during the publication process, metadata about the resource is gathered, and system-wide update notification and versioning mechanisms are triggered..

Learning resources could be simple paragraphs of text, movies, applets, individualizing homework problems, etc. In addition to providing a distributed digital library with mechanisms to store and catalog these resources, the Network enables faculty to combine and sequence these resources at several levels: An instructor from Community College A could combine a text paragraph from University B with a movie from College C and an online homework problem from Publisher D, to form one page. Another instructor from High School E can take that page from Community College A and combine it with other pages into a module, unit or chapter. Those in turn can be combined into whole coursepacks. Faculty can design their own curricula from existing and newly created resources instead of having to buy into a complete off-the-shelf product.

Fig. 2.1.1 shows a general overview of the resource assembly mechanism and the different levels of content granularity supported by the current implementation of this principle. The topmost puzzle piece represents a resource at the fragment level  one GIF, one movie, one paragraph of text, one problem, or one regular web page. Attached to the resource is metadata gathered at the publication time of the resource.

Using the resource assembly tool described below, these fragments and pages can be assembled into a page. A page is a resource of the grain size which would be rendered as one page on the web and/or on the printer.

Using the same tool, fragments (which would then be rendered as standalone pages), pages and sequences can be assembled into sequences. Sequences are resources which are rendered a sequence of pages, not necessarily linear. Examples are one lesson, one chapter, or one learning cycle

On the third granularity level, fragments (rendered as standalone pages), pages, and sequences can be assembled into courses. Courses are a sequence which represents the entirety of the resources belonging to a learning unit into which learners can be enrolled. Examples are a University one-semester course, a
workshop, or a High School class.
&

Fig 2.1.1  Resource Assembly
Maps

To increase the utility of the materials, the number of hard-coded hyperlinks between the resources should be minimized. The actual combining and sequencing is part of the system functionality and driven by external "roadmaps", which are constructed by the instructors. With this mechanism, one and the same resource can be part of different courses in different contexts. The soft-linking makes it possible to import only the desired set of resources without effectively importing additional parts another instructors resources through hard-linked menus or "next page" buttons that might resided on those resources.
Curriculum Adaptivity
Maps allow for conditional choices and branching points. The actual path through and presentation of the learning resources is determined by instructor-specified combinations of learner choices and system-generated adaptations (for example, if the learner does not pass a test, additional resources may be included). Each learner can have an individualized curriculum according to preferences, capabilities and skills.

These maps can be generated at different levels of granularity with a graphical tool, or in an automated way through custom scripts.
Resource Assembly Tool
The Network provides the Resource Assembly Tool as one means to generate maps. The Resource Assembly Tool provides a graphical user interface inside of a standard web browser. The current implementation is written in JavaScript. 

Fig. 2.1.2 shows screenshots of the current implementation. The interface usually consists of two browser windows, one resizable one with a frameset that contains the menu and the map under construction, and a multipurpose non-resizable window that displays information and input forms.

When a new map is started, it only has a start and a finish resources. The author can then enlarge the map area and insert resources into it.

In Fig. 2.1.2A, the author is editing information about a resource in the map after clicking on the box representing the resource in the map. In the dialog, the author can enter a map-internal title for the resource, which is displayed to the learners when navigating the maps. In the same dialog, the author will specify the URL of the resource, which can either be internal to the Network, or any URL of a web page outside of it. For internal resources, the author can also browse the Network filesystem or search the resource metadata to locate an appropriate resource.

&Fig. 2.1.2A  Example, Graphical User Interface of Resource Assembly Tool


The resource priority can be chosen. A resource can be regular, mandatory or optional. These resource priorities are only used in book-keeping of earned points by the learners. Within the map, resources of different priorities are displayed in different colors.

The dialog also allows for two modes of removing the resource from the map: deleting it from the map including every link to and from it, and deleting it while reconnecting any links that went through the resource. As an example, resources A and B might both connect to resource C, and resource C might connect to D. When removing C from the map using the first option, A and B will not be connected to D anymore. Using the second option, in the end, A will connect to D, and B will connect to D. In the latter case, the Resource Assembly tool will also handle link conditions correctly: if A connected to C under condition 1, and C connected to D under condition 2, then in the end A will connect to D under a new condition which is (1 AND 2).

Finally, this dialog allows the author to connect the resource to another resource (or itself) through a new link. When selecting this option, the Resource Assembly Tool goes into link mode, and will link the current resource to the next resource clicked on (unless the action is cancelled).


&


Fig. 2.1.2B  Example, Graphical User Interface of Resource Assembly Tool

Fig. 2.1.2B shows the Resource Assembly Tool in info mode, that is, when no specific component of the map is edited, and if the Tool is not in link mode. In info mode, the contents of the dialog window change dynamically as the mouse is moved over the components of the map. In this case, the mouse pointer is over the link condition between two resources. The dialog window shows the titles of the connected resources, as well as the condition priority. In this scenario, the condition priority is set such that the link cannot be taken (is blocked) if the condition is false. The condition priority can also be set such that the link is recommended if the condition is true (possibly giving the learner several options where to go next), or that the link has to be taken (is forced) over any other possible link if the condition is true. Within the map, conditions of different priorities are displayed in different colors. If the author now were to click on the condition, the Tool would go into edit mode, and the condition could be edited.

Fig. 2.1.2C shows the Tool in edit mode for the link between the resource titles displayed. The author can remove the link, or insert a new resource into the link.

Obviously, by this mechanism, rather complex maps can be generated. These are different from binary trees, both because branches can loop back, and because branches can be re-united  in fact, most branches re-unite in the finish resources. Into each link, a condition with one of three different priorities can be attached. Whether or not a certain resource in the map can be displayed depends on whether or not it can be reached through any path along allowed links, starting with the start resource of the course. If a resource is not linked to, it is assumed to be accessible if the map which it is part of is accessible.


&

Fig. 2.1.2C  Example, Graphical User Interface of Resource Assembly Tool 
Map Representation and Storage Format
Fig. 2.1.3 shows the XML representation of the resource map constructed in Fig. 2.1.2, which is the format in which maps are stored. In the figure, however, additional graphical map layout information generated by the Resource Assembly Tool is not displayed. This graphical information is optional to re-generate the same graphical layout when the map is brought up again in the Resource Assembly Tool, and is not needed for any other system functionality.

Maps can be generated by tools other than the Resource Assembly Tool. In particular, an author might have some other representation of a course sequence, which can be converted into a map using scripts. If this map then were to be brought up in the Resource Assembly Tool, the Tool would automatically generate a graphical layout for it. Each entry of the map (resources, conditions and links) is stored in a separate tag. 

Resources and conditions have to have unique ID numbers. These numbers are automatically generated by the Resource Assembly Tool when the entry is first created, or added to the entries when a map generated outside the Resource Assembly Tool is first retrieved. They can also be assigned by custom scripts or added in by hand.

In this example, Fig. 2.1.3, entry 1 is the start resource of the map  when this map is accessed, the source (src) URL of this tag will be the first resource rendered. Entry 2 is the finish resource of this map. This resource will be the last resource in the sequence of resources. Entry 6 is a problem resource with the given URL and title, as well as the priority mandatory. Entry 19 is a condition, which is used by the link between entries 6, the problem, and 9, a sequence. The final syntax for conditions has not yet been determined.

<map>
<resource id="1" 
          src="/res/msu/korte/phy231welcome.html" 
          type="start" 
          title="Start"></resource>
<resource id="2" 
          src="" type="finish" 
          title="Finish"></resource>
<resource id="6" 
          src="/res/msu/korte/tests/units.problem" 
          type="mandatory" 
          title="Physical Units Test"></resource>
<resource id="9" 
          src="/res/msu/korte/chapters/onedim.sequence" 
          title="Motion in One Dimension"></resource>
<resource id="11" 
          src="/res/msu/bauer/bridges/units.sequence" 
          title="Physical Units Refresher"></resource>
<condition id="19" 
         type="stop"                 
         value="user.assessments[this./res/msu/korte/tests/units.problem].status=solved">
  </condition>
<link from="1" to="6"></link>
<link from="6" to="9" condition="19"></link>
<link from="6" to="11"></link>
<link from="11" to="6"></link>
</map>
Fig. 2.1.3  XML representation of the map in Fig. 2.1.2C (non-graphical information only).
Example of Nested Maps

Fig. 2.1.4 shows the XML representation of three maps which are imported into each other. Fig. 2.1.4B is the sequence that is referenced as resource 9 in the course map Fig. 2.1.4A. In the resulting map, the entry point of resource 9 in Fig. 2.1.4A is in fact the entry point of the start resource of Fig. 2.1.4B, namely, resource 1 there. The exit point of resource 9 in Fig. 2.1.4A is the exit point of the finish resource of Fig. 2.1.4B, namely, resource 2 there.

Fig. 2.1.4C is the page which is referenced as resource 24 in Fig. 2.1.4B.

A course can easily contain several hundreds of these nested maps. Since the accessibility of each individual resource in the course depends on the state of all possible paths linking it to the start resource of the course across all intermediate maps, the computation and disk-I/O effort per single transaction could quickly become prohibitive. Thus, all maps and conditions are compiled into a pre-processed binary data structure at the start of a session.

<map>
<resource id="1" src="" type="start" title="Start"></resource>
<resource id="2" src="" type="finish" title="Finish"></resource>
<resource id="5" src="/res/msu/korte/tests/pretest.problem" type="mandatory"  
  title="Pretest"></resource>
<resource id="9" src="/res/msu/korte/parts/part1.sequence" type="mandatory" 
  title="Part 1"></resource>
<resource id="11" src="/res/msu/korte/tests/midterm.sequence" type="mandatory" 
  title="Midterm"></resource>
<resource id="15" src="/res/msu/korte/parts/part2.sequence" type="mandatory" 
  title="Part 2"></resource>
<condition id="19" type="stop" 
  value="user.assessments[this./msu/korte/tests/pretest.problem].status=solved">
  </condition>
<resource id="20" src="/res/msu/korte/refresh/refresher.sequence" 
  title="Refresher"></resource>
<resource id="29" src="/res/msu/korte/tests/final.sequence" type="mandatory" 
  title="Final Exam"></resource>
<condition id="30" type="stop" 
  value="user.assessments[this./msu/korte/tests/midterm.sequence].percent>60">
  </condition>
<resource id="36" src="/res/msu/korte/refresh/review.sequence"
  title="Review"></resource>
<condition id="43" type="force" 
  value="user.assessments[this./msu/korte/tests/midterm.sequence].percent<10">
  </condition>
<resource id="58" src="/res/msu/korte/chapters/applications.sequence" type="optional"  
  title="Applications"></resource>
<condition id="70" type="stop"  
  value="user.assessments[this./msu/korte/tests/final.sequence].percent>60">
  </condition>
<link from="1" to="5"></link>
<link from="9" to="11"></link>
<link from="11" to="15" condition="30"></link>
<link from="5" to="9" condition="19"></link>
<link from="5" to="20"></link>
<link from="20" to="5"></link>
<link from="11" to="36" condition="43"></link>
<link from="36" to="9"></link>
<link from="36" to="11"></link>
<link from="15" to="29"></link>
<link from="29" to="2" condition="70"></link>
<link from="11" to="11"></link>
</map>
Fig. 2.1.4A  Example of a course map that has nested sequences

<map>
<resource id="1" src="" type="start" title="Start"></resource>
<resource id="2" src="" type="finish" title="Finish"></resource>
<resource id="5" src="/res/msu/korte/parts/part1intro.html" 
  title="Part 1 Introduction"></resource>
<resource id="6" src="/res/msu/korte/parts/part1dir.xml" title="Directions"></resource>
<resource id="12" src="/res/msu/korte/tests/part11.problem" title="Problem 1"></resource>
<resource id="13" src="/res/msu/korte/tests/part13.problem" title="Problem 3"></resource>
<resource id="19" src="/res/msu/korte/tests/part12.problem" title="Problem 2"></resource>
<resource id="24" src="/res/msu/korte/parts/summary.page" title="Summary"></resource>
<condition id="47" type="stop"
  value="user.assessments[this./msu/korte/tests/part11.problem].status=solved">
  </condition>
<condition id="48" type="stop"     
  value="user.assessments[this./msu/korte/tests/part12.problem].status=solved">
  </condition>
<condition id="49" type="stop"   
  value="user.assessments[this./msu/korte/tests/part13.problem].status=solved">
  </condition>
<link from="5" to="6"></link>
<link from="1" to="5"></link>
<link from="6" to="12"></link>
<link from="6" to="13"></link>
<link from="6" to="19"></link>
<link from="12" to="24" condition="47"></link>
<link from="19" to="24" condition="48"></link>
<link from="13" to="24" condition="49"></link>
<link from="24" to="2"></link>
</map>
Fig. 2.1.4B  Example of a sequence (part1.sequence) that has nested pages

<map>
<resource id="1" src="" type="start" title="Start"></resource>
<resource id="2" src="" type="finish" title="Finish"></resource>
<resource id="5" src="/res/msu/smith/racecar.problem"></resource>
<resource id="6" src="/res/msu/smith/toofast.html"></resource>
<resource id="8" src="/res/msu/smith/tooslow.html"></resource>
<resource id="15" src="/res/msu/smith/accelerate.html"></resource>
<condition id="40" type="force" 
  value="user.assessments[this./msu/smith/racecar.problem].status=solved"></condition>
<condition id="41" type="stop" 
  value="user.assessments[this./msu/smith/racecar.problem].answer=friction"></condition>
<condition id="42" type="stop" 
  value="user.assessments[this./msu/smith/racecar.problem].answer=sliding"></condition>
<condition id="43" type="stop" 
value="user.assessments[this./msu/smith/racecar.problem].answer=nonconstant"></condition>
<link from="1" to="5"></link>
<link from="5" to="6" condition="41"></link>
<link from="5" to="8" condition="42"></link>
<link from="5" to="15" condition="43"></link>
<link from="6" to="2"></link>
<link from="8" to="2"></link>
<link from="15" to="2"></link>
<link from="5" to="2" condition="40"></link>
</map>
Fig. 2.1.4C  Example of a page (summary.page)
&

Fig. 2.1.5  Flow chart of the course initialization routine run when a learner first accesses a course during a session (see Figs. 2.1.6A and 2.1.8A for the procedures loadmap and traceroute)
Initialization of a Course for a Learner
When a learner first enters a course during a session, the system will initialize this course for the learner. In particular, at this point, the course map and all nested (embedded) maps and resources are evaluated, and the information is compiled into two binary structures, which are stored with the session information: the resource properties hash, and the link conditions array. This information will be used over the duration of the session for several purposes: navigation (which resource is the next, which one the previous?), for access control (can the resource be reached under the link conditions given the current state of the student?), and to register assessment results within the context of a certain course and map (there might be several instances of the same problem resource within a course).

Evaluation of the Map Structure for a Course

The URL of the course is passed to the procedure readmap (Fig. 2.1.5).  Procedure readmap first initializes the resource properties as an empty hash, seeds the link conditions array with a 0th element, which is set to true, priority normal, and sets the map counter to 0 (Fig. 2.1.5, Step R1). While the resource properties hash, the link conditions array and the map counter are global variable of the initialization process, all other variables are local to the procedures (an important property for these routines to run recursively). The procedure readmap then calls procedure loadmap for the URL of the course (Fig. 2.1.5, Step R2).

Figs. 2.1.6, 2.1.7 show a dump of excerpts of the binary structure generated in loadmap for the nested maps of example Fig. 2.1.4.

Procedure loadmap (Fig. 2.1.6A) first checks if the map URL has already been processed (multiple inclusion of the same map in a course structure) (Fig. 2.1.6A, Step L1)  if it was, it has been assigned a map counter value in the resource properties hash. If the map has been processed, there is no need to process it again, and loadmap returns.


If the map has not been processed yet, the map counter is incremented and the map is registered under the current value in the resource properties hash (Fig. 2.1.6A, Step L2). The file is then opened (Fig. 2.1.6A, Step L3), which might entail prior replication, and the contents are parsed. If there are no further entries, loadmap returns (Fig. 2.1.6A, Step L4).

The new entry tag is then read (Fig. 2.1.6A, Step L5) and the type is determined (Fig. 2.1.6A, Step L6). 

If the entry is a resource (Step L7), a resource ID is formed by combining the map counter and the resource ID within the map. For example, the Part I Introduction resource of part1.sequence (Fig. 2.1.4B) was assigned the resource ID 2.5, since it has the internal resource ID 5 in the 2nd map processed (see Fig. 2.1.6B under ids_). If the same URL is found again, additional IDs are assigned to it. It is necessary to store the IDs under the URL in the resource properties hash for reverse lookup if a user simply requests a URL. If the resource is a start or finish resources, the resource ID is registered as the start or finish resource of the map, respectively (Fig. 2.1.6B, map_start_, map_finish_). The properties of the resource (URL, Title, Priority, etc) are now stored under the resource ID, see for example Fig. 2.1.6B title_2.5.

If the resource is not a map itself (Fig. 2.1.6A, Step L8), the next entry is read. Otherwise, procedure loadmap calls itself recursively to process that map (Step L9).

If in Step L6, the type of the entry was determined to be a condition, a condition ID is formed (Step L10) by again combining the map counter with the internal ID. The condition is also added to the end of the condition array (see Fig. 10), which is a compilation of all conditions in the course (Step L11). The conditions in this array are evaluated when a transaction occurs that could change the state of the student, and the state of each condition is stored by the index number in the session environment. A reference to the index number in the condition array is stored under the condition ID (Fig. 2.1.6D, condid_).

If the entry is a link (Step L6), a link ID is generated (Step L12). This ID is formed by combining the map counter and another counter which is incremented for every new link within the map. Under this ID, the IDs of the originating and the destination resource of the link are stored, as well as that of the link condition (Fig. 2.1.6D). For the originating resource, in Step L13 the link ID is added to the list of outgoing links (Fig. 2.1.6C, to_), and for the destination resource, the link ID is added to the list of incoming links (Fig. 2.1.6C, from_).

After the last entry has been processed, procedure loadmap returns. After the last map has been processed, the original course-level instance of loadmap returns to readmap (Fig. 2.1.5, Step R2).

&

Fig. 2.1.6A  Flow chart of procedure loadmap

ids_/res/msu/korte/chapters/applications.sequence: 1.58
ids_/res/msu/korte/parts/part1.sequence: 1.9
ids_/res/msu/korte/parts/part1dir.xml: 2.6
ids_/res/msu/korte/parts/part1intro.html: 2.5
ids_/res/msu/korte/parts/part2.sequence: 1.15
ids_/res/msu/korte/parts/summary.page: 2.24
ids_/res/msu/korte/refresh/refresher.sequence: 1.20
ids_/res/msu/korte/refresh/review.sequence: 1.36
ids_/res/msu/korte/tests/final.sequence: 1.29
ids_/res/msu/korte/tests/midterm.sequence: 1.11
ids_/res/msu/korte/tests/part11.problem: 2.12
ids_/res/msu/korte/tests/part12.problem: 2.19
ids_/res/msu/korte/tests/part13.problem: 2.13
ids_/res/msu/korte/tests/pretest.problem: 1.5
ids_/res/msu/smith/accelerate.html: 3.15
ids_/res/msu/smith/racecar.problem: 3.5
ids_/res/msu/smith/toofast.html: 3.6
ids_/res/msu/smith/tooslow.html: 3.8

map_start_/res/msu/korte/foo.sequence: 1.1
map_start_/res/msu/korte/parts/part1.sequence: 2.1
map_start_/res/msu/korte/parts/summary.page: 3.1

map_finish_/res/msu/korte/foo.sequence: 1.2
map_finish_/res/msu/korte/parts/part1.sequence: 2.2
map_finish_/res/msu/korte/parts/summary.page: 3.2

title_1.11: Midterm
title_1.15: Part 2
title_1.20: Refresher
title_1.29: Final Exam
title_1.36: Review
title_1.5: Pretest
title_1.58: Applications
title_1.9: Part 1
title_2.12: Problem 1
title_2.13: Problem 3
title_2.19: Problem 2
title_2.24: Summary
title_2.5: Part 1 Introduction
title_2.6: Directions


Fig. 2.1.6B  Dump of the resource properties hash. Excerpt of the resource properties gathered in procedure loadmap

to_1.1: 1.1
to_1.11: 1.3,1.7,1.12
to_1.15: 1.10
to_1.20: 1.6
to_1.29: 1.11
to_1.36: 1.8,1.9
to_1.5: 1.4,1.5
to_1.9: 1.2
to_2.1: 2.2
to_2.12: 2.6
to_2.13: 2.8
to_2.19: 2.7
to_2.24: 2.9
to_2.5: 2.1
to_2.6: 2.3,2.4,2.5
to_3.1: 3.1
to_3.15: 3.7
to_3.5: 3.2,3.3,3.4,3.8
to_3.6: 3.5
to_3.8: 3.6

from_1.11: 1.2,1.9,1.12
from_1.15: 1.3
from_1.2: 1.11
from_1.20: 1.5
from_1.29: 1.10
from_1.36: 1.7
from_1.5: 1.1,1.6
from_1.9: 1.4,1.8
from_2.12: 2.3
from_2.13: 2.4
from_2.19: 2.5
from_2.2: 2.9
from_2.24: 2.6,2.7,2.8
from_2.5: 2.2
from_2.6: 2.1
from_3.15: 3.4
from_3.2: 3.5,3.6,3.7,3.8
from_3.5: 3.1
from_3.6: 3.2
from_3.8: 3.3

Fig. 2.1.6C  Dump of the resource properties hash. Excerpt of information gathered about links between resources in subroutine loadmap.


goesto_1.1: 1.5
goesto_1.10: 1.29
goesto_1.11: 1.2
goesto_1.12: 1.11
goesto_1.2: 1.11
goesto_1.3: 1.15
goesto_1.4: 1.9
goesto_1.5: 1.20
goesto_1.6: 1.5
goesto_1.7: 1.36
goesto_1.8: 1.9
goesto_1.9: 1.11
goesto_2.1: 2.6
goesto_2.2: 2.5
goesto_2.3: 2.12
goesto_2.4: 2.13
goesto_2.5: 2.19
goesto_2.6: 2.24
goesto_2.7: 2.24
goesto_2.8: 2.24
goesto_2.9: 2.2
goesto_3.1: 3.5
goesto_3.2: 3.6
goesto_3.3: 3.8
goesto_3.4: 3.15
goesto_3.5: 3.2
goesto_3.6: 3.2
goesto_3.7: 3.2
goesto_3.8: 3.2
comesfrom_1.1: 1.1
comesfrom_1.10: 1.15
comesfrom_1.11: 1.29
comesfrom_1.12: 1.11
comesfrom_1.2: 1.9
comesfrom_1.3: 1.11
comesfrom_1.4: 1.5
comesfrom_1.5: 1.5
comesfrom_1.6: 1.20
comesfrom_1.7: 1.11
comesfrom_1.8: 1.36
comesfrom_1.9: 1.36
comesfrom_2.1: 2.5
comesfrom_2.2: 2.1
comesfrom_2.3: 2.6
comesfrom_2.4: 2.6
comesfrom_2.5: 2.6
comesfrom_2.6: 2.12
comesfrom_2.7: 2.19
comesfrom_2.8: 2.13
comesfrom_2.9: 2.24
comesfrom_3.1: 3.1
comesfrom_3.2: 3.5
comesfrom_3.3: 3.5
comesfrom_3.4: 3.5
comesfrom_3.5: 3.6
comesfrom_3.6: 3.8
comesfrom_3.7: 3.15
comesfrom_3.8: 3.5
undercond_1.1: 0
undercond_1.10: 0
undercond_1.11: 1.70
undercond_1.12: 0
undercond_1.2: 0
undercond_1.3: 1.30
undercond_1.4: 1.19
undercond_1.5: 0
undercond_1.6: 0
undercond_1.7: 1.43
undercond_1.8: 0
undercond_1.9: 0
undercond_2.1: 0
undercond_2.2: 0
undercond_2.3: 0
undercond_2.4: 0
undercond_2.5: 0
undercond_2.6: 2.47
undercond_2.7: 2.48
undercond_2.8: 2.49
undercond_2.9: 0
undercond_3.1: 0
undercond_3.2: 3.41
undercond_3.3: 3.42
undercond_3.4: 3.43
undercond_3.5: 0
undercond_3.6: 0
undercond_3.7: 0
undercond_3.8: 3.40

condid_1.19: 8
condid_1.30: 9
condid_1.43: 10
condid_1.70: 11
condid_2.47: 5
condid_2.48: 6
condid_2.49: 7
condid_3.40: 1
condid_3.41: 2
condid_3.42: 3
condid_3.43: 4

Fig. 2.1.6D  Dump of the resource properties hash. Excerpt of information gathered about links and link conditions between resources in subroutine loadmap.

0 : true:normal
1 : user.assessments[this./msu/smith/racecar.problem].status=solved:force
2 : user.assessments[this./msu/smith/racecar.problem].answer=friction:stop
3 : user.assessments[this./msu/smith/racecar.problem].answer=sliding:stop
4 : user.assessments[this./msu/smith/racecar.problem].answer=nonconstant:stop
5 : user.assessments[this./msu/korte/tests/part11.problem].status=solved:stop
6 : user.assessments[this./msu/korte/tests/part12.problem].status=solved:stop
7 : user.assessments[this./msu/korte/tests/part13.problem].status=solved:stop
8 : user.assessments[this./msu/korte/tests/pretest.problem].status=solved:stop
9 : user.assessments[this./msu/korte/tests/midterm.sequence].percent>60:stop
10 : user.assessments[this./msu/korte/tests/midterm.sequence].percent<10:force
11 : user.assessments[this./msu/korte/tests/final.sequence].percent>60:stop

Fig. 2.1.7  Excerpt of the dump of the condition array constructed in procedure loadmap (the final syntax of conditions has not yet been determined)
 
Paths and Path Conditions
 
The next mayor step will be to determine all possible paths and conditions leading up to a resource for access control.

readmap checks if the course has a start resource from its map_start entry in the resource properties (Step R2), and if does not, continue to store the two global binary data structures (Steps R5,R6)  in this special case, all resources which are part of any maps in the course are assumed to be accessible.

If the course has a start resource, readmap calls the procedure traceroute (Fig. 2.1.8A) with the following parameters (Step R4): The cumulative condition along this path or route so far is set to true (the map is accessible); the resource ID of the start resource of the course map; and an empty list for all resources processed so far along this route. It is again important to note that all variables except the global binary structures are local to traceroute, since traceroute will recursively call itself whenever there is a branching to follow all possible paths of the maps.

traceroute will establish a section within the resource properties hash that builds up all conditions leading up to a resource. Fig. 11B shows an excerpt of the final result. For example, resource 2.5, the introduction to part 1, can be reached under condition 8 (see Fig. 10), meaning, after solving the pretest problem.

traceroute first checks if the resource has already been processed on this route by its resource ID (Fig. 2.1.8A, Step T1)  this test avoids that traceroute runs into endless loops when the links on the map loop. Next, the resource ID is added to the list of processed resources on this route (Step T2).

The resource conditions are now ORd with the cumulative conditions on this route (Step T3)  the route represents another way of getting to the resource. A small routine with simplification rules for boolean expressions is called  to simplify the potentially very long expression.

In the next step, it is determined if the resource is itself a map (Step T4). If it is, the exit route conditions can differ from the entry route condition by all additional conditions along the paths in the embedded maps (for non-map resources, entry and exit route conditions are the same). If however the embedded map does not have a start resource (Step T5), that is not the case  again, the missing of entry point to an embedded link structure is interpreted as the resources being openly accessible.

If the embedded map does have a start resource, traceroute is called recursively with the current route conditions, the ID of the start resource of that map, and the list of already processed resource IDs (Step T6). Upon return, if the embedded map does not have a finish resource, the entry and exit conditions of this map are assumed to be the same (Step T7). If the map had a finish resource, the route condition so far is set to the resource condition of the finish resource of the embedded map (Step T8)  in order go on from here, the user would have had to reach the finish resource of the embedded map.

Now the route conditions are correctly set for exiting the resource and going on from here. traceroute now loops over all outgoing links of the resource (Step T9). If the link does have a link condition (Step T10), then for this path, the cumulative route condition so far AND the link condition (Step T11). If there is no link condition, then there is no change in route conditions (Step T12).

To further process the routes along this link, traceroute is called recursively with the resource ID of the destination resource of the link, the new route conditions, and the list of already processed resources (Step T13). traceroute returns after processing the last outgoing link of the resource it had been called for.

Fig. 11B shows part of the output of traceroute for the example Fig. 2.1.4.

&
Fig. 2.1.8A  Flow chart of procedure traceroute

conditions_1.1: 0
conditions_1.11:
(((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1))|((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1)|(8&7&2)|(8&7&3)|(8&7&4)|(8&7&1)))|((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1)|(8&7&2)|(8&7&3)|(8&7&4)|(8&7&1)|(8&6&2)|(8&6&3)|(8&6&4)|(8&6&1))
conditions_1.15:
((((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1))|((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1)|(8&7&2)|(8&7&3)|(8&7&4)|(8&7&1)))|((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1)|(8&7&2)|(8&7&3)|(8&7&4)|(8&7&1)|(8&6&2)|(8&6&3)|(8&6&4)|(8&6&1)))&9
conditions_1.2:
(((((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1))|((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1)|(8&7&2)|(8&7&3)|(8&7&4)|(8&7&1)))|((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1)|(8&7&2)|(8&7&3)|(8&7&4)|(8&7&1)|(8&6&2)|(8&6&3)|(8&6&4)|(8&6&1)))&9)&11
conditions_1.20: 0
conditions_1.29:
((((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1))|((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1)|(8&7&2)|(8&7&3)|(8&7&4)|(8&7&1)))|((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1)|(8&7&2)|(8&7&3)|(8&7&4)|(8&7&1)|(8&6&2)|(8&6&3)|(8&6&4)|(8&6&1)))&9
conditions_1.36:
((((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1))|((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1)|(8&7&2)|(8&7&3)|(8&7&4)|(8&7&1)))|((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1)|(8&7&2)|(8&7&3)|(8&7&4)|(8&7&1)|(8&6&2)|(8&6&3)|(8&6&4)|(8&6&1)))&10
conditions_1.5: 0
conditions_1.9: 8
conditions_2.1: 8
conditions_2.12: 8
conditions_2.13: 8
conditions_2.19: 8
conditions_2.2:
(((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1))|((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1)|(8&7&2)|(8&7&3)|(8&7&4)|(8&7&1)))|((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1)|(8&7&2)|(8&7&3)|(8&7&4)|(8&7&1)|(8&6&2)|(8&6&3)|(8&6&4)|(8&6&1))
conditions_2.24: ((8&5)|(8&7)|(8&6))
conditions_2.5: 8
conditions_2.6: 8
conditions_3.1: ((8&5)|(8&7)|(8&6))
conditions_3.15: ((8&5&4)|(8&7&4)|(8&6&4))
conditions_3.2: ((8&5&2)|(8&5&3)|(8&5&4)|(8&5&1)|(8&7&2)|(8&7&3)|(8&7&4)|(8&7&1)|(8&6&2)|(8&6&3)|(8&6&4)|(8&6&1))
conditions_3.5: ((8&5)|(8&7)|(8&6))
conditions_3.6: ((8&5&2)|(8&7&2)|(8&6&2))
conditions_3.8: ((8&5&3)|(8&7&3)|(8&6&3))

Fig. 11B  Dump of resource properties hash. Excerpt of cumulative link conditions to reach a certain resource.
Multivalued Boolean Evaluation of Link Priorities

When a user accessed a resource on a map and desires to access the next resource, the request is processed by a number of steps. From the data examplified in Fig. 2.1.6C, it is determined which outgoing links exist. From the data in Fig. 2.1.6D it is determined to which resources those links lead. For each of the resources, the expressions in Fig. 2.1.8A are evaluated as follows. Stored in the session environment is the evaluation of the table Fig. 10, where the boolean part is evaluated as 0 or 1. In addition, a multivalued boolean value is computed incorporating the condition priority. A false blocking condition is assigned the value zero, all other false conditions the value 1. A true forced condition is assigned the value 3, all other true conditions the value 2. 

In the expressions Fig. 2.1.8A an & (AND) is processed as the minimum (min) operation, a | (OR) is processed as the maximum (max) operation. The outcome 0 means blocked, the outcome 1 mean not recommended, the outcome 2 recommended, and the outcome 3 forced.
Session 2: SQL Metadata Database
Scott Harrison 

Last updated: 02/15/2001 

This section describes issues associated with LON-CAPA and a SQL database. 

The current database is implemented assuming a non-adjustable architecture involving these data fields (specific to each version of a resource). 

title 
author 
subject 
notes 
abstract 
mime 
language 
creationdate 
lastrevisiondate 
owner 
copyright 

Security occurs as a function of the user 'www', and the permissions on the files in the /usr/local/mysql directory. (These files and directories should be 700, 600, 500, 400, etc; not allow access to anyone but user 'www'.) 

These commands create the loncapameta database. 

mysql> CREATE DATABASE IF NOT EXISTS loncapa;
mysql> USE loncapa;
mysql> CREATE TABLE IF NOT EXISTS metadata (title TEXT, author TEXT, subject TEXT, url TEXT, keywords TEXT, version TEXT, notes TEXT, abstract TEXT, mime TEXT, language TEXT, creationdate DATETIME, lastrevisiondate DATETIME, owner TEXT, copyright TEXT, FULLTEXT idx_title (title), FULLTEXT idx_author (author), FULLTEXT idx_subject (subject), FULLTEXT idx_url (url), FULLTEXT idx_keywords (keywords), FULLTEXT idx_version (version), FULLTEXT idx_notes (notes), FULLTEXT idx_abstract (abstract), FULLTEXT idx_mime (mime), FULLTEXT idx_language (language), FULLTEXT idx_owner (owner), FULLTEXT idx_copyright (copyright)) TYPE=MYISAM;
mysql> INSERT INTO metadata VALUES ('The Structure of Scientific Revolutions','Thomas S. Kuhn','scientific philosophy','/res/msu/shh1/poobah2.html','aphorisms, theories, paradigm, revolution','current','still developing','This famous book stands out in contrast to the more rigid theories of Popper.','html','seniso','1999-03-03 12:34:56','1999-03-03 3:12:00','shh1@msu.edu','default');
mysql> SELECT * FROM metadata WHERE title REGEXP "1";

Q&A

Q: How big are data records in test database? A: on average, 1000 bytes each, medline records from PubMed. 
Q: How big is the biggest field? A: on average, 838 bytes each 
Q: How much time to insert 5284 medline records into database? A: 600 seconds 
Q: What about when using "speed-technique" on page 130? A: 689 seconds (weird, eh?) 
Q: What about REGEXP searching? A: about 1-2 seconds for small fields; 10 to 20 seconds for REGEXP search on "abstract" field 
Q: What about FULLTEXT indexing? A: about 6 seconds for abstract field. 

An important quote from the manual: 

In MySQL Version 3.23.23 or later, you can also create special FULLTEXT indexes. They are used for full-text search. Only the MyISAM table type supports FULLTEXT indexes. They can be created only from VARCHAR and TEXT columns. Indexing always happens over the entire column and partial indexing is not supported. See section 25.2 MySQL Full-text Search for details. 

I plan on using a MyISAM table type with 11 metadata fields of column type=TEXT. 

It might be worthwhile to look at /usr/local/mysql/manual.html. It is quite in depth. 

Current status of implementation

Need to 

       Installation: Fix binary file listings for user permissions and ownership. 
       Installation: Make sure sql server starts, and if database does not exist, then create. (/etc/rc.d). 
       Processes: Make sure loncron initiates lonsql on library machines. 
       Read in metadata from right place periodically. 
       Implement tested perl module handler. 

Right now, a lot of "feasibility" work has been done. Recipes for manual installation and configuration have been gathered. Network connectivity of lond->lonsql->lond->lonc type tests have been performed. A binary installation has been compiled in an RPM (LON-CAPA-mysql, with perl components a part of LON-CAPA-systemperl). The most lacking test in terms of feasibility has been looking at benchmarks to analyze the load at which the SQL database can efficiently allow many users to make simultaneous requests of the metadata database. 

Documentation has been pieced together over time. But, as mentioned in the previous section, it needs an overhaul. 

The binary installation has some quirks associated with it. Some of the user permissions are wrong, although this is benign. Also, other options of binary installation (such as using binary RPMs put together by others) were dismissed given the difficulty of getting differing combinations of these external RPMs to work together. 

Most configuration questions have been initially worked out to the point of getting this SQL software component working, however there may be more optimal approaches than currently exist. 

Purpose within LON-CAPA
LON-CAPA is meant to distribute A LOT of educational content to A LOT of people. It is ineffective to directly rely on contents within the ext2 filesystem to be speedily scanned for on-the-fly searches of content descriptions. (Simply put, it takes a cumbersome amount of time to open, read, analyze, and close thousands of files.) 

The solution is to hash-index various data fields that are descriptive of the educational resources on a LON-CAPA server machine. Descriptive data fields are referred to as "metadata". The question then arises as to how this metadata is handled in terms of the rest of the LON-CAPA network without burdening client and daemon processes. I now answer this question in the format of Problem and Solution below. 

PROBLEM SITUATION: If Server A wants data from Server B, Server A uses a lonc process to send a database command to a Server B lond process.

    lonc= loncapa client process    A-lonc= a lonc process on Server A
    lond= loncapa daemon process

                 database command
    A-lonc  --------TCP/IP----------------> B-lond

The problem emerges that A-lonc and B-lond are kept waiting for the MySQL server to "do its stuff", or in other words, perform the conceivably sophisticated, data-intensive, time-sucking database transaction.  By tying up a lonc and lond process, this significantly cripples the capabilities of LON-CAPA servers. 

While commercial databases have a variety of features that ATTEMPT to deal with this, freeware databases are still experimenting and exploring with different schemes with varying degrees of performance stability.

THE SOLUTION: A separate daemon process was created that B-lond works with to handle database requests.  This daemon process is called "lonsql".

  So,
                database command
  A-lonc  ---------TCP/IP-----------------> B-lond =====> B-lonsql
         <---------------------------------/                |
           "ok, I'll get back to you..."                    |
                                                            |
                                                            /
  A-lond  <-------------------------------  B-lonc   <======
           "Guess what? I have the result!"

  Of course, depending on success or failure, the messages may vary,
  but the principle remains the same where a separate pool of children
  processes (lonsql's) handle the MySQL database manipulations.

Dependencies
I believe (but am not 100% confident) that the following RPMs are necessary (in addition to the current ones in rpm_list.txt) to run MySQL. Basically I discovered these
dependencies while trying to do external RPM based installs. I assume, and sometimes found, that these dependencies apply to tarball-based distributions too. (So to play it
on the safe side, I am going to include these RPMs as part of the core, minimal RPM set.) 

       egcs-1.1.2-30 
       cpp-1.1.2-30 
       glibc-devel-2.1.3-15 
       zlib-devel-1.1.3-6 

Installation
Installation of the LON-CAPA SQL database normally occurs by default when using the LON-CAPA installation CD (see http://install.lon-capa.org). It is installed as the LON-CAPA-mysql RPM. This RPM encodes for the MySQL engine. Related perl interfaces (Perl::DBI, Perl::Msql-Mysql) are encoded in the LON-CAPA-systemperl RPM. 

The three components of a MySQL installation for the LON-CAPA system are further described immediately below. 

Perl::DBI module- the API "front-end"... database interface module for organizing generic database commands which are independent of specific database implementation (such as MySQL, mSQL, Postgres, etc). 
Perl::MySQL module- the API "mid-section"... the module to directly interface with the actual MySQL database engine
MySQL database engine- the "back-end"...  the binary installation (compiled either from source or pre-compiled file listings) which provides the actual MySQL functionality on the system

Configuration (automated)

Not yet developed. This will be part of an interface present on LON-CAPA systems that can be launched by entering the command /usr/sbin/loncapaconfig. 

Manual configuration

This is not complete. 

Starting the mysql daemon: Login on the Linux system as user 'www'. Enter the command /usr/local/bin/safe_mysqld & 

Set a password for 'root': /usr/local/bin/mysqladmin -u root password 'new-password' 

Adding a user: Start the mysql daemon. Login to the mysql system as root (mysql -u root -p mysql) and enter the right password (for instance 'newmysql'). Add the user www 

INSERT INTO user (Host, User, Password)
VALUES ('localhost','www',password('newmysql'));

Granting privileges to user 'www': 

GRANT ALL PRIVILEGES ON *.* TO www@localhost;
FLUSH PRIVILEGES;

Set the SQL server to start upon system startup: Copy support-files/mysql.server to the right place on the system (/etc/rc.d/...). 
The Perl API 
   $dbh = DBI->connect( "DBI:mysql:loncapa",
                        "www",
                        "SOMEPASSWORD",
                        { RaiseError =>0,PrintError=>0});

There is an obvious need to CONNECT to the database, and in order to do
this, there must be:
  a RUNNING mysql daemon;
  a DATABASE named "loncapa";
  a USER named "www";
  and an ABILITY for LON-CAPA on one machine to access
       SQL database on another machine;
  
So, here are some notes on implementing these configurations.

** RUNNING mysql daemon (safe_mysqld method)

The recommended way to run the MySQL daemon is as a non-root user
(probably www)...

so, 1) login as user www on the linux machine
    2) start the mysql daemon as /usr/local/bin/safe_mysqld &

safe_mysqld only works if the local installation of MySQL is set to the
right directory permissions which I found to be:
chown www:users /usr/local/var/mysql
chown www:users /usr/local/lib/mysql
chown -R www:users /usr/local/mysql
chown www:users /usr/local/include/mysql
chown www:users /usr/local/var

** DATABASE named "loncapa"

As user www, run this command
    mysql -u root -p mysql
enter the password as SOMEPASSWORD

This allows you to manually enter MySQL commands.
The MySQL command to generate the loncapa DATABASE is:

CREATE DATABASE 'loncapa';

** USER named "www"

As user www, run this command
    mysql -u root -p mysql
enter the password as SOMEPASSWORD

To add the user www to the MySQL server, and grant all
privileges on *.* to www@localhost identified by 'SOMEPASSWORD'
with grant option;

INSERT INTO user (Host, User, Password)
VALUES ('localhost','www',password('SOMEPASSWORD'));

GRANT ALL PRIVILEGES ON *.* TO www@localhost;

FLUSH PRIVILEGES;

** ABILITY for LON-CAPA machines to communicate with SQL databases on
   other LON-CAPA machines

An up-to-date lond and lonsql.

Testing

To test the backend MySQL database, a number of commands should be run after installation. 

       cd /usr/local/mysql/sql-bench; ./run-all-tests --small-test 
       without the --small-test flag, this test can take more than 10 hours! 
       cd /usr/local/mysql; bin/mysqladmin version 
       cd /usr/local/mysql; bin/mysqladmin variables 
       cd /usr/local/mysql; bin/mysqlshow 
       cd /usr/local/mysql; bin/mysqlshow mysql 
       cd /usr/local/mysql; bin/mysql -e "select host,db,user from db" mysql 
       cd /usr/local/mysql/mysql-test; ./test-run-all 

These are sections of perl code which helps test the LON-CAPA network. 

** TEST the database connection with my current tester.pl code
which mimics what command will eventually be sent through lonc.

$reply=reply(
    "querysend:SELECT * FROM general_information WHERE Id='AAAAA'",$lonID);

Example sections of code relevant to LON-CAPA

Here are excerpts of code which implement the above handling: 

LONSQL

A subroutine from "lonsql" which establishes a child process for handling
database interactions.

sub make_new_child {
    my $pid;
    my $sigset;
    
    # block signal for fork
    $sigset = POSIX::SigSet->new(SIGINT);
    sigprocmask(SIG_BLOCK, $sigset)
        or die "Can't block SIGINT for fork: $!\n";
    
    die "fork: $!" unless defined ($pid = fork);
    
    if ($pid) {
        # Parent records the child's birth and returns.
        sigprocmask(SIG_UNBLOCK, $sigset)
            or die "Can't unblock SIGINT for fork: $!\n";
        $children{$pid} = 1;
        $children++;
        return;
    } else {
        # Child can *not* return from this subroutine.
        $SIG{INT} = 'DEFAULT';      # make SIGINT kill us as it did before
    
        # unblock signals
        sigprocmask(SIG_UNBLOCK, $sigset)
            or die "Can't unblock SIGINT for fork: $!\n";
        
        
        #open database handle
        # making dbh global to avoid garbage collector
        unless (
                $dbh = DBI->connect("DBI:mysql:loncapa","www","SOMEPASSWORD",{ RaiseError =>0,PrintError=>0})
                ) { 
                    my $st=120+int(rand(240));
                    &logthis("WARNING: Couldn't connect to database  ($st secs): $@");
                    print "database handle error\n";
                    sleep($st);
                    exit;

          };
        # make sure that a database disconnection occurs with ending kill signals
        $SIG{TERM}=$SIG{INT}=$SIG{QUIT}=$SIG{__DIE__}=\&DISCONNECT;

        # handle connections until we've reached $MAX_CLIENTS_PER_CHILD
        for ($i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {
            $client = $server->accept()     or last;
            
            # do something with the connection
            $run = $run+1;
            my $userinput = <$client>;
            chomp($userinput);
                    
            my ($conserver,$querytmp)=split(/&/,$userinput);
            my $query=unescape($querytmp);

            #send query id which is pid_unixdatetime_runningcounter
            $queryid = $thisserver;
            $queryid .="_".($$)."_";
            $queryid .= time."_";
            $queryid .= $run;
            print $client "$queryid\n";
            
            #prepare and execute the query
            my $sth = $dbh->prepare($query);
            my $result;
            unless ($sth->execute())
            {
                &logthis("WARNING: Could not retrieve from database: $@");
                $result="";
            }
            else {
                my $r1=$sth->fetchall_arrayref;
                my @r2; map {my $a=$_; my @b=map {escape($_)} @$a; push @r2,join(",", @b)} (@$r1);
                $result=join("&",@r2) . "\n";
            }
            &reply("queryreply:$queryid:$result",$conserver);

        }
    
        # tidy up gracefully and finish
        
        #close the database handle
        $dbh->disconnect
           or &logthis("WARNING: Couldn't disconnect from database  $DBI::errstr ($st secs): $@");
    
        # this exit is VERY important, otherwise the child will become
        # a producer of more and more children, forking yourself into
        # process death.
        exit;
    }
}


LOND enabling of MySQL requests

This code is part of every lond child process in the way that it parses command request syntax sent to it from lonc processes.  Based on the diagram above, querysend corresponds to B-lonc sending the result of the query. queryreply corresponds to B-lond indicating that it has received the request and will start the database transaction (it returns "ok" to A-lonc ($client)).

# ------------------------------------------------------------------- querysend
                   } elsif ($userinput =~ /^querysend/) {
                       my ($cmd,$query)=split(/:/,$userinput);
                       $query=~s/\n*$//g;
                     print $client sqlreply("$hostid{$clientip}\&$query")."\n";
# ------------------------------------------------------------------ queryreply
                   } elsif ($userinput =~ /^queryreply/) {
                       my ($cmd,$id,$reply)=split(/:/,$userinput); 
                       my $store;
                       my $execdir=$perlvar{'lonDaemons'};
                       if ($store=IO::File->new(">$execdir/tmp/$id")) {
                           print $store $reply;
                           close $store;
                           print $client "ok\n";
                       }
                       else {
                           print $client "error:$!\n";
                       }


Session 3: XML Files/Style Files
XML Files

All HTML / XML files are run through the lonxml handler before being served to a user. This allows us to rewrite many portion of a document and to support serverside tags. There are 2 ways to add new tags to the xml parsing engine, either through LON-CAPA style files or by writing Perl tag handlers for the desired tags. 

Global Variables

*	$Apache::lonxml::debug - debugging control 
*	@Apache::lonxml::pwd - path to the directory containing the file currently being processed 
*	@Apache::lonxml::outputstack 
$Apache::lonxml::redirection - these two are used for capturing a subset of the output for later processing, don't touch them directly use &startredirection and &endredirection 
*	$Apache::lonxml::import - controls whether the <import> tag actually does anything 
*	@Apache::lonxml::extlinks - 
*	#Apache::lonxml::metamode - some output is turned off, the meta target wants a specific subset, use <output> to guarentee that the catianed data will be in the parsing output 
*	#Apache::lonxml::evaluate - controls whether run::evaluate actually derefences variable references 
*	%Apache::lonxml::insertlist - data structure for edit mode, determines what tags can go into what other tags 
*	@Apache::lonxml::namespace - stores the list of tag namespaces used in the insertlist.tab file that are currently active, used only in edit mode. 


Notable Perl subroutines

If not specified these functions are in Apache::lonxml 

*	xmlparse - see the XMLPARSE figure 
*	recurse - acts just like xmlparse, except it doesn't do the style definition check it always calls callsub 
*	callsub - callsub looks if a perl subroutine is defined for the current tag and calls. Otherwise it just returns the tag as it was read in. It also will throw on a default editing interface unless the tag has a defined subroutine that either returns something or requests that call sub not add the editing interface. 
*	afterburn - called on the output of xmlparse, it can add highlights, anchors, and links to regular expersion matches to the output. 
*	register_insert - builds the %Apache::lonxml::insertlist structure of what tags can have what other tags inside. 


Functions Tag Handlers can use

If not specified these functions are in Apache::lonxml 

*	debug - a function to call to printout debugging messages. Will only print when Apache::lonxml::debug is set to 1 
*	warning - a function to use for warning messages. The message will appear at the top of a resource when it is viewed in construction space only. 
*	error - a function to use for error messages. The message will appear at the top of a resource when it is viewed in construction space, and will message the resource author and course instructor, while informing the student that an error has occured otherwise. 
*	get_all_text - 2 args, tag to look for (need to use /tag to look for an end tag) and a HTML::TokeParser reference, it will repedelyt get text from the TokeParser until the requested tag is found. It will return all of the document it pulled form the TokeParser. (See Apache::scripttag::start_script for an example of usage.) 
*	get_param - 4 arguments, firsth is a scaler sting of the argument needed, second is a reference to the parser arguments stack, third is a reference to the Safe space, and fourth is an optional "context" value. This subroutine allows a tag to get a tag argument, after being interpolated inside the Safe space. This should be used if the tag might use a safe space variable reference for the tag argument. (See Apaceh::scripttag::start_script for an example.) 
*	newparser - 3 args, first is a reference to the parser stack, second should be a reference to a string scaler containg the text the newparser should run over, third should be a scaler of the directory path the file the parser is parsing was in. (See Apache::scripttag::start_import for an example.) 
*	register - should be called in a file's BEGIN block. 2 arguments, a scaler string, and a list of strings. This allows a file to register what tags it handles, and what the namespace of those tags are. Example: 


sub BEGIN {
  &Apache::lonxml::register('Apache::scripttag',('script','display'));
}

Would tell xmlparse that in Apache::scripttag it can find handlers for <script> and <display> 
*	startredirection - used when a tag wants to save a portion of the document for its end tag to use, but wants the intervening document to be normally processed. (See Apache::scripttag::start_window for an example.) 
*	endredirection - used to stop preventing xmlparse from hiding output. The return value is everthing that xmlparse has processed since the corresponding startredirection. (See Apache::scripttag::end_window for an example.) 
*	Apache::run::evaluate - 3 args, first a string, second a reference to the Safe space, 3 a string to be evaluated before the first arg. This subroutine will do variable interpolation and simple function interpolations on the first argument. (See Apache::lonxml::xmlparse for an example.) 
*	Apache::run::run - 2 args, first a string, second a reference to the Safe space. This handles passing the passed string into the Safe space for evaluation and then returns the result. (See Apache::scripttag::start_script for an example.) 


Style Files
&
Style File specific tags

*	<definetag> - 2 arguments, name name of new tag being defined, if proceeded with a / defining an end tag, required; parms parameters of the new tag, the value of these parameters can be accesed by $parametername. 
*	<render> - define what the new tag does for a non meta target 
*	<meta> - define what the new tag does for a meta target 
*	<tex> / <web> / <latexsource> - define what a new tag does for a specific no meta target, all data inside a <render> is render to all targets except when surrounded by a specific target tags. 


&
Session 4: What a Problem looks like/What a Problem does
Tags
Response tags 
Arguments for all response tags 
ID, if this isn't set it will be set during the publication step. It is used to assign parameters names in a way that can be tracked if an instructor modifies things by hand. 
name optional, if set, it will be used by the resource assembly tool when one is modifying parameters. 
Implemented response tags 
<responseparam> if it appears it should be inside of a <*response> tag, defines an externally adjustable parameter for this question. Arguments: 
default required, specifies a default value for the parameter 
name required, specifies an internal name for the parameter 
type required specifies the type of parameter, one of "tolerance", "int", "float", "string", "date" (configuration of paramters is handled by lonparmset.pm and parameter.html) 
description a string describing the parameter, this is what is used to talk about a parameter outside of a problem 
<numericalresponse> implements a numerical answer, it needs an internal <textline> for the response to go in. It checks all styles of numerical supported in CAPA. Possible args are: 
answer required, specifies the correct answer, must be a perl list 
type optional, CAPA style str args, cs/ci/mc 
units optional, specifies unit of correct answer, CAPA style 
<essayresponse> implements a ungraded large text response, it need an internal <textarea> for the response to go in. 
<imageresponse> implements a image click style image submission, uses the foil structure tags below. Additional tags that should appear in a <foil> are: 
<image> required, the contained text specifies a published graphical resource that is the image used, should only appear once per foil 
<rectangle> required, the contained text specifies a rectangular area that is correct, should look like (1,2)-(3,4), at least 1 required 
<text> required, the contained text is printed on top of the image. 
<optionresponse> implements a "select from these choices" style question, the choices are specified by the instructor, it uses the foil structure tags below with this additional args: 
<foilgroup> is required to have options which should be a perl list of possible options for the student. 
<radiobuttonresponse> implements a true / false style question with 1 correct answer.it uses the foil structure tags below but the value of a <foil>can only be "true" or "false" or "unused" 
Foil Structure Tags 
All tags that implement a foil structure have an optional arg of max that controls the maximum number of total foils to show. 
<foilgroup> required, must be the tag that surrounds all foil definitions 
<foil> required, all data inside is a possible foil 
<conceptgroup> optional, surrounds a collection of <foil>, when a problem is displayed only one of the contained <foil>is selected for display. It receives one required argument concept. 
Hint structure 
All of these tags must appear inside a <*response> tag. 
<hintgroup> Tag that surrounds all of a hint. 
<hintpart> required, Tag to implement conditional hints. It has a required argument on. When a <*hint> tag named the same as the value the on attribute evaluates to be correct the <hintpart> will show. If no other <hintpart> are to show then all hintparts with a on of "default" will show 
<numericalhint> has all the arguments that <numericalresponse>, does and the required attribute name which should be set to the value of which <hintpart> will be shown. 
Input Tags 
This group of tags implement a mechanism for getting data for students, they will usually be used by a <*response>. 
<textarea> creates a Large text input box, If data appears between the start and end tags, the data will appear i the textarea if the student has not yet made a submission. Additionally it takes two arguments rows and cols which control the height and width of the area respectively. It defaults to 10 and 80. 
<textline> creates a single line of input element, it accepts 1 argument size which controls the width on the textline, it defaults to 20. 
Output Tags 
This group of tags generate useful pieces of output. 
<displayduedate> this will insert the current duedate if one is set into the document. It is generated to be inside a table of 1x1 elements 
<displaytitle> this will insert the title of the problem from the metadata of the problem 
<window> the text in between is put in a popup javascript window 
Scripting 
These tags allow the document to behave programmatically 
<display> the intervening perl script is evaluated in the safe space and the return value of the script replaces the entire tag 
<import> causes the parse to read in the file named in the body of the tag and parse it as if the entire text of the file had existed at location of the tag 
<parserlib> the enclosed filename contains definitions for new tags 
<script> if the argument type is set to "loncapa/perl" the enclosed data is a perl script which is evaluated inside the perl Safe space. The return value of the script is ignored. 
<scriptlib> the enclosed filename contains perl code to run in the safe space 
<block> has a required argument condition that is evaluated, it the condition is true everything inside the tag is evaluated, if it is false everything inside the block tag is skipped 
<notsolved> everything inside the tag is skipped if the problem is "solved" 
<postanswerdate> everything inside the tag is skipped if the problem is before the answer date 
<preduedate> everything inside the tag is skipped if the problem is after the due date 
<randomlist> the enclosed tags are parsed in a stable random order 
<solved> everything inside the tag is skipped if the problem is "not solved" 
<while> implements a while loop, required argument condition is a perl scriptlet that when evaluated results in a true or false value, on true the entirety of the text between the whiles is parsed. The condition is tested again, etc. If false it goes to the next node in the parse. 
Structure Tags 
These tags give the problem a structure and take care of the recording of data and giving the student messages. 
<problem> must be the first tag in the file, this tag sets up the header of the webpage and generates the submit buttons, it also handles due dates properly 
<part> must be below <problem> if it is going to be used. It does many of the same tasks as <problem> but allows multiple separate problems to exist in a single file. 
<startouttext><endouttext> these tags are somewhat special, they must have no internal text and occur in pairs. Their use is to mark up the problem so the web editor knows what sections should be edited in a plain text block on the web. 
<script> Functions
A list of functions that have been written that are available in the Safe space scripting environment inside a problem. The eventual goal is to provide all of the functions available in CAPA 
random 
tan 
atan 
acos 
asin 
log10 
pow 
ceil 
floor 
format 
map 
choose 
caparesponse_check 
caparesponse_check_list 
<script> Variables
$external::target - set to the current target the xml parser is parsing for 
$external::part - set to the id of the current problem <part>; zero if there are now <part> 
$external::gradestatus - set to the value of the current resource.partid.solved value 
$external::datestatus - set to the current status of the clock either CLOSED, CAN_ANSWER, CANNOT_ANSWER, or SHOW_ANSWER 
$external::randomseed - set to the number that was used to seed the random number generator 
$pi - set to PI 
Symbs

To identify a specific instance of a resource, LON-CAPA uses symbols or symbs. These identifiers are built from the URL of the map, the resource number of the resource in the map, and the URL of the resource itself. The latter is somewhat redundant, but might help if maps change.

An example is

 msu/korte/parts/part1.sequence___19___msu/korte/tests/part12.problem

The respective map entry is

 <resource id="19" src="/res/msu/korte/tests/part12.problem"     
  title="Problem 2">
 </resource>

Symbs are used by the random number generator, as well as to store and restore data specific to a certain instance of for example a problem.
Store / Restore
2 important functions in lonnet.pm are &Apache::lonnet::cstore() and &Apache::lonnet:restore() (and &Apache::lonnet::store(), which is is the non-critical message twin of cstore). These functions are for handlers to store a perl hash to a users permanent data space in an easy manner, and to retrieve it again on another call. It is expected that a handler would use this once at the beginning to retrieve data, and then again once at the end to send only the new data back. 

The data is stored in the users data directory on the users homeserver under the ID of the course.

The hash that is returned by restore will have all of the previous value for all of the elements of the hash. 

Example: 

#creating a hash
my %hash;
$hash{'foo'}='bar';
#storing it
&Apache::lonnet::cstore(\%hash);
#changing a value 
$hash{'foo'}='notbar';
#adding a new value
$hash{'bar'}='foo';
&Apache::lonnet::cstore(\%hash);
#retrieving the hash
my %history=&Apache::lonnet::restore();
#print the hash
foreach my $key (sort(keys(%history))) {
    print("\%history{$key} = $history{$key}");
}
    
Will print out: 


%history{1:foo} = bar
%history{1:keys} = foo:timestamp
%history{1:timestamp} = 990455579
%history{2:bar} = foo
%history{2:foo} = notbar
%history{2:keys} = foo:bar:timestamp
%history{2:timestamp} = 990455580
%history{bar} = foo
%history{foo} = notbar
%history{timestamp} = 990455580
%history{version} = 2
    

Note that the special hash entries keys, version and timestamp were added to the hash. version will be equal to the total number of versions of the data that have been stored. The timestamp attribute will be the UNIX time the hash was stored. keys is available in every historical section to list which keys were added or changed at a specific historical revision of a hash. 

Warning do not store the hash that restore returns directly. This will cause a mess since it will restore the historical keys as if the were new keys. I.E. 1:foo will become 1:1:foo etc. 

Calling convention: 


  my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$uname,$home);
  &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$uname,$home);
    

Arguments (only %newrecord is required the rest are somewhat optional, read the details): 

$symb - a string containing the internal name of the specific instance of a resource. Usually this value can be gotten from &Apache::lonnet::symbread($filename). If the argument is blank, it will attempt to use symbread() for it. If the result is ambiguous store/restore will fail. 
$courseid - the internal name for a course, usually found in $ENV{'request.course.id'} which is what will be looked at if no value is passed to the functions. 
$domain - the domain that the user belongs to, usually found in $ENV{'user.domain'} which is what will be looked at if no value is passed to the functions. 
$uname - the login name for the user, usually found in $ENV{'user.name'} which is what will be looked at if no value is passed to the functions. 
$home - the homeserver for the user, usually found in $ENV{'user.home'} but can be easily gotten from a domain and name through &Apache::lonnet::homeserver($uname,$domain). If no value is passed to store/restore the value in %ENV will be used. 
%newrecord - the hash to store being passed by reference 


Return values: 

an empty string - the function was unable to determine exactly where to store or restore from. At least one of the "optional" arguments was unable to be determined. 
a hash - restore successfully read a old hash for this specific user / resource instance. 
no_such_host - the $home specfied desn't exist in the network. 
con_delayed - the $home was uncontactable at this time. The store will be delayed until it is again available. 
con_failed - the $home was uncontactable at this time and store was unable to delay the store until a later time. The store failed. 
ok - the store completed succesfully 
error: - remote server failied to store or restore the reason follows the : 

Mandatory Homework Data

resource.partid.opendate 	#unix time of when the local machine should let the
                    	#student in

resource.partid.duedate  	#unix time of when the local machine should stop
                    	#accepting answers

resource.partid.answerdate 	#unix time of when the local machine should
                    		#provide the correct answer to the student

resource.partid.weight     # points the problem is worth

resource.partid.maxtries   # maximum number of attempts the student can have





resource.partid.tol # lots of possibilities here
                    # percentage, range (inclusive and exclusive),
		   # variable name, etc
                    # 3%
                    # 0.5
                    # .05+
                    # 3%+
                    # 0.5+,.005

resource.partid.sig  # one or two comma sepearted integers, specifying the
                     # number of significatn figures a student must use

resource.partid.feedback # at least a single bit (yes/no) may go with a
                         # bitmask in the future, controls whether or not
                         # a problem should say "correct" or not


resource.partid.solved # if not set, problem yet to be viewed
                # incorrect_attempted == incorrect and attempted
                # correct_by_student == correct by student work
                # correct_by_override == correct, instructor override
                # incorrect_by_override == incorrect, instructor override
                # excused == excused, problem no longer counts for student
                # '' (empty) == not attempted
                # ungraded_attempted == an ungraded answer has been
                                          sumbitted and stored
resource.partid.tries  # positive integer of number of unsuccessful attempts
                # made, malformed answers don't count if feedback is
                # on

resource.partid.awarded 	# float between 0 and 1, percentage of
                 	# resource.weight that the stundent earned.

resource.partid.responseid.submissons
                    	# the student submitted string for the part.response

resource.partid.responseid.awarddetail
                     # list of all of the results of grading the submissions
                     # in detailed form of the specific failure
		    # Possible values:
                     # EXACT_ANS, APPROX_ANS : student is correct
                     # NO_RESPONSE : student submitted no response
                     # MISSING_ANSWER : student submitted some but not
                     #                   all parts of a response
                     # WANTED_NUMERIC : expected a numeric answer and
                     #                   didn't get one
		    # SIG_FAIL : incorrect number of Significant Figures
                     # UNIT_FAIL : incorrect unit
                     # UNIT_NOTNEEDED : Submitted a unit when one shouldn't
                     # NO_UNIT : needed a unit but none was submitted
		    # BAD_FORMULA : syntax error in submitted formula
                     # INCORRECT : answer was wrong
                     # SUBMITTED : submission wasn't graded

Sample Problems
A Simple Problem
<problem>
        <script type="loncapa/perl">
$length=&random(10,99,.1);
$width=&random(1,10,.01);
@area=($length*($width*10));
        </script>

What is the area of a box $length mm in length and 
&format($width,"2E") cm in width.

        <numericalresponse id="11" answer="@area" units="mm^2">
                <textline></textline>
                <responseparam name="tol" type="tolerance" default="5%"></responseparam>
        </numericalresponse>

</problem>
A More Complex Problem

<problem>

<displayduedate />
<p><displaytitle /></p>
<script type="loncapa/perl">
$vF="<b> F<sub>1</sub> </b>";
$vF1="<b> F<sub>1</sub> </b>";
$vF2="<b> F<sub>2</sub> </b>";

$mF="|<b>F</b>|";
$F1mag="|<b>F<sub>1</sub></b>|";
$F2mag="|<b>F<sub>2</sub></b>|";
$trq1mag="|<b> <font face=symbol>t</font><sub>1</sub></b>|";
$trq2mag="|<b> <font face=symbol>t</font><sub>2</sub></b>|";
$Q1="Q<sub>1</sub>";
$Q2="Q<sub>2</sub>";
$tau="<font face=symbol>t</font>";
$tau1="<font face=symbol><b>t</b></font><sub>1</sub>";
   $val=&random(1,4,1);
   $tp=&choose($val,"her","her","his","his");
   $sd=&choose($val,"daughter","niece","nephew","son");

</script>
<startouttext />
$trq1mag and $trq2mag are the magnitudes of the torques produced repectively by 
forces $vF1 and $vF2 with respect the pivot P. The magnitudes of $vF1 is 
$F1mag and that of $vF2 is $F2mag. $Q1 and $Q2 are the locations 
on a rigid body where $vF1 and $vF2 act.  

<endouttext />
<optionresponse max="600">
        <foilgroup options="('Correct','Incorrect','Can not tell')">
                <conceptgroup concept="Effect of the moment-arm on the torque">
                        <foil name="1a" value="Incorrect">
                          For $F1mag larger than $F2mag , $trq1mag is larger than $trq2mag
                        </foil>
                        <foil name="1b" value="Incorrect">
                          For $F1mag smaller than $F2mag , $trq1mag is smaller than $trq2mag
                        </foil>
                        <foil name="1c" value="Correct">
                          For $F1mag larger than $F2mag , $trq1mag can be less  than $trq2mag
                        </foil>
                        <foil name="1d" value="Correct">
                          For $F1mag smaller than $F2mag , $trq1mag can be larger  than $trq2mag
                        </foil>
                </conceptgroup> 
                <conceptgroup concept="For a given pivot, relation of force vector to torque.">
                        <foil name="2a" value="Correct">
                  The moment-arm of $vF is the shortest distance from P to the line along $vF .
                        </foil>
                        <foil name="2b" value="Incorrect">
                          The moment-arm of $vF is the shortest distance from P to $vF vector.
                        </foil>
                        <foil name="2c" value="Correct">
                          The moment-arm of $vF is not the distance from P to Q<sub>1</sub>.
                        </foil>
                        <foil name="2d" value="Incorrect">
                          The moment-arm of $vF is the distance from P to Q<sub>1</sub>.
                        </foil> 
                </conceptgroup>
                <conceptgroup concept="Torque is force x moment-arm.">
                        <foil name="3a" value="Correct">
                          $trq1mag equals to the product of the moment-arm and $F1mag .
                      </foil>
                        <foil name="3b" value="Incorrect">
                        $trq1mag equals to $F1mag times the distance from Q<sub>1</sub> to P.
                        </foil>
                        <foil name="3c" value="Correct">
                          $trq1mag is not equal to the product of $F1mag and the distance from Q<sub>1</sub> to P.
                        </foil>
                        <foil name="3d" value="Incorrect">
                        $trq1mag is not equal to the product of the moment-arm and $F1mag .
                        </foil>
                </conceptgroup>
                <conceptgroup concept="Pivot point is required to calculate torque">
                        <foil name="4a" value="Correct">
                         $tau1 vector depends on the location of P.
                        </foil>
                        <foil name="4b" value="Incorrect">
                         $tau1 vector does not depend on the location of P.
                        </foil>
                        <foil name="4c" value="Correct">
                         $tau1 vector has no meaning unless a pivot is selected.
                        </foil>
                        <foil name="4d" value="Incorrect">
                         $tau1 vector can be determined without selecting P. 
                        </foil>
                </conceptgroup> 
                <conceptgroup concept="torque from 2 forces acting along same line">
                        <foil name="5a" value="Correct">
                          Two equal forces, acting on a body along the same line but at different positions, produce equal torques with respect to a given pivot."
                        </foil>
                        <foil name="5b" value="Incorrect">
                          Two equal forces, along the same line, produce equal torques with respect to a given pivot only if they act at the same point on a body."
                        </foil>
                        <foil name="5c" value="Incorrect">
                          Two equal forces acting on a body along the same line but at different positions, produce equal torques for only one pivot."
                        </foil>
                </conceptgroup>
        
                <foil name="6" value="unused">
                        This foil will never display since it is unused.
                </foil>
        </foilgroup>
        <notsolved>
                <hintgroup>
Think the definition of the torque. The force and the moment-arm respect to the pivot.  
                </hintgroup>
        </notsolved>
</optionresponse>
</problem>

Internal Structure Homework Handler
&

Session 5: Spreadsheet/Messaging

Spreadsheets

Spreadsheets are handled by lonspreadsheet.pm, and are completely web-based. They exist on the level of a whole course, a student, and individual assessments.
&
Fig. 2.4.1  Example Spreadsheet on Assessment Level

Fig. 2.4.1 shows an example of a spreadsheet on the individual assessment level. The data in column A is imported from what the problem stored. Fields in this column can be addressed either by An (for example A5) or by the symbolic name given up front.

Row 0, columns A through Z, are exported into the next level up, the student spreadsheet. 

The spreadsheet in Fig. 2.4.1 was calculated from the data in Fig. 2.4.2. This is the default spreadsheet on the assessment level. Course coordinators can construct their own spreadsheets, which are stored with the course and then used instead of the default one.


[www@zaphod www]$ cat /home/httpd/html/res/adm/includes/default.assesscalc
<field col=A row=0>[stores_0_solved]</field>
<field col=B row=0>'Tries:'</field>
<field col=C row=0>[stores_0_tries]</field>
<field col=D row=0>'Timestamp:'</field>
<field col=E row=0>[timestamp]</field>
<field col=F row=0>'Duedate:'</field>
<field col=G row=0>[parameter_0_duedate]</field>
<field col=W row=0>'Available Points:'</field>
<field col=X row=0>[parameter_0_weight]</field>
<field col=Y row=0>'Awarded Points:'</field>
<field col=Z row=0>[parameter_0_weight]*[stores_0_awarded]</field>

Fig 2.4.2  Default Spreadsheet on Assessment Level


Fig 2.4.3 shows the next level up spreadsheet with the exported data from this sheet.

&

Fig 2.4.3  Default Spreadsheet on Student Level

&

Fig 2.4.4  Default Spreadsheet on Course Level

Within the fields, any non-I/O non-system Perl code can be used, which is internally evaluated within a safe space. Field names and Column-Row combinations can be used as variables. The wildcard * is defined, which means all rows or all columns, respectively. In addition, within the top-most row acts as a template, where the entries are applied to all empty cells in the respective column  here the wildcard # will be replaced by the respective row number (for example, b# is b6 in row 6).
Fig. 2.4.5 shows how ranges are can be defined for functions.

*  all rows, all columns
B*  all rows in column B
*5  all columns in row 5
C5..F25  all cells in the rectangle between C5 and F25

Fig 2.4.5  Available Functions in Spreadsheet

Fig 2.4.6 list the functions which are defined for the spreadsheet.

&NUM(range)  number of non-empty cells in range
&BIN(low, high, range)  number of non-empty cells in range with values between low and high
&SUM(range)  sum of the non-empty cells in range
&MEAN(range)  mean value of non-empty cells in range
&STDDEV(range)  standard deviation of non-empty cells in range
&PROD(range)  product of non-empty cells in range
&MAX(range)  maximum value of non-empty cell in range
&MIN(range)  minimum value of non-empty cells in range
&SUMMAX(n ,range)  sum of the maximum n non-empty cells in range
&SUMMIN(n, range)  sum of the minimum n non-empty cells in range
&EXT(expression)  access to EXT function in lonnet

Fig 2.4.6  Available Functions in Spreadsheet

Fig 2.4.7 shows a course-customized student-level spreadsheet with many of these functions, templates and wildcards in action. In the dialog window, &SUM(d*) is entered as the expression for cell H0, which will add up all cells in column d. The template row is used to define expressions for columns a, b, c, and d, where for b and d both the # wildcard and access to the EXT function is used in order to multiply the respective X and Z cells in each row with 1 or 0 depending on whether the value in G (the duedate) is smaller or larger than the system time (? is the standard Perl choice operator).

&
Fig 2.4.7  Customized Spreadsheet on Student Level
A course with 200 students and 200 homework problems creates about 400,000 separate spreadsheets. A challenge is appropriate caching to make calculation practical while at the same time appropriately de-validating stale sheets as data changes.

On the long run, appropriate import and export functions to standard client-based spreadsheet applications need to be created (csv files).

Messaging

lonmsg.pm has several functions to send and receive internal messages.

author_res_msg  send message to resource author
user_crit_msg  send a critical message to a user. A critical message will require acknowledgment by the recipient and the sender will be notified 
user_crit_received  routine to trigger acknowledgment
user_normal_msg  send a message to a user
statuschange  change the status of a message (read, replied, forwarded, etc)

The handler of lonmsg.pm  also displays messages, has routines to reply, etc.

lonfeedback.pm allows it to send feedback to a resource. It includes a screenshot of the current resource, as well as previous attempts if the resource was a homework.

loncommunicate.pm will be the access handler to email sending, as well as the planned chatrooms, etc.

&
Fig 2.4.8  Example of a Feedback
Day 3
Session 1: Installation/CVS/Review Mechanism
Understanding the Files
Scott Harrison, last updated 05/19/2001 
Source repository summary
Within our source repository, there are 420 files, which are mapped into 39 different system directories. 
The "one file" information strategy
We manage all the installation file details of LON-CAPA within one file. This file keeps track of the associated file ownerships and permissions as well as directory ownerships and permissions. We also allow for different sets of file/directory ownerships and permissions to be applied (a development set, and a run-time "secure" set). 
This "one file" also encodes the invocation of "build" commands whenever compiled binaries need to be regenerated due to changing source code. 
Categorizing the files
To most efficiently manage details associated with groups of files, we categorize them as shown in the table below. 
TypePermissionsDevelopment Permissionssymbolic linkroot:rootroot:rootinterface file0444 root:root0644 www:userssetuid script6755 root:root6755 root:rootsystem file0644 root:root0644 root:rootscript0700 www:users0500 www:usersconf0644 root:root0644 root:rootroot script0700 root:root0700 root:roothandler0444 root:root0600 www:usersstatic conf0444 root:root0444 root:rootgraphic file0444 root:root0400 www:usersSpecial treatment of the "conf" category
During both installation and upgrades, our procedures safeguard the contents of your machine's configuration. During a CVS upgrade, when you type: "make install", NONE of your "conf" files are overwritten. These include: 
"/etc/httpd/conf/access.conf" 
"/etc/smb.conf" 
"/home/httpd/lonTabs/hosts.tab" 
"/home/httpd/lonTabs/spare.tab" 
"/etc/krb.conf" 
"/etc/ntp.conf" 
The command "make configinstall" will correctly upgrade these files and intelligently conserve configuration information present within them. 
The entire file space
A standard LON-CAPA development system has a total of 47464 files belonging to a total of 416 different software packages. 
409 of these packages come from ftp.redhat.com. The other 7 of these packages represent "custom-built subsystems" needed to implement LON-CAPA on a machine. 
LON-CAPA-setup-3.1-1Used only during a fresh installation, this RPM overwrites the /etc/passwd, /etc/group, /etc/hosts.deny, /etc/pam.d/login, and /etc/pam.d/passwd files of the standard RedHat setup-*.rpm. This RPM is installed automatically by the LON-CAPA installation CD. (You should never install this manually since you will lose ability to log into your computer). This RPM also sets up a /home/www directory during the installation.LON-CAPA-base-3.1-1This RPM can be built from CVS by the RPM target in CVS:loncom/build/Makefile. This RPM handles the installation of all 420 CVS source files. We recommend that you do NOT upgrade this RPM on a running LON-CAPA system since you may lose your machine's configuration. All "conf" files are saved with .rpmsave extensions during an RPM upgrade. However, if you upgrade twice, you will wind up with useless .rpmsave backup files.LON-CAPA-krb4-3.1-1This RPM encodes 222 files needed to support Athena-Kerberos version 4 authentication.LON-CAPA-loncapaconfig-3.1-1This RPM encodes a python-Tk GUI for configuring variables on your LON-CAPA machine. There are 569 files in this RPM. /usr/sbin/loncapaconfig launches the GUI. The GUI works well, but is not yet recommended for standard use. LON-CAPA-mysql-3.1-1This encodes MySQL version 3.23.33. This is the backend 'engine' for handling libraries of metadata. The usage of MySQL and LON-CAPA is described in greater detail at http://install.lon-capa.org/docs/loncapasqldatabase.html. This RPM contains 1066 files.LON-CAPA-systemperl-3.1-1This RPM contains 445 files which encode for various builds of perl modules taken from www.cpan.org. These perl modules come from about 16 different CPAN packages: Algorithm::Diff, Authen::Krb4, Crypt::DES, Crypt::IDEA, DBI, Digest::MD5, HTML-Tree, HTML::Parser, HTML::Tagset, MIME-tools, MIME::Base64, Msql-Mysql-modules, Net, Safe::Hole, URI, and libwww-perl. LON-CAPA-barcode-3.1-1This RPM contains 73 files which encode for the GD graphics library and a perl module GD::Barcode which manipulates the graphics library to produce a wide range of barcode formats. This RPM is described better at CVS:doc/build/barcode.htmlA note on dependencies
In an ideal world, we could understand how to install anything and how every piece of software relied on every other piece of software. This would make compiling installations and upgrading computers a LOT easier. 
Ideally, we would have used pre-existing RPMs for MySQL and some of the perl modules. The current, pre-existing RPMs for these components are found within ftp "contrib" repositories. 
Unfortunately, these "contrib" RPMs make false assumptions about the standard directory setup of a RedHat 6.2 system as well as the existing shared object libraries. The solution was to "roll our own" RPMs based on compilations directly from source. 
A note on the installation CD
We make every effort to include up-to-date RPMs on our installation CDs. This helps reduce the number of errors and increase security on LON-CAPA systems. 
Unfortunately, it is not straightforward to have up-to-date kernels installed on machines. This is because the installation code (mostly written by RedHat) only supports one kernel version. After installation, you will need to upgrade your kernel by following instructions at http://www.redhat.com/support/docs/howto/kernel-upgrade/kernel-upgrade.html. I recommend that you do this soon after installation. In case something goes wrong, you can always start again. 
The only other minor note is that the RedHat 6.2 upgrade RPM xntp3-5.93-15 was not installing correctly from the installation CD due to a dependency on a high version of rpmlib not present in the installation CD binaries. This was fixed by rebuilding the xntp3-5.93-15 RPM from a .src.rpm (source rpm) on a RedHat system with old versions of the rpm-* RPMs. 
LON-CAPA Installation Instructions
for the 05/24/2001 developer's release Scott Harrison, last updated 05/19/2001
What you need: 
a RedHat Linux compatible computer that is hooked up to the ethernet with a working IP address, 
a LON-CAPA installation CD, 
and an installation boot floppy. 
Starting instructions: 
Turn the computer off. 
Insert the "LON-CAPA Installation Boot Floppy" 
Turn the computer on. 
During boot-up, insert the "LON-CAPA Installation CD-ROM" 
(For systems with bootable CD-ROM devices, you can just use the CD-ROM and not use the installation boot floppy). 
Warnings: 
Installation will remove all data on your computer. 
This is a prototype installation release of a developing software system. 
We are developing documentation on the LON-CAPA installation at http://install.lon-capa.org/. Documentation is not well developed on these pages, but it may be of some help in understanding the system internals. 
Standard legal disclaimer: Use this software at your own risk. By using this software you assume all liability for its operation. 
Installation screens: The following installation screens present an example installation for a computer grover.morphy.edu (12.34.56.99) done by a Doctor Herbert Sherbert. Since this is the first installation of a LON-CAPA server at Morphy University, Dr. Sherbert chooses to install a library server which can store educational resources (as opposed to an access server which simply load-balances high amounts of web server requests). For those experienced with RedHat-type installations, there are really only two screens which are specific to setting LON-CAPA system parameters. 
Installation Welcome Screen. Just press the "Enter/Return" key at this first screen. 
Language Selection. Choose English. (It is the only supported language so far in the translation tables associated with the installation). Select "OK" to advance to the next screen. 
Keyboard Selection. Most likely, you have a "us" keyboard which is the default setting. Select "OK" to advance to the next screen. 
Welcome to Learning Online!. This screen directs you to look for more information at http://install.lon-capa.org/. Please be advised that documentation on these pages is not highly developed. Select "OK" to advance to the next screen. 
Installation Type. Five options are presented on this installation screen. 
Install LON-CAPA Library Server 
Install LON-CAPA Access Server 
Install LON-CAPA Library Development Server 
Install LON-CAPA Access Development System 
Upgrade Existing Installation 
If this is the first LON-CAPA machine you are setting up at your institution, I strongly recommend you select "Install LON-CAPA Library Development Server". The first two choices are run-time servers which are significantly more secure (for instance, do not support telnet, just ssh). These choices do not support X-windows or other system amenities which will make tinkering and learning about the LON-CAPA system more difficult. Select "OK" to advance to the next screen. 
Manual Partitioning. Read the screen. Write down the amount of RAM on your system. Multiply the RAM by ten and calculate the number of MEGAbytes (not kilobytes) of swap space your system is recommended to be on your hard drive. Select "OK" to advance to the next screen. 
Current Disk Partitions. More information on using disk druid to properly configure a linux system is present on many different internet sites that you can find with an internet search engine like www.google.com. One such site is http://www.linuxinfor.com/rhl70/s1-textmode-partition.html. Partition your hard disk. Select "OK" to advance to the next screen. 
Choose Partitions to Format. Select all your partitions and select "OK". (You probably do not need to check for bad blocks during the format). 
Hostname Configuration. Dr. Sherbert would enter grover.morphy.edu. You would enter the host name corresponding to the working IP address attached by ethernet to your computer. Select "OK" to advance to the next screen. 
Network Configuration. Do NOT use bootp/dhcp. LON-CAPA only works with static IP. Enter in the IP address of your computer (e.g. 12.34.56.99). Find out the correct values for netmask, gateway, and primary nameserver from other personnel at your institution (or look at information present on currently connected computers). Select "OK" to advance to the next screen. 
Library Server Configuration. "LON Host ID" can be any set of alphanumeric characters. This host id must be unique (per computer) in terms of the entire worldwide LON-CAPA network. The system administrator e-mail is where periodic status reports are e-mailed in the event of system startup, shutdown, malfunction, and routine checks. The domain is a set of alphanumeric characters unique to a given institution. The final two fields, "Load Limit" and "Expiration Time", allow for the handling of server load and cached educational resources. We recommend that you leave these two fields at their default values. 
&
Fig 3.1.1  Library Server Configuration
Library System Settings. Many different kinds of computers are used at Morphy University: Macintosh, Linux, BSD, and Windows 3.1/95/98/2000/Me/NT. To provide flexible and easy access to the library server for faculty participants, Samba is selected to enable Windows/Network Neighborhood file shares (e.g. Loncapa_morphy/Morphyl1). Apple Shares is selected to enable Apple Share connection with the Apple "Chooser" (e.g. LONCAPA_MORPHYL1). NFS is selected to enable user-specific network file services for Linux (and other) computers with NFS client utilities. NTP Server allows for the synchronization of time and should be set to an IP address that supports the XNTP version 3 protocol; if left blank, there will be no time synchronization on the server, though it's time is expected to remain relatively constant (and correct if the machine is configured properly). Kerberos realm allows for authenticating students and instructors based on an institution's Kerberos version 4 password-checking scheme (if supported by the institution). IMPORTANT: You will need to add an entry to hosts.tab (second "Add" key) corresponding to your new installation. Dr. Sherbert would enter something corresponding to morphyl1:morphy:library:grover.morphy.edu:12.34.56.99.
&
Fig 3.1.2  Library Server Configuration
Mouse Selection. Enter the appropriate values for describing the model mouse attached to your computer. Select "OK" to advance to the next screen. 
Time Zone Selection. You probably do not want to select the GMT option. Just enter in the time zone of your institution. (If the time is incorrect upon system bootup, and you cannot or do not want to connect to an NTP server, you can always reconfigure the system time with the command, as root, /usr/sbin/timeconfig). Select "OK" to advance to the next screen. 
Root Password. Enter in your machine's root password. Be creative and decide on something non-guessable. Select "OK" to advance to the next screen. 
Web Server Password. Enter in your machine's password for a user 'www'. Select "OK" to advance to the next screen. 
Add User. Add a user to the machine. Select "OK" to advance to the next screen. 
User Account Setup. Perform any additional changes to the user accounts on your machine. Select "OK" to advance to the next screen. 
X probe results. (We assume you have a detectable video card). Select "OK" to advance to the next screen. 
Warning, Installation to begin. You will now erase all data on your hard disk and install the LON-CAPA system. Select "OK" to courageously begin. 
Package Installation. A carefully selected set of RPMs is being installed that provides full LON-CAPA system functionality. 
Bootdisk. If you want (though it is probably not necessary), you can insert a fresh (NOT your LON-CAPA installation boot floppy) floppy disk to help ensure you can boot up your LON-CAPA server system. 
Monitor Setup. Select what kind of monitor is attached to your computer (or just choose custom). Several screens will follow which guide your configuration of your computer monitor. (Note that this configuration only occurs with development servers, since the other servers do not support X-windows). It probably makes sense to start "X" up when booting if it appears it is correctly configuring your computer monitor. 
Note about hosts.allow. To enable various kinds of network connectivity (including appleshares, network neighborhood, telnet, ftp, nfs) from other computers on the internet, you may want to adjust your /etc/hosts.allow table after boot-time. (The web server and the LON-CAPA network layer do not depend on /etc/hosts.allow however.) Dr. Sherbert added the following line to his /etc/hosts.allow file to make sure other computers at Morphy University could access grover.morphy.edu: 
ALL: .morphy.edu
Alternatively, to allow wide access (though password-protected) to anyone in the world, Dr. Sherbert could have added 
ALL: ALL
Complete. Select "OK" to reboot the system. Be sure to remove your installation medium (both the CD-ROM and installation floppy) before boot-up. 
Booting up for the first time: 
It will probably say "Cannot connect to the database!" after the loncontrol server process runs upon boot-up. You need to edit /etc/httpd/conf/access.conf and replace the line 
PerlSetVar   lonSqlAccess {[[[[lonSqlAccess]]]]}
with 
PerlSetVar   lonSqlAccess   123
Please, as root, run "sh /usr/sbin/loncapa_configure". This is a one-time action that synchronizes the system services on the machine. 
Feedback: 
Specific ideas on how to manage the installation can be sent to harris41@msu.edu. In terms of bug reports, we would also like to hear from you, but there is no need for great detail (or despair?) since the bug is most likely already on our "to-do" list. 
Setting yourself up for CVS
These instructions assume bash (as opposed to tcsh). 
You will also need an account on zaphod.lite.msu.edu. Please e-mail lon-capa@hobbes.lite.msu.edu and request that an account be created. 
The straightforward way to enable CVS is to manually configure your environment and log in: 
export CVSROOT=:pserver:USERNAME@zaphod.lite.msu.edu:/home/cvs cvs login 
You can also modify your shell environment (.bash_profile and .bash_logout). 
The commands:export CVSROOT=:pserver:USERNAME@zaphod.lite.msu.edu:/home/cvs cvs login can be appended to ~/.bash_profile. "cvs logout" can be appended to ~/.bash_logout 
To check out LON-CAPA, go to any writeable directory and type: 
cvs co loncapa
This will create a directory tree similar to: 
loncapa_________CAPA
          |
          |_____loncom
          |
          |_____doc
          |
          |_____rat
          |
          \_____packaging
Useful commands are: 
CommandDescriptioninfo cvsdoc'scvs log FILENAMEsee what's happened with a filecvs update -dupdate your CVS tree from the current directory locationCVS Upgrade
Assuming that you have set yourself up for LON-CAPA CVS, periodically upgrading your system is a simple process. 
StepsCommandsMake sure you are logged in for CVSexport CVSROOT=:pserver:USERNAME@zaphod.lite.msu.edu:/home/cvs cvs loginGo to your repository directorycd loncapaUpdate your CVS sourcescvs update -dGo to the build directorycd loncom/buildBecome 'root'suInstall/update static filesmake installInstall/update dynamically configurable filesthis preserves the current settings of your machine, don't worry :) make configinstallRestart your web serverDue to an apache bug, you should enter this command twice. Restarting the web server will 
introduce changes made to /home/httpd/lib/perl/Apache/*.pm files; 
update user and group permissions if /etc/passwd or /etc/group change. /etc/rc.d/init.d/httpd restart /etc/rc.d/init.d/httpd restartRestart the lonc/lond processesBe patient (this takes several minutes)./etc/rc.d/init.d/loncontrol restartAfter CVS logging in, you can always cut and paste this line below assuming you do everything as root :)cd loncapa; cvs update -d; cd loncom/build; make install; make configinstall; /etc/rc.d/init.d/httpd restart; /etc/rc.d/init.d/httpd restart; /etc/rc.d/init.d/httpd restart; /etc/rc.d/init.d/loncontrol restartIt may be also advisable to test your system after an upgrade if there are critical tasks it is being used for. 
The specification file which defines the CVS:source-to-system information is CVS:doc/loncapafiles/loncapafiles.html. Changes to this file directly translate into changes in the installation. 
RPM Upgrade
BE CAREFUL. READ THIS STUFF. 
WARNINGS: 
Do not ever install or upgrade an LON-CAPA-base RPM. You will lose important configuration information on your machine. The CVS upgrade is much safer and more effective in bringing you up to date. 
Do not ever install or upgrade a LON-CAPA-setup RPM. You will lose information from your /etc/group, /etc/passwd, and other important files. 
Be careful about installing a LON-CAPA-mysql RPM. You need to run /home/httpd/perl/searchcat.pl after this to re-seed your metadata database. 
Don't upgrade/install/delete your kernel RPM unless you have done it before. 
There are four things involved in an RPM upgrade: 
Gaining information about the RPMs on your system. 
Upgrade existing RPMS from a trusted source 
Remove RPMs which do not belong 
Add new RPMs 
Gaining information about the RPMs on your system: "make rpmstatuspost" will tell you about RPMs which do not belong (are "external" to LON-CAPA). It will also tell you if you have "out-of-date" RPMs which should maybe be upgraded. Important specification files for RPM installation are CVS:doc/otherfiles/rpm_list.txt and CVS:doc/otherfiles/cd_rpms.txt. 
Upgrade existing RPMS from a trusted source: RPMs are currently available at 
http://install.lon-capa.org/3.1/currentcdsource/RedHat/RPMS 
For example, to upgrade your LON-CAPA-systemperl RPM, you would enter commands like 
wget http://install.lon-capa.org/3.1/currentcdsource/RedHat/RPMS/LON-CAPA-systemperl-3.1-1.i386.rpm(then as root) rpm -Uvh --force LON-CAPA-systemperl-3.1-1.i386.rpm 
Remove RPMs which do not belong: If an RPM should NOT be on your system (like apmd), then you want to remove this RPM. Since RedHat is a little erroneous when it comes to dependencies, you may wish to use the --nodeps flag. 
rpm -e --nodeps apmd-3.0final-2.i386.rpm 
Add new RPMs: Use the same command as for upgrading. 
(as root) rpm -Uvh --force icewm-1.0.5-gnome.i386.rpm 
We often use icewm as our development machine window manager given the RedHat 6.2 bugs involving enlightenment and gnome. 
Viewing the status of your machine
StepsCommandsMake sure you are logged in for CVSexport CVSROOT=:pserver:USERNAME@zaphod.lite.msu.edu:/home/cvs cvs loginGo to your repository directorycd loncapaUpdate your CVS sourcescvs update -dGo to the build directorycd loncom/buildBecome 'root'suView the CVS source->install status of your machinemake statuspost then visit http://MACHINENAME/lon-status/filestatus.htmlView the RPM status of your machine make rpmstatuspostthen visit http://MACHINENAME/lon-status/rpmstatus.htmlSubmitting software patches
Scott Harrison, last updated 05/19/2001 
The system works, yet there remains much tweaking to do. 
&
General Guidelines
submit patches to albertel@msu.edu 
patches must be a unified diff format (-u) 
should be against a specific CVS tag (like HEAD, or when we get to releases, the most recent *_RELEASE tag) 
should contain a description of bugs they fix or functionality they add 
try to make each patch as targeted as possible. (Fix 1 bug, or add 1 feature) to make it easier to see what is going on. 
Large functionality changes should probably get some discussion on the mailing list before being submitted. 
Example Scenario
Large functionality changes should probably get some discussion on the mailing list before being submitted. 
A fictional Dr. Sherbert is writing a handler to display web statistics (information present in /var/log/httpd/access.log). Here is a list of e-mails and commands which take place. 
Dr. Sherbert e-mails the list with his idea 
sherbert %> mail lon-capa@hobbes.lite.msu.edu
Hi,

I want to create a handler to show web statistics (hits
per hour, IP addresses, most popular URLs, hits per day,
etc).  This would provide data I can show the
administration as well as helping me better monitor
how adequately my server cluster is performing.
I plan on calling this handler lonapachestat.pm, associating
with apachestat, and available only to those with roles (see
roles.tab and rolesplain.tab) of "gan=generating anonymous
statistics".  I would make appropriate changes to
/etc/httpd/conf/srm.conf

-Bert
Two others respond on the mailing list. 
gwynne %> mail lon-capa@hobbes.lite.msu.edu
Bert,

I like that idea, but don't you think that this is
better handled as a batch-cron job?  Why not have
these statistics compiled every day?  I think
SOURCE="loncom/cron/loncapa" TARGET="etc/cron.d/loncapa"
handles this.  Also, I assume you mean associating
with the location http://MACHINENAME/adm/lonapachestat.

Gwynne


godfried %> mail lon-capa@hobbes.lite.msu.edu
Bert,

This would be of immense help to some questions I have.
I want to be able to "play-back" what each user session
is doing for my course.  Also, if a student e-mails me,
I want to be able to see where in the course sequence
the student was working.  I would need the statistics calculated
dynamically as opposed to a batch process.

Godfried
After more discussion, Dr. Sherbert's idea is accepted.  
PATCHING /etc/httpd/conf/srm.conf 
submit patches to albertel@msu.edu patches must be a unified diff format (-u) should be against a specific CVS tag (like HEAD, or when we get to releases, the most recent *_RELEASE tag) should contain a description of bugs they fix or functionality they add try to make each patch as _targetted_ as possible. (Fix 1 bug, or add 1 feature) to make it easier to see what is going on. 
Dr. Sherbert wants to alter the web server configuration so that whenever http://MACHINENAME/apachestat is requested, the lonapachestat.pm handler is called. 
To do this, he needs to alter srm.conf. After setting up CVS and checking out LON-CAPA (cvs co loncapa), he needs to find srm.conf in the CVS source repository. 

[sherbert@morphy1 loncapa]$ find . -type f | grep srm.conf
./loncom/srm.conf
[sherbert@morphy1 loncapa]$ 

Dr. Sherbert sees the following section of code in srm.conf. 
# -------------------------------------------------------------- Admin Programs

<Location /adm/roles>
PerlAccessHandler       Apache::lonacc
SetHandler perl-script
PerlHandler Apache::lonroles
ErrorDocument     403 /adm/login
ErrorDocument	  500 /adm/errorhandler
</Location>

<Location /adm/login>
SetHandler perl-script
PerlHandler Apache::lonlogin
</Location>

<Location /adm/logout>
PerlAccessHandler       Apache::lonacc
SetHandler perl-script
PerlHandler Apache::lonlogout
ErrorDocument     403 /adm/login
</Location>

Dr. Sherbert then adds in his handler. 

# -------------------------------------------------------------- Admin Programs

<Location /adm/apachestat>
PerlAccessHandler       Apache::lonacc
SetHandler perl-script
PerlHandler Apache::lonapachestat
ErrorDocument     403 /adm/login
ErrorDocument	  500 /adm/errorhandler
</Location>

<Location /adm/roles>
PerlAccessHandler       Apache::lonacc
SetHandler perl-script
PerlHandler Apache::lonroles
ErrorDocument     403 /adm/login
ErrorDocument	  500 /adm/errorhandler
</Location>

<Location /adm/login>
SetHandler perl-script
PerlHandler Apache::lonlogin
</Location>

<Location /adm/logout>
PerlAccessHandler       Apache::lonacc
SetHandler perl-script
PerlHandler Apache::lonlogout
ErrorDocument     403 /adm/login
</Location>

Dr. Sherbert then creates a unified diff format of his changes against the HEAD (current) release. 

[sherbert@morphy1]$ cd loncapa/loncom
[sherbert@morphy1]$ cvs diff -U 3 -r HEAD srm.conf
Index: srm.conf
===================================================================
RCS file: /home/cvs/loncom/srm.conf,v
retrieving revision 1.14
diff -U3 -r1.14 srm.conf
--- srm.conf	2001/05/15 12:35:07	1.14
+++ srm.conf	2001/05/19 13:14:53
@@ -353,6 +353,14 @@
 
# -------------------------------------------------------------- Admin Programs 
+
+PerlAccessHandler       Apache::lonacc
+SetHandler perl-script
+PerlHandler Apache::lonapachestat
+ErrorDocument     403 /adm/login
+ErrorDocument	  500 /adm/errorhandler
+
+
 
 PerlAccessHandler       Apache::lonacc
 SetHandler perl-script

Dr. Sherbert e-mails his patch to Guy.
 
[sherbert@morphy1]$ cvs diff -U 3 -r HEAD srm.conf | mail -s 'patch to\
 srm.conf to add adm/apachestat handling with lonapachestat.pm'\
albertel@msu.edu

Guy responds 

Bert,

Your change was checked into the LON-CAPA system.  Thanks!

-Guy

Dr. Sherbert did the following right things. 
he described the fix in his mail message patch to srm.conf to add adm/apachestat handling with lonapachestat.pm 
his submitted change fixed 1 bug/feature 
he created a unified diff format for his patch 
Session 2: Worktime
Session 3: Projects

Large Chunks of functionality that need work:

- Statistics
	- Simple
		- resource analysis class/system wide
		- resource correlation course wide
		- other stats from CAPA
	- Complex
		- foil level analysis/correlation measures
		- derandomized foils analysis
		- have/view reason student selected a foil
	- resource quality, how good is a resource

- Messaging
	- crtical messages
	- email gateways into/out of the system
	- handle more types of communication
	       - stu <-> stu
	       - ins <-> stu
	       - ins -> class/section
	       - messages seeded with data from spreadsheet
	       - chat / whiteboard / bbs
	       - "round robin" feedback handling

- Grading
	- simple grading needs cleaning up (see Guy's TODO list)
	- survey data extraction ( stat complex could handle most of
	  this)
	- essay / shortanswer
		- instructor / autoget all/none
		- team based submission
		- peer graded
		- peer suggest grade

- homework engine
	- new parm - mode -> homework/exam/survey controls response
	  renderings / awards and solved status
	- edit interface / clone other problem
	- math stuff
	- validating <part> and multiple <*response> works as
	  advertised
	- handling previous answers correctly
	- CAPA problems 
	- <imageresponse> need Java applet
	- <randomlabel> 

- metadata
	- implement new method of handling what a problem stores

- RAT
	- set parms / choose parts
	- set conditions
	- language for conditions
	- browse link
	- some kind of non-anti-save

- Publish
	- review step
	- coauthor role
		- permisions / locking
	- retrieve diff
	- auto thumbnail / convert images

- printing
	- tex target (CGI / daemon?)

- Remote Control
	- instructor remote (MyDesk?)
	- evaluate this quality control feedback
	- level up / down

Example of a TODO list

+ add functionality
& change functionality
* bug
! Priority
? Questionable/unverified
c Continual

G=Gerd
A=Alex
S=Scott
B=Ben
Y=Guy
N=Hon-Kie
I=Issac

XMLPARSE
    + support text_TAG functionality (Y/A)
   !* needs to fixup missing end tags in source (Y/A)
    + add <options> tag (A)
    + counters and output formats for counters (A/Y)   
    + deregister()
    + register need to take care of overloading, and deregister needs to unload
    + answer target - for simple display of correct answer for a problem
    * <m> tag needs to do variable evaluation before tth-ing the string, also 
 	add eval="nothing" to turn this off.
    * convert the rest to use get_param

CAPARESPONSE.C
   !+ pass back the reason (Y)

RUN.pm
    & ->share() a var rather than pass a parameter? Maybe set 
      a global in the safe enviroment using ->root()?

EDIT INTERFACE
    + undo (Y)
    + delete (Y)
    * insert (getting there) (Y)
    c add more tags (Y)
    & make it easier to add plain textfield stype entries (Y)
    + have textfield style entries protect against bad data (</parserlib> in 
	the parserlib textfiled (Y)
    + make default setup prettier

HOMEWORK
    + need to support /OR (Y)
   !+ create <stringresponse> <formularesponse>(Y)
   !+ <rbresponse> <oresponse> need to restore last submitted response (Y)
    + <rbresponse> <oresponse> hints need to work (Y)
    * <rb/i/o response> break if name isn't spcified (Y)
    & all response types need to be verified about what they do after the 
      answer date (Y)
    + view problem as specific student (Y)
    + <imageresponse> needs to be able to support multiple images and multiple
        clicks on an image, need a Java applet most likely
    * <essayresponse> needs to protect input / output

/ADM/GRADES
    * show list of multiple students if multiple match (Y)
    * allow specifying the domain (Y)
    + handle ambiguous case (Y)
    + back to homework link (Y)
    + handle extra fields (Y)
    + interface needs to be driven more by the type field (Y)
    + show only a subset of students (Y)
    + does IE 5.5 like it? (Y)
    + set all to something (Y)
    + set grades aren't correctly rendered in student view (Y)

NUMERICALRESPONSE
   !* doesn't throw error when #response > #answer (Y)
   !* bad message when #response < #answer (Y)

GOODIES
    * bookmarks don't work correctly (B)
    * indexer does not always work (N)
    + messaging (G)
    + chatroom, etc
    + annotations can be localized and published
    + PURLs

/ADM/CREATEUSER
    * cc setting allows section
    * do stu sections settings actually work
    * dc shows machines not just domains

TEX/TTH/TTM
    * Address bugs in tth/ttm (second half January, A,Y,G)

BUILD
    * make sure that ssh is always allowed, even for run-time servers

SQL DATABASE
    *!need to improve sql database security (S)
    * need to allow for parsing logic statements for metadata database (S)
    * need to call all library servers (S)
    * need to show status of library server retrieval (S)
    * need to perform customized metadata search (S)

GERD STUFF
    + lecture online converter does all types (G/Y)
    + lond can add UNIX user and change UNIX password (G/S)
    & lond produces no history files for nohist_ namespaces
    + pageflip up and down work
    + feedback, mailing and announcement mechanism finished
    + londropadd does XML
    +?TAs can open and close assignments
    *?menu.html does weird stuff on some browsers sometimes (maybe fixed)
   !& tests interaction between parmset, problem handler and spreadsheet (G)
    + course id-field

RAT
    + RAT can set resource parameters (G)
    *?RAT error line 1413 "insert resource into link" for recon link (G) 
      (could not reproduce)
    + need to be able to evaluate conditions in lonuserstate
    + need to be able to set conditions in RAT client (G)
    * "finish" resource non-editable
    * unescaped colons in resource titles

PUBLISHER
    * needs to devalidate spreadsheets in problem publishing (G)
    +?does HTML to XHTML cleanup job



Glossary

Server  The Network has two classes of servers, library servers and access servers

Home Server of a user  Server that stores all personal records and resources of a user

Library Server  A library server can act as a Home Server that stores all personal records of user, and is responsible for the initial authentication of that user when a session is opened on any server in the Network. For Authors, it also hosts their construction area and the authoritative copy of every resource that was published by that author. Library servers can be used as backups to host sessions when all access servers in the Network are overloaded.

Access Server  machines that host learner sessions.

Domain  The Network is divided into domains  domains could be defined by departmental or institutional boundaries. Domains provide the possibility to limit the spread of personal user information flow, load balancing, and content material.  Physically, every domain needs at least one dedicated library server.

Users  users are identified by a usernames and the domain. Usernames need to be unique within a domain and are not coupled to specific courses. They can also be carried over several semesters.

Role - Every user can have several roles, and the roles can change over the lifetime of a username. For example, over the course of studies, a student username assumes the role of "student" in different courses.

Resource  multimedia piece of content

Rendering  the process of generating output from resources

Granularity  grain size of a resource. The system distinguishes between four generic levels of granularity: fragment, page, sequence and course

Fragment  a resource of the smallest self-contained renderable grain size. Examples: one
image, one movie clip, one paragraph of text

Page  a resource of the grain size which would be rendered as one page on the web and/or on
the printer

Sequence  a resource which would be rendered as a sequence of pages, not necessarily
linear. Examples: one lesson, one chapter, one learning cycle

Course  a sequence which represents the entirety of the resources belonging to a learning
unit into which learners can be enrolled. Examples: a University one-semester course, a
workshop, a High School class. Courses are defined by a "course-level" resource assembly map and an enrollment list with sections. 

Resource Priority  a resource can be regular, mandatory or optional. These resource priorities are only used in book-keeping of earned points by the learners. There are two additional resources priorities, start and finish which cannot be set by authors

Map  a page, sequence or course resource

Start Resource  the first resource or entry point of a map
Finish Resource  the last resource or exit point of a map

Link  path from one resource to another within a map

Condition  condition under which a link can be taken. Examples for variables used in conditions: course parameters, learner performance, learner preferences, date

Condition Priority  a condition can be used to recommend a certain link over others branching off from the same resource, to block a link if it is false,  or to force a link over all others if true

Resource Assembly  the process of generating a map by referencing and linking resources. The system allows for assembly of fragments and pages into a page; fragments, pages, sequences into a sequence; fragments, pages, sequences into a course.

Resource Pool  the entirety of the resources stored and cataloged within the system itself

External Resource  a resource which is not part of the resource pool

Author  the author of a resource

Learner  the consumer of resource renderings

State  the entirety of the conditions which determine a particular learner's rendering of a
course. 

Linear Resource Assembly  the process of combining a set of resources into a non-branching
non-variable order, where the rendering is independent of state. Examples: an image and a
paragraph of text get assembled into one page where the image will always be rendered on top
of the paragraph.

Technical Presentation (January 2001)

The following presentation was given at the LON-CAPA User Conference in January 2001.




The Guts of LON-CAPA Workshop	-  PAGE 38 -

	-  PAGE 4 -



?ADFPQ&'(@ABbc !34TU{|}./0񪣪j&&U&mH
jU&mHmHj&&U&j&&U&j&&U&jI&&U&0Jj&&U&0JCJ$j&&CJ$U&CJ$
jCJ$U&	jU&CJH*&CJCJH<9MNOPRSTUVWX~BQR56$$&&&9MNOPRSTUVWX~BQR56
3w	O	]				V
        !             2: 
        !             3: 
        !             4: 
W(h
P



'n&&/yIhA
3w	O	]				V
        !             5: 
        !             6: 
        !             7: 
W(h
&!
        !             8: 
&!
        !             9: 
&!
        !            10: &012WXrstuv./IJKMNlm					<	=	W	ji&&U&mHj&&U&mHjo&&U&mHj&&U&mHju&&U&mHj&&U&mHj{&&U&mHj&&U&mH
jU&mHmH=W	X	Y	[	\	p	q																				5
        !            11: 6
        !            12: P
        !            13: Q
        !            14: R
        !            15: T
        !            16: U
        !            17: n
        !            18: o
        !            19: 
        !            20: 
        !            21: 
        !            22: 
        !            23: 
        !            24: 
        !            25: 
        !            26: 
        !            27: 
        !            28: 
        !            29: 
        !            30: 
        !            31: 
        !            32: 
        !            33: 	67QRSUV_j&&U&mHjQ&&U&mHj&&U&mHjW&&U&mHj&&U&mHj]&&U&mHj&&U&mHjc&&U&mHmH
jU&mHj&&U&mH=_`z{|~"#$&'GHbcdfg|}



j3&&U&mHj&&U&mHj9&&U&mHj&&U&mHj?&&U&mHj&&U&mHjE&&U&mHj&&U&mHjK&&U&mHmH
jU&mH=
P



'n>y3u
        !            34: E{T
&!
        !            35: 
&!
        !            36: 
&!
        !            37: 

/
0
J
K
L
N
O
q
r



















!"#%&MNhijlm89j&&U&mHj&&U&mHj&&U&mHj!&&U&mHj&&U&mHj'&&U&mHj&&U&mHj-&&U&mHj&&U&mHmH
jU&mH=9:<=XYstuwx	
        !            38: 
-./12TUopqst	$%?j&U&mHj&U&mHj&&U&mHj	&&U&mHj&&U&mHj&&U&mHj&&U&mHj&&U&mHmH
jU&mH>>y3u
        !            39: E{T,`%V6]dUBo$V13:^n o o!p!!!!!j#k###%¿HI12
        !            40: w
        !            41: g
        !            42: &&&&H?@ACDZ[uvwyz
34NOPRS^_yz{}~&j&U&mHjh&U&mHj&U&mHjn&U&mHj&U&mHjt&U&mHj&&U&mHjz&&U&mHmH
jU&mHj&U&mH=,`%V6]dUBo
&!
        !            43: 
&!
        !            44: 
&!
        !            45: &'(*+?@Z[\^_st !#$56PQRTUz{jJ	&U&mHj&U&mHjP&U&mHj&U&mHjV&U&mHj&U&mHj\&U&mHj&U&mHjb&U&mHmH
jU&mH=	
        !            46: 01245<=WXY[\CD^_`bc{|j
&U&mHj2
&U&mHj&U&mHj8&U&mHj&U&mHj>&U&mHj
        !            47: &U&mHjD
        !            48: &U&mHj	&U&mHmH
jU&mH=45OPQSTst!"<=>@ANOijkmnj&U&mHj&U&mHj&U&mHj &U&mHj&U&mHj&&U&mHj&U&mHj,&U&mHmH
jU&mH> "#56PQRTUjk+,-/012^_ibl	
        !            49: 5CJ5CJ	jU&	jU&j&U&mHj&U&mHj&U&mHj&U&mHj&U&mHj&U&mHmH
jU&mHj&U&mH=$V13:^n o o!p!!!!!j#k##&&&&&
&!
        !            50: 
&!
        !            51: 
&!
        !            52: }~!!"";"<"E"F"""""""#
###)#*#2#3#8#9#t#u#z#{#######^$_$$$%%%%5%6%G%H%L%M%%%%%%%&&'&(&*&+&0&1&3&>&i&l&p&q&B'J''')
)|))**6OJQJ5a##%%%%%&&l&m&!'"'((++--..00v2w23344
!&&%%%%%&&l&m&!'"'((++--..00v2w23344)5*5z6{677777788====V>W>|yv
        !            53: Rijz{./cdwxop67TU
        !            54: <
,*****++++++P,[,t/x/0 000216111113	3'4+4Y4]444#5'5*5.5555566{66666777777777888	888!8%81858&99u9v9999999v:|:::3;4;6;:;;;;;<<<<5CJ
jPCJU&CJ56OJQJ\4)5*5z6{677777788====V>W>>>> ?X????6@m@$&&&<A=G=>'>V>W>AA$AEAbAdAvAAAAABB>BBBBBCCDDEEEEFFFFGGGGGGHHIIIIIiItII#J(JcJdJfJmJJKKLLYQcQRRRRRRRRKT`TUU2V=VCVKV-W
j[7CJU&
j	CJU&6h5hOJQJhhCJOJQJ5CJCJ5OJQJQW>>>> ?X????6@m@@@AAAcAdADDEEGGIIiIjIbJcJeJfJJJJMM:M;MOOþ~{xroli
        !            55: &wxy02=>}~)*&+	&
        !            56: d	&
        !            57: 	&
        !            58: 	&
        !            59: 	&
        !            60: C	&
        !            61: z	&
        !            62: 	&
        !            63: 	&
        !            64: "	&
        !            65: V	&
        !            66: 	&
        !            67: 	&
        !            68: (m@@@AAAcAdADDEEGGIIiIjIbJcJeJfJJJJM&"$&$&l&&&&&&&,""$&MM:M;MOOPPQQ8T9T0U1UXXXXXYYYYYQYRYy\z\^^&&OPPQQ8T9T0U1UXXXXXYYYYYQYRYy\z\^^aaaacccccdd#f$f&f'f(fQf~ff9g~xu
        !            69: 
        !            70: &/0 !PQxy@A,-W0WWWXXXXXYYYYYY#YQYUY]Y=ZRZZZ["[D\G\\\q]y]]]]]Y^`^^^^
        !            71: ___&`<```aab
bFbNbbbccccccccccccccccccdd d]dedddee$fCJOJQJCJOJQJOJQJ
jCJU&5CJ
jӱCJU&CJ5R^aaaacccccdd#f$f&f'f(fQf~ff9g:gvgwg^i_ivjwj*l
        !            72: &F&&&$f%f&f'f(f5fOfQf:g@gugwg|ggggg_idinioiyi~iiiwjyjjjjjjjkk+l;llllllllmmmmmmmmnnnn$n.nZn5xMxyyyyy}}5CJ(OJQJCJOJQJ5CJOJQJ	jCJmH	jCJmH6OJQJ6OJQJ
        !            73: 56CJCJ565CJB*CJ8jz_	B*CJ8U&C9g:gvgwg^i_ivjwj*l+lllmmm$nZn[npprr{s|sttvvwwyy4z5zOzvzzzz{0{}zwtqnk9ST
        !            74: jST
        !            75: !e	&
        !            76: &	&
        !            77: 	&
        !            78: 	&
        !            79: &
        !            80: 	&(*l+lllmmm$nZn[npprr{s|sttvvwwyy&
$d&&%d&&d&&'d&$d&&%d&&d&&'d&@&
        !            81: &F&y4z5zOzvzzzz{0{A{B{]{{{{{|;|c|t|u|||||||}
$d&%d&&d&'d&0{A{B{]{{{{{|;|c|t|u|||||||}H}u}}}}}~~1~H~g~x~y~~~~~~~2CE~{xuCEVr!@Wtu@i%Mz	+FGX.}H}u}}}}}~~1~H~g~x~y~~~~~~~2CE
$d&%d&&d&'d&}}CDāŁÂǔU`fw)Zc˖Ø˘ə͙ۙBI˚͛Λ<=KLٜڜKLXmH
        !            82: 	jmH
        !            83: 	jmH56OJQJh&CJOJQJ5CJCJ5CJOJQJ5CJ(OJQJCJOJQJ5CJ OJQJH#CTUV9amnāƁ	 CdÂׂ=ӃM„&K~{xuJ#a3np
        !            84: $Eh'Op234Ee|-#CTUV9amnāƁ	 Cd
$d&%d&&d&'d&Âׂ=ӃM„&K6nDׇ$&&
$d&%d&&d&'d&K6nDׇ$_2g=.]i"F֍9_َ>iS~{xu_2q7~*N{VxBk3	>L,n:%.$_2g=.]i"F֍9_َ&>iS4f.{Ē?*vǔO
        !            85: &F$1$&&&S4f.{Ē?*vǔOyו+":;җӗ	
        !            86: MZwuuuuuuuuuuuuuuuuu&&$	&
        !            87: I$	&
        !            88: Y$	&
        !            89: i$	&
        !            90: $	&
        !            91: $	&
        !            92: $	&
        !            93: %$	&
        !            94: &
        !            95: q$	&r
        !            96: 
        !            97: Fp1{B
        !            98: <.Oyו+":;җӗ	
        !            99: M$&$d&&%d&&d&&'d&$&$d&&%d&&d&&'d&@&$&
!&&&
        !           100: &F$XYڝ۝ܝ/1;gh"'.ğƟ!'ˠ2HNOUV\]cdltա
        !           101: "&,0MUw{ʣ QCJOJQJh&6OJQJOJQJ6CJCJOJQJCJCJ5CJmH5mH
	j5mH
        !           102: 	jmH5
        !           103: 	jmHJZʝ01ghƟʠˠ12tu
!&&d&$&$&$d&&%d&&d&&'d&@&$&$d&&%d&&d&&'d&ʝ01ghƟʠˠ12tuʣˣ 5Y}Ҥ>^¥.JŦݦ?Zvԧ	PQi	4_)sFSɬMe,ֱ-سٳ2LMǴ&&dʣˣ 5Y}Ҥ>^¥.JŦݦ?1$&&?Zvԧ	PQi	4_)sFSɬMe1$&&QiسٳMڸ|Cobdn7=y#+-9?K	w,-
@Kv#;RjCJCJOJQJCJOJQJCJ5CJCJ6OJQJOJQJCJ56CJOJQJCJOJQJh&Me,ֱ-سٳ2LMǴ'a&1$&&'a&V?|ܷTڸ۸,Lj`ٺ	/^{|*BCopռ&=fڽnv~5)Sw>bKL,oDR&&d&V?|ܷTڸ۸,Lj`ٺ1$&&ٺ	/^{|*BCopռ&=fڽnv1$&&~5)Sw>bK
$d&&%d&&d&&'d&
!&"&&&KL,oDRMJQ[
$d&&%d&&d&&'d&MJQ["dxy"#qrnowIJbC
#<>?Rk
        !           104: ,XY~	
        !           105: +QRZs`a&&d"dxy"#qrnowIJb&"&
!&
$d&&%d&&d&&'d&C
#<>Ŝ"$& $&$&&&&&&!!$&$&&"&&
$d&&%d&&d&&'d&>?Rk
        !           106: ,X`&,&Ƥ8&8$&$&v&&&&F!\
M
"$&8$&$&Y&&&&&F!\
M
j+Yc}~*Zr>FS\v~Wa}~"<BLO$JKL;<BDEMNCJOJQJCJOJQJCJCJOJQJ	j]n	U&5OJQJ<CJCJ5CJ0J#CJCJOJQJCJLXY~	
        !           107: &\ &8$&$&Y&&&&&F)	s!$	,H	"$& $&$&&&&&&!!$&$&&"8$&$&Y&&&&&F!\
M

        !           108: +QRZs`a4&&&&&&8$&$&Y&&&&&F)	s!$	,H	"$&a	)<M:wG}_=D,8TgbqGe/6*W}~NOBcs&6LWhv&&d	)<M:wG}_
        !           109: &Fd&$d&&%d&&&d&&'d&&
        !           110: &F$d&&%d&&&d&&'d&&
$d&&%d&&&d&&'d&&&=D,8Tgbq
        !           111: &F
        !           112: d&$d&&%d&&&d&&'d&&
        !           113: &Fd&$d&&%d&&&d&&'d&&
$d&&%d&&&d&&'d&&
        !           114: &Fd&$d&&%d&&&d&&'d&&Ge/6*W}~N&
        !           115: &Fd&$d&&%d&&&d&&'d&&
$d&&%d&&&d&&'d&&
        !           116: &F
        !           117: d&$d&&%d&&&d&&'d&&NOBcs&6LWhvd&$d&&%d&&&d&&'d&&&<h=c
        !           118: Lp'd&$d&&%d&&&d&&'d&&<h=c
        !           119: Lp'QzKL`wx$5ymxHIYZ\MSk&&l&&&&&&;&<&&&"&#&&&
        !           120: &
        !           121: &O&q&s&t&&&&&d'QzKL`wx$5yd&$d&&%d&&d&&'d&&&d&$d&&%d&&&d&&'d&&Nvwx&HIZ[\f&&&&&&&&q&r&t&}&&>&H&&&+&,&7&:&v&&&&&&&&&&	&"&"&"&%"&("&e"&"&"&"&"&W'&a'&()&	j
U&	jk_
U&CJj`1
5CJU&	jcU&6OJQJ56OJQJjި
        !           122: CJOJQJU&CJOJQJCJ5CJCJOJQJHmxHIYZ\MS&&&
        !           123: &F&d&$d&&%d&&d&&'d&k&&l&&&&&&;&<&&&"&#&&&
        !           124: &
        !           125: &O&q&s&t&&&&&&&&
!$&&&&&&&&&&@&W&=&>&]&^&&&*&+&v&w&x&&&n&o&&&&&&&&&&&&&"&"&"&"&"&e"&"&T$&U$&%&%&E'&F'&e)&f)&l)&~)&)&)&)&)&*&D*&V*&*&*&*&*&#+&Y+&l+&+&+&+&,&n,&},&,&,&,&-&
-&-&-&k-&-&-&V/&W/&/&/&n1&o1&u1&1&1&D2&b2&2&2&3&:3&3&3&3&4&&&d&&@&W&=&>&]&^&&&*&+&v&w&x&&&n&o&&&&&&&&&&&&&&&&"&"&"&"&"&e"&"&T$&U$&%&%&E'&F'&e)&f)&l)&~)&)&)&)&)&*&D*&V*&*&*&*&$&&&()&e)&f)&-&-&-&k-&-&-&-&-&,.&7.&p.&{.&.&.&.&/&//&:/&W/&b/&/&/&n1&o1&&9&9&9&9&F9&>&>&>&>&>&>&?&C&C&C&C&C&C&C&C&C&C&D&D&D&D&D&YH&`H&bH&lH&zH&H&H&H&<I&OI&TJ&[J&qJ&xJ&J&J&J&J&J&K&"K&,K&9K&@K&BK&MK&K&K&xL&L&$M&8M&TM&hM&H*&OJQJ
j
CJU&CJOJQJ5CJ5CJCJ6W*&*&#+&Y+&l+&+&+&+&,&n,&},&,&,&,&-&
-&-&-&k-&-&-&V/&W/&/&/&&&"$&$&l&&&&&&&,""$&/&n1&o1&u1&1&1&D2&b2&2&2&3&:3&3&3&3&4&%4&h4&4&4&4&5&f5&u5&5&5&5&A6&P6&6&$&&4&%4&h4&4&4&4&5&f5&u5&5&5&5&A6&P6&6&6&6&97&H7&f7&7&7&7&8&8&N8&m8&8&8&8&8&9&9&9&D9&F9&L9&9&9&	:&3:&:&:&?;&;&;&<&^<&m<&<&<&<&=&b=&q=&=&=&=&=&
        !           126: >&9>&h>&>&>&>&>&>&
        !           127: ?&?&?&P?&?&?&@&Q@&@&@&A&,A&A&A&A&B&wB&B&B&B&C&;C&YC&xC&C&C&C&C&C&C&C&D&D&G&&&d6&6&6&97&H7&f7&7&7&7&8&8&N8&m8&8&8&8&8&9&9&9&D9&F9&L9&9&9&	:&&"$&$&l&&&&&&&""$&	:&3:&:&:&?;&;&;&<&^<&m<&<&<&<&=&b=&q=&=&=&=&=&
        !           128: >&9>&h>&>&>&>&$&>&>&>&
        !           129: ?&?&?&P?&?&?&@&Q@&@&@&A&,A&A&A&A&B&wB&B&B&B&C&;C&YC&$&&"$&$&l&&&&&&&""YC&xC&C&C&C&C&C&C&C&D&D&G&G&'H&(H&J&J&.K&/K&L&L&L&M&M&bN&&&"$&$&l&&&&&&&,""$&G&G&'H&(H&J&J&.K&/K&L&L&L&M&M&bN&cN&Q&Q&bR&cR&T&T&	W&
        !           130: W&W&W&W&W&W&&X&9X&fX&X&X&X&Y&MY&~Y&Y&Y&
        !           131: Z&8Z&fZ&Z&Z&Z&
        !           132: [&/[&1[&\[&[&[&[&[&"\&T\&V\&j\&}\&\&\&\&\&\&\&]&']&=]&Q]&p]&]&]&]&]&]&^&&^&
^&#^&1^&>^&L^&]^&m^&y^&^&^&^&^&^&^&^&^&^&
        !           133: _&_&"_&$_&<_&K_&Z_&i_&&&dhM&M&M&M&M&N&,N&JN&^N&N&N&%O&0O&O&O&O&O&Q&Q&Q&Q&Q&Q&Q&Q&"R&*R&XR&_R&iR&pR&R&R&JS&QS&S&S&T&T&T&T&U&U&V&&V&JV&SV&V&V&V&V&=W&DW&W&W&W&W&W&W&W&W&W&W&W&W&W&W&W&&X&/[&1[&[&[&T\&U\&]&]&]&]&]&]&&^&"_&$_&m`&5CJOJQJCJOJQJCJOJQJ5CJCJ	jU&H*&5OJQJTbN&cN&Q&Q&bR&cR&T&T&	W&
        !           134: W&W&W&W&W&W&&X&9X&fX&X&X&X&Y&MY&~Y&Y&Y&
        !           135: Z&8Z&fZ&d&$&&fZ&Z&Z&Z&
        !           136: [&/[&1[&\[&[&[&[&[&"\&T\&V\&j\&}\&\&\&\&\&\&\&]&']&=]&Q]&p]&]&]&d&$&]&]&]&]&^&&^&
^&#^&1^&>^&L^&]^&m^&y^&^&^&^&^&^&^&^&^&^&
        !           137: _&_&d&$&&"$&$&l&&&&&&&,""$&_&"_&$_&<_&K_&Z_&i_&y_&_&_&_&_&_&_&_&_&`&`&)`&C`&Q`&_`&m`&o`&p`&"$&$&l&&&&&&&,""d&$&i_&y_&_&_&_&_&_&_&_&_&`&`&)`&C`&Q`&_`&m`&o`&p`&q`&`&`&`&a&a&/a&Aa&Ra&ca&sa&a&a&a&a&a&a&a&a&b&b&*b&;b&Lb&\b&lb&|b&b&b&b&b&b&b&b&b&c&c&1c&Dc&Xc&kc&~c&c&c&c&c&c&c&d&d&-d&Ad&Ud&id&}d&d&d&d&d&d&d&e&e&e&)e&;e&Pe&be&se&e&e&e&e&e&e&e&f&f&&f&7f&Hf&\f&&&dm`&n`&q`&|`&`&`&`&b&b&e&e&)g&+g&g&g&g&g&g&jh&qh&sh&uh&k&k&k&k&(l&0l&ll&ol&m&m&m&m&^n&en&zn&n&n&n&n&n&&p&p&p&p&p&p&q&q&q&q&q&q&,r&7r&9r&@r&Zr&dr&r&r&Ls&Ss&Xt&_t&uu&|u&@v&Jv&v&v&pw&ww&x&x&x&x&y&y&@y&Hy&y&y&5OJQJ65CJ$CJCJOJQJCJOJQJ5CJCJ5CJOJQJSp`&q`&`&`&`&a&a&/a&Aa&Ra&ca&sa&a&a&a&a&a&a&a&a&b&b&*b&;b&Lb&\b&lb&|b&b&d&$&&b&b&b&b&b&b&b&b&c&c&1c&Dc&Xc&kc&~c&c&c&c&c&c&c&d&d&-d&Ad&Ud&id&}d&d&d&d&$&d&d&d&d&d&e&e&e&)e&;e&Pe&be&se&e&e&e&e&e&e&e&f&f&&f&7f&Hf&\f&pf&f&f&f&d&$&\f&pf&f&f&f&f&f&f&f&g&g&)g&+g&:g&Ig&Yg&ig&xg&g&g&g&g&g&g&g&g&g&sh&uh&h&h&i&di&i&j&Nj&j&j&8k&k&k&k&k&k&ml&ol&l&l&m&m&9n&:n&p&p&q&q&r&r&t&t&v&v&sx&tx&y&z&C{&D{&{&{&{&{&{&{&{&|&|&}&}&p~&~&~&`&q&>&P&b&t&&&&&&&&΁&&&&&݂&&&df&f&f&f&f&g&g&)g&+g&:g&Ig&Yg&ig&xg&g&g&g&g&g&g&g&g&g&&8$&$&l&&&&&&F,"d&$&g&sh&uh&h&h&i&di&i&j&Nj&j&j&8k&k&k&k&k&k&ml&ol&l&l&m&m&9n&&"$&$&l&&&&&&&,""$&&9n&:n&p&p&q&q&r&r&t&t&v&v&sx&tx&y&z&C{&D{&{&{&{&{&{&{&{&|&|&}&}&p~&$&&y&y&y&/z&9z&z&z&z&z&D{&L{&i{&s{&{&{&{&{&{&{&{&{&{&{&&
        !           138: &&z&M&X&&&&&o&v&҆&݆&&&&&&ܝ&&&&K&&V&#&t&2&;&s&}&&&&&&I&J&Z&^&t&&&&&&$&&&&+&1&J&&&I&d&6B*&5B*&B*&B*&CJ CJ CJOJQJCJOJQJ5CJ
jCJU&CJOJQJ5Pp~&~&~&`&q&>&P&b&t&&&&&&&&΁&&&&&݂&&&	&
        !           139: &&"$&$&l&&&&&&&,""$&݂&&&	&
        !           140: &z&&&&&և&&&&"&#&o&p&&&
        !           141: &&&"&,&2&<&J&\&c&n&o&Q&R&&&&Ɗ&>&&&&&&i&&&M&̐&&&;&<&&&&&V&W&x&y&&&֓&C&&Ɣ&&&&&&&И&ј&&&&&&&&&&e&&&&ܝ&ݝ&&&&&&&&&&(&f&&&d
        !           142: &z&&&&&և&&&&"&#&o&p&&&
        !           143: &&&"&,&2&<&J&\&c&n&o&Q&
        !           144: &F!&&&Q&R&&&&Ɗ&>&&&&&&i&&&M&̐&&&;&<&&&&&V&W&x&y&&&&&&֓&C&&Ɣ&&&&&&&И&ј&&&&&&&&&&e&&&&ܝ&ݝ&&&&&&&&&&&&&(&f&&&&K&L&&آ&&&&&ϣ&|&פ&ؤ&&& &;&<&&&f&&&&K&L&&آ&&&&&ϣ&|&פ&ؤ&&& &;&<&I&&&&&̧&@&&&&&&&ĩ&ũ&ܩ&ݩ&Q&R&&&U&V&~&&&ԫ&ի&&&&&&լ&&&V&W&&&έ&&&9&a&d&&&Ю&Ѯ&&%&&&T&&&ۯ&&1&V&z&&°&ð&߰&&&&<&=&o&&&±&ñ&ױ&ر&&&4&5&&&d<&I&&&&&̧&@&&&&&&&ĩ&ũ&ܩ&ݩ&Q&R&&&U&V&~&&&ԫ&ի&
!
        !           145: &F"&&ի&&&&&&լ&&&V&W&&&έ&&&9&a&d&&&Ю&Ѯ&&%&&&T&&&ۯ&&&ۯ&&1&V&z&&°&ð&߰&&&&<&=&o&&&±&ñ&ױ&ر&&&4&5&l&&&&&&5&l&&&&&&&L&M&_&`&&&³&&&&&G&H&&ڴ&&D&o&&&%&&&n&o&&&&&I&J&x&y&&&&&&"&#&8&E&U&Z&v&&ĸ&&&.&3&C&{&&߹&&&!&.&e&&&Ϻ&&3&<&E&c&&&&.&]&&&	&#&$&1&&ǽ&Ƚ&&H&}&&&Ծ&&&/&l&&&&&d&&&L&M&_&`&&&³&&&&&G&H&&ڴ&&D&o&&&%&&&n&o&&&&

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