
/* File: global.h
*  This/ file is included in all modules of Manhattan.
*
*  There is really nothing you should change here!!!
*
*  See custom.h for important server settings.
*
*  The Manhattan Virtual Classroom is 
*  copyright (c) 1997-2006 Steven Narmontas
*
*/

#ifndef GLOBAL_H
#define GLOBAL_H

#include <time.h>
#include "custom.h"





/*** SYSTEM identification *****/
#define VERSION "Version 3.2"


#define MAX_COOKIE 512    /* max length of a cookie set by Manhattan */
#define USE_COOKIE "0"    /* string passed as an id=? value to let the programs know to use cookies for the key string */
#define COOKIE_DONE  "done"   /* cookie id is set to this string on logout */

/***   PATH information *******/

#define COURSE_PATH  "../courses/"        /* where the course directories are stored */
#define CONFIG_FNAME "config.dat"         /* name of the (binary) configuration file */
#define PASSWORD_FNAME "passwd"           /* name of the password file in each classroom */
#define TOPIC_SORT_FNAME "sort.dat"       /* name of the file used to control sort order of topics */

#define XML_ROSTER_PATH "../tmp/CGI_DATA_%s_roster.xml"
#define TMP_PATH "../tmp/"      	  /* temp file directory */
#define CLIPBOARD_PATH "../clipboards/"   /* location of teachers' clipboard directories */
#define TEMPLATE_PATH "../templates/"     /* location of teachers' template directories */

#define LOG_PATH "../users/logs"     /* where login logs are stored */
#define ROSTER_LOG_PATH "../auto_update/logs" /* where WNEC roster logs are stored */
#define AUTO_UPDATE_REQUEST_PATH "../auto_update/request"      	  /* request file directory */
#define AUTO_UPDATE_ROSTER_PATH "../auto_update/rosters"      	  /* request file directory */
#define AUTO_UPDATE_UPDATED_PATH "../auto_update/updated_courses"      	  /* request file directory */
#define AUTO_UPDATE_ADDED_PATH "../auto_update/added_faculty"      	  /* request file directory */
#define LOG_FNAME "log.txt"
#define LAST_LOGIN_FNAME "last_login"


#define USER_INDEX_FNAME    "index.txt"
#define USER_INDEX_LOCKFILE "index.lck"
#define NEW_COURSE_LOCKFILE "new_course.lck"

#define UNZIP_PATH   "unzip"              /* location of the unzip program */
#define ZIP_PATH     "zip"

#define CHAT_DIRECTORY         "../chat"               		/* relative to sbin -where melange, melange.conf, melange.pid, melange.log are found */
#define CHAT_PROGRAM         "melange"                 		/* the melange chat executable, stored in CHAT_DIRECTORY  */
#define CHAT_CONF_PATH   "../chat/melange.conf"   	        /* this is relative to the SBIN directory */
#define CHAT_SYSTEM_LOG_PATH "../chat/melange.log"              /* this is relative to the SBIN directory */
#define CHAT_PID_PATH        "../chat/melange.pid"             	/* a text file holding the PID of the melange process, relative to SBIN directory */
#define CHAT_ACTIVE_FILE   "../chat/melange.active"    		/* if this file exists, someone is in chat */

#define CHAT_ACCESS_LOG    "chat_access.log"            	/* records times each user enters chat */
#define CHAT_MSG_LOG	   "chat_messages.dat"          	/* transcripts for a particular class' chat sessions are stored here */


#define BIO_DIR     "bio"
#define BIO_ORIG_PIC_FNAME   "photo.jpg"   /* name of temporary uploaded picture file */
#define BIO_PIC_FNAME "thumb.photo.jpg"    /* name of photo file for a person's bio */
#define NO_PHOTO_FNAME "no_photo.jpg"    /* name of jpg file to be displayed when user's picture not available */
#define BIO_FNAME   "bio.txt"


#define IMAGES_DIR      "../images"
#define THEME_DIR_PREFIX "theme_"
#define LANG_DIR "lang"                   /* where the language files are stored within a theme directory */
#define LANG_EXTENSION ".lang"            /* all lang files should end in this */
#define CLEARSILVER_EXTENSION ".cs"       /* all clearsilver template files should end in this */

/* names of directories used in system*/
#define INBOXES_DIR "inboxes"  /* a directory for storing all of the inboxes for a course */
#define PEOPLE_DIR  "people"  /* a directory for storing the users within a course */


/* data for each of the modules is stored in directories with the following names */

#define ASSIGNMENTS_DIR "assign"
#define ANONYMOUS_DIR   "anon"
#define DISCUSSION_DIR  "discuss"
#define TEAM_DIR 	"team"
#define INET_DIR 	"inet"
#define LOUNGE_DIR 	"lounge"
#define MAIL_DIR 	"mail"
#define HANDOUTS_DIR 	"handouts"
#define LECTURES_DIR 	"lectures"
#define GRADES_DIR 	"grades"
#define TEAM_TEACH_DIR 	"team_teach"
#define SELFTEST_DIR 	"selftest"
#define CHAT_DIR 	"chat"
#define SURVEYS_DIR     "surveys"
#define PODCASTS_DIR     "podcasts"

/* The directory USERS_DIR holds all of the user account information
 * for a Manhattan server.  Within USERS_DIR, you'll find subdirectories
 * corresponding to each user on the server.  The files COURSE_LIST_FNAME,
 * SESSION_LIST_FNAME, and PASSWD_FNAME contain information for each user.
 */

#define USERS_DIR  "users"                 	/* directory name of central store of username info */
#define ADMIN_DIR "admin"                       /* this directory under USERS_DIR holds administrative accounts */
#define LOGS_DIR "logs"

#define KEY_DIR    "keys"                  	/* name of directory within USERS_DIR where keys are stored */
#define ID_FNAME   "id"                   	/* file contains name and ID info for a user */
#define COURSE_LIST_FNAME "course_list"   	/* text file listing courses a user is enrolled in */
#define SEMESTER_SORT_FNAME "semester_sort"  	/* text file that controls the sort order of the semesters on MyManhattan page */
#define KEY_FILE_EXTENSION ".key"         	/* files ending with this store user keys for each course */
#define PASSWD_FNAME "passwd"             	/* file listing a user's password */


/*** when a website or a hot potatoes EXAM is posted, 
*** the files are stored in a dynamically created directory
**  the next two are used to determine the first three letters
*** of that directory name
***/

#define NORMAL_WEBSITE_DIR_PREFIX "dir"    
#define HOTPOT_EXAM_DIR_PREFIX    "hot"

#define HOTPOT_EXAM_SCORE_EXTENSION ".score"




/***** FILE names **********/


#define MAINTENANCE_LOCK "SYSTEM_LOCKED"   		/* presence of this file in tmp directory prevents all logins */

#define EXIT_FILE "logout.html"   			/* contents of this file is appended to logout screen for standalone classes */


#define INBOX_FNAME "inbox.dat"    			/* where inbox info is stored */

#define USER_INBOX_FNAME "user_inbox.dat"               /* new name given to inbox file that records a particular's users
                                                        ** setting regarding a message.  See USER_INBOX_RECORD below
                                                        */
#define OUTBOX_FNAME "outbox.dat"  			/* where outbox info is stored */

#define NEWS_FILTER_FNAME "filter.dat"  		/* the filter for a newsgroup, or Post Office Inbox */
#define OUTBOX_FILTER_FNAME  "outbox_filter.dat"        /* the filter for Post Office Outbox */


#define OUTBOX_FILTER_FNAME  "outbox_filter.dat"

#define GRADES_NEW_FNAME "grades.new"  			/* flag file indicates new grades are available */



#define GRADES_HTML_FNAME "grades.html"      		/* file placed in ea. grades dir */
#define GRADES_INF_FNAME  "grades.inf"   		/* found only in teacher's dir, is a file of GRADES_INFO_STRUCT
                                         		**  records.  (see below)
                                         		*/
                              

#define ZIP_TMP_FNAME "temp.zip"          /* an uploaded zip file is temporarily stored in this file */
#define ZIP_TMP_DIRNAME "temp_zip_dir"    /* ... and extracted to this directory */
#define ZIP_START_FNAME "index.html"      /* ... the zip file might contain a file with this name */

#define ZIP_LECTERN_START_FNAME "__LECTERN__"   /* The zip file might have contained a Lectern II RealAudio Lecture
                                                ** if so, this "filename" will be stored in the message's info file
                                                ** to flag this fact, so the attached website can be handled specially
                                                */


#define ZIPPED_WEBSITE_FNAME "website.zip" 	/* a zipped website is sent to user with this name */

#define CLIPBOARD_INF_FNAME "clipboard.inf"  	/* see CLIPBOARD_INFO struct below */

#define GATHER_LAST_FNAME "last_gather.dat"
#define GATHER_LAST_INBOX_FNAME "last_inbox_gather.dat"
#define GATHER_LAST_OUTBOX_FNAME "last_outbox_gather.dat"

#define HOTPOT_FNAME "hotpot.dat"  /* stores results of Hot Potato quizzes
                                   ** used in Self-tests modules
                                   */
#define HOTPOT_TMP_FNAME "hotpot.tmp" /* temporary storage used for converting
                                      ** a Hot Potatoes quiz submitted as
                                      ** an attached web site 
                                      */                                   
#define HOTPOT_TMP_DIRNAME "hotpot.dir"  /* directory in user's selftests 
                                         ** directory where modified 
                                         ** hot potato website is copied
                                         */

#define ACCESS_LOG_FNAME "access.log"
#define PODCAST_DOWNLOAD_LOG_FNAME "podcast_download_log.dat"

#define DROP_LIST_FNAME "drop_list"
#define ADD_LIST_FNAME "add_list"


#define USAGE_REPORT_FNAME "usage_report.hdf"

#define MAX_LOCK_ATTEMPTS 3         /* number of times to attempt to lock a file */

                                       
/* max lengths of some strings, these are reasonable guesses with
*  lots of extra space thrown in */

#define MAX_PATH     256     	/* max len of a (reasonable) path  changed from 128 on 8/14/02 */
#define MAX_FILENAME 64      	/* max len of a (reasonable) filename */
#define MAX_COURSE_ID      20   /* max len of a directory name holding a course */
#define MAX_COURSE_NO   20    	/* eg CSS 100-01 */
#define MAX_COURSE_TITLE 40    	/* eg. College Success Skills */
#define MAX_SEMESTER 25       	/* eg "Fall, 1996"*/
#define MAX_INSTRUCTOR 25     	/* eg. "Dr. Paul Salinger" */
#define MAX_USERNAME   20   	/* eg: snarmontas */
#define MAX_NAME       35   	/* eg: Steven Narmontas */

#define MAX_COURSE_SUBDIR  (MAX_USERNAME + 1)   /* max len of a subdirectory name within the courses directory 
                                                 ** must be same or longer than MAX_USERNAME 
                                                 */


#define MAX_PASSWORD   20	    /* this is the max length of the plain text password */
#define MAX_ENCRYPTED_PASSWORD 40   /* need at least 34 characters to support MD5 */

#define MAX_ID         15   	/* student's id in passwd file */
#define ILLEGAL_ID_CHARS  ": /\\;,?" /* these chars cannot be in a valid id number */

#define MAX_KEY     15   	/* 8 random chars, plus 6 added by mktemp() */
#define MAX_SUBJECT 45       	/*  ... of an email message */
#define MAX_URL     256      	/* eg. http://www.wnec.edu */
#define MAX_MIME_TYPE 150       /* eg. application/mspowerpoint */
#define MAX_FROM    128         /* 'from=' is  a common parameter passed to the CGI, an example is:
				** &from=news_expand_topic|crs^f98engl13207]id^xxqrckeka10737]grp^0]topic^1 
				*/

#define MAX_HOTPOT_TIME 80      /* Hot Potatoes quiz's use a Javascript time
                                ** string like "Thursday, August 17, 2002 08:09:21"
                                */
#define MAX_HOTPOT_EXERCISE  256  /* Max len of a Hot Potato's quiz title 
                                  ** apparently the aps have no limit
                                  */
                                  
#define MAX_HOTPOT_SCORE 10   /* Hot Potatoes sends a score like "100%" */                                  
/*** some things you might want to adjust ***/

#define MAX_ATTACHMENTS 20    /* how many file attachments per msg */
                            
#define EDITOR_WIDTH 70      /* how many cols to allow for editing? */



/* 
** these assigned integers for the different modules are used throughout
**/

#define CLASS_DISCUSSION 0
#define STUDENT_LOUNGE   1
#define ANONYMOUS_DISCUSSION 2
#define TEAM_DISCUSSION 3
#define HANDOUTS_NOTICES 4
#define INTERNET_RESOURCES 5
#define ASSIGNMENTS 6
#define TEAM_TEACH 7
#define CHATTER 8
#define MAIL 9
#define GRADES 10
#define SELFTEST 11
#define LECTURES 12

#define CLIPBOARD 13

#define PEOPLE 14
#define SURVEYS 15
#define PODCASTS 16






#define ACCESS_ALL          0    /* Full access for teachers and students */
#define ACCESS_NONE         1    /* No one can see the course */
#define ACCESS_TEACHER_READ 2    /* Only teachers see course, but as read-only */
#define ACCESS_ALL_READ     3    /* All can view course, but as read-only */
#define ACCESS_TEACHER      4    /* Teachers have full access, students have no access */
#define ACCESS_STUDENT_READ 5    /* Teachers have full access, students have read-only access */
#define ACCESS_CAPTURE      6    /* Course is ready to be captured by offline browsing software */

/* each class's configuration file consists of one of the following structures */
struct configuration
   {
     char course_no[MAX_COURSE_NO + 1];
     char title[MAX_COURSE_TITLE + 1];
     char semester [MAX_SEMESTER + 1];
     char instructor [MAX_INSTRUCTOR + 1];
     char course_path[MAX_PATH + 1];
     
     int login_expire;       /* how many seconds is login screen valid
                                this is no longer used
                             */
     int key_expire;         /* how many secs is a key good for */
     int mail_attachments;   /* number of file attachments to allow */

     int assignments;      /* include these items on menu ? */
     int syllabus;         /* this is an antiquated name for handouts/notices */
     int discussion;
     int postoffice;
     int internet;
     int lounge;
     int chat;
     int anonymous;
     int team;
     int team_teach;
     int grades;
     int selftest;
     int lectures;
     int people;
     int surveys;

     
     int misc;          /* stores miscellaneous settings - see bit assignments below */
     int podcasts;     /* podcast module */
     
     /* save space for as yet un-thunkup uses  */
     
     int future6;
     int theme;
     
     
     int access;        /* who can read/write/see this course? 
                        ** see the #define's for ACCESS_ immediately above */
                        

     int standalone;    /* does this course use central login? */
     int template;     /* is this a course template? */

   };
   
typedef struct configuration CONFIG_STRUCT;


/** rightmost bit of conf.misc flags whether or not spell check is enabled */
#define ALLOW_SPELL_CHECK(value) (value & 0x01)
#define SET_SPELL_CHECK(value)   (value | 0x01) /* turn on spell check */  
#define UNSET_SPELL_CHECK(value)  (value & 0xFFFE) /* turn off spell check */

/*** next bit of conf.misc flags whether or not messages should default
**** to fixed font
***/
#define USE_FIXED_FONT(value) (value & 0x02)   /* should fixed font be used? */
#define SET_FIXED_FONT(value) (value | 0x02)   /* turn on fixed font         */
#define UNSET_FIXED_FONT(value) (value & 0xFFFD)  /* turn off fixed font */

/*** bit 3 of conf.misc flags whether or not emoticons (smiley faces) should be
**** made available to users when they compose messages
***/
#define EMOTICONS_DISABLED(value) (value & 0x04) 
#define DISABLE_EMOTICONS(value)  (value | 0x04)
#define ENABLE_EMOTICONS(value)   (value & 0xFFFB)
     

/*** bits 4 and 5 of conf.misc controls the width of the textareas
**** used to compose messages.
***/
#define EDITOR_WIDTH_PREFERENCE(value) ((((value) & 0x18)) >> 3) /* two bits control editor width */
#define SET_EDITOR_WIDTH_PREFERENCE(conf_misc_value, new_value)  ((conf_misc_value) | ((new_value) << 3)) 


/*** bit 6 of conf.misc controls whether or not the teacher has locked students out of the classroom
***/
#define CLASSROOM_LOCKED(value) ((value) & 0x20)  
#define LOCK_CLASSROOM(value)   ((value) | 0x20)
#define UNLOCK_CLASSROOM(value) ((value) & 0xFFDF)






/* In addition to faculty and students, the plan was to allow for people
** AUDITing the course and for ADMINistrators.  These plans have not yet
** materialized, but AUDIT and ADMIN still are listed in the following.
** imagine that.
**/
typedef enum group_type{FACULTY,STUDENT,AUDIT,ADMIN, UNKNOWN_GROUP}GROUP_TYPE; /* actually, only FACULTY, STUDENT and ADMIN are used */


/* next struct tells who is using the system.  It is read from the key file in the 
** 'keys' directory.  Basically the key file can be thought of as a server side 
** cookie.
*/

#define MAX_IP  25              /* len of xxx.xxx.xxx.xxx + 10 */
typedef struct session_struct
 {
   char username[MAX_USERNAME + 1];
   char realname[MAX_NAME + 1];
   char id[MAX_ID + 1];
   char alias[MAX_NAME + 1];
   char team;				/* what team is this person on A-Z */
   GROUP_TYPE group;
   time_t expires;
   char ip_address[MAX_IP + 1];        /* what IP address did they login from? from REMOTE_ADDR environment variable */
  }SESSION;

typedef struct user_data
{
  char username[MAX_USERNAME + 1];
  char realname[MAX_NAME + 1];
  char lastname[MAX_NAME + 1];
  char password[MAX_PASSWORD + 1];
  char id[MAX_ID + 1];
  char team;                /* news_members.c needs this */
  GROUP_TYPE group;
  char alias[MAX_NAME + 1];
}
USER_DATA;



typedef struct p_node
{
  USER_DATA data;
  struct p_node *next;
}P_NODE;




/**  For each message sent, the following files are created in the sender's
***  directory:
***  
***         <some unique_fname>.inf      the information file in the 'inf' dir
***         <some unique_fname>.msg      the actual message in the 'msg' dir
***          plus, zero or more of
***          <some unique_fname>.fil     attached files in the 'attach' dir
***

*** the *.inf file holds it all together. The file consists of the following
*** series of records (defined below):
***
***  one INFO record followed by zero or more nonblank ATTACHMENT
***  records, followed by one or more person records 
**/



/* how did user come to receive a message */
typedef enum receive_type{TO,CC,BCC} RECEIVE_TYPE;



/** DELETED was added for version 2.4 and is used to flag that
*** the message was completely deleted by the user
**/
typedef enum send_type {NEWMSG, FORWARD, REPLY, GROUP_REPLY, DELETED} SEND_TYPE;



/** Next typedef was introduced with version 2.4
**** The INFO structure (see next) always had an
**** element of type SEND_TYPE.  This element was
**** always set to  0 and was never really
**** used by any program.
****
**** The Post Office module was refurbished with version
**** 2.4, and it became necessary to detect which Post Office
**** messages were posted by the new system versus earlier systems
**** The trick is to introduce the next enumerated type into the
**** INFO struct, replacing the SEND_TYPE element.  The new 
**** Post Office sets the value of all messages to VERSION24, and
**** we can detect earlier versions since thay have values of 
**** PRE24 or ALSO_PRE24
***/

typedef enum post_office_version {PRE24, VERSION24} POST_OFFICE_VERSION;


/** a *.inf file consists of one INFO struct .... **/
typedef struct info_struct
    {
   
     char msg_fname[MAX_FILENAME + 1];  /* the name of the msg file */
     char subject[MAX_SUBJECT + 1];
     POST_OFFICE_VERSION version;           
     time_t time_sent;
     int no_attachments;                /* how many files are attached */
} INFO;


/** followed by zero or more ATTACHMENT structs ... **/
typedef struct attachment
  {
    char unique_fname[MAX_FILENAME + 1];    /* as it appears on this server*/
    char orig_fname[MAX_FILENAME + 1];      /* its original name */
   } ATTACHMENT;

/*** ... followed by one or more PERSON records. **/

 typedef struct person
  {
    char username[MAX_USERNAME + 1];
    char realname[MAX_NAME + 1];
    RECEIVE_TYPE how_received;
    time_t time_read;
    time_t time_deleted;
  } PERSON;

/* the following facilitate the creation of linked lists when dealing with
** info files.  They are sort of duplicated below oh well ...
**/

typedef struct person_node
                          {
                            PERSON data;
                            struct person_node *next;
                          } PERSON_NODE;
                            
typedef struct attachment_node { 
                                  ATTACHMENT data;
                                  struct attachment_node *next;
                                } ATTACHMENT_NODE;


/*** a *.NEW file is placed in the directory of each recipient when a msg is sent
**** the file simply consists of a single copy of the NEWFILE_RECORD
**** defined below.  
****/
typedef struct newfile_struct{
     char sender[MAX_USERNAME + 1];     	/* who sent this file? (username) */
     char sender_realname[MAX_NAME + 1];   	/* sender's realname */
     SEND_TYPE how_sent;		   
     RECEIVE_TYPE how_received;            	/* TO,CC, etc */ 
     char subject[MAX_SUBJECT + 1];    		/* msg subject */
     time_t time_sent;				/* time msg sent */
     int attachments;                		/* are there files attached?*/
     char info_fname[MAX_FILENAME + 1];   	/* where is the info file */

     }NEWFILE_RECORD;


/*** the inbox is a file of records of the following structure
**** the intent is to provide enough information to quickly post the 
***  INBOX on-screen, minimizing unnecessary disk access ...
*** the *.new files (described above) are read and appended to the end
*** of the inbox file, then deleted.
*/


typedef struct inbox_struct{
   NEWFILE_RECORD  newfile_info;        /* read from the *.new file */
   time_t time_read;     /* time this user first read file */
   time_t is_sleepy;     /* did user mark this message as 'sleepy'? */
 } INBOX_RECORD;


/*** the outbox is a file of records listing the msgs sent by a particular
**** user.  it's a file of the following records
****/
#define MAX_TO 3  /* store up to this many real-names in the outbox */
typedef struct outbox_struct{

  char info_fname[MAX_FILENAME + 1];       /* the name of the info file */

  /* the info_fname is all we really need, but the following will reduce
  ** disk activity, since it allows us to easily present the outbox to the user
  */
  char subject[MAX_SUBJECT + 1];
  char to[(MAX_NAME * MAX_TO)+ 25];          /* short list of who msg was sent to */
  SEND_TYPE how_sent;                     
  time_t time_sent;
  time_t is_sleepy;            		    /* did user mark this message as 'sleepy'? */
  int attachments;                          /* are files attached? */
  int unread;                               /* has one or more recipients not read the msg?*/
} OUTBOX_RECORD;


/*** *.RED files are placed in the sender's directory the first time a 
**** recepient reads a msg they have sent.  RED files consists of a single record, as below
**** Like *.new files, *.red files are read, and then the information is used to update the 
**** outbox before they *.red file is deleted.
***/

typedef struct read_struct{
    char info_fname[MAX_FILENAME + 1];   /* which info file to update */
    char reader_username[MAX_USERNAME + 1]; /* who read the message */
    time_t  time_read;                      /* when was it read */
   } READ_STRUCT;

/*** *.DEL files are placed in the sender's directory when a 
**** recipient moves a Post Office message to the attic.
****  DEL files consists of a single record, as below
***/

typedef struct del_struct{
    char info_fname[MAX_FILENAME + 1];   /* which info file to update */
    char deleter_username[MAX_USERNAME + 1]; /* who deleted the message */
    time_t  time_deleted;                      /* when was it deleted */
   } DEL_STRUCT;



/*** linked lists of msg receivers are used when sending mail
****/

typedef struct receiver_node{
          char username[MAX_USERNAME + 1];
          char realname [MAX_NAME + 1];
          struct receiver_node *next;
          } RECEIVER_NODE;


/*** linked lists of filenames are used when dealing with attached files 
***/

typedef struct file_node{
           char unique_fname[MAX_PATH + 1];
           char orig_fname[MAX_PATH + 1];
           struct file_node *next;
             } FILE_NODE;


                                
                                
/******** NEWS  **** NEWS  *******
 * This section defines data structures for the inbox.dat files
 * used to store message data for most of the modules EXCEPT the
 * POST OFFICE.  These modules include Class Discussion, Anonymous
 * Discussion, Team & Team_Teacher Discussion, Handouts/Notices,
 * Lectures, Self-tests, Assignments.  For historical reasons, these
 * groups are referred to as "news" groups
 */



typedef struct news_info_struct
    {
   
     char msg_fname[MAX_FILENAME + 1];   /* the name of the msg file */
     
     char sender[MAX_USERNAME + 1];      /* username of the sender */
     char sender_realname[MAX_NAME + 1];  /*full name of the sender */
     char receiver_username[MAX_USERNAME + 1]; /*need this for assignments module */
     char subject[MAX_SUBJECT + 1];      /* the subject of the msg */
     time_t time_sent;                   /* when was the message sent? */
     signed char attachments;            /* how many files are attached */
     
     char sender_team;                   /* what team is the sender on? */
     
     int topic_id;                       /* What topic is this msg associated with? 
					 * (A topic is identified by its msg_id) 
					 */
     int msg_id;                         /* the unique msg id */
     int reply_to;                       /* what msg_id is this msg a reply to */
   } NEWS_INFO;



 typedef struct news_person
  {
    char username[MAX_USERNAME + 1];
    char realname[MAX_NAME + 1];
    time_t time_read;
    unsigned char user_unlocked;   /* did this user 'unlock' the attachments to read them? */
  } NEWS_PERSON;



/* the NEWS_FILTER is stored in an individual's directory and
 * specifies which messages should be displayed and how
 * they are to be displayed
 */
 
typedef struct news_filter_struct{
            int oldest_first;	          /* show oldest msgs first? */
	    int show_user_hidden;	  /* show msgs marked by a user as 'hidden'? */
       	    int show_teacher_hidden;      /* show msgs marked by a teacher as 'hidden'? */
            } NEWS_FILTER;

            
typedef enum {OLDEST_FIRST, NEWEST_FIRST, SHOW_USER_HIDDEN, HIDE_USER_HIDDEN, 
                             SHOW_TEACHER_HIDDEN, HIDE_TEACHER_HIDDEN} NEWS_FILTER_CMD;

            
            
/* Each message has a status associated with it
 * This enumerated type is used in the CENTRAL_INBOX_RECORD
 * (see next)
 */

              
typedef unsigned char MSG_STATUS;              
#define NORMAL           00    /* students have full access */
#define DELETED          01    /* msg has been deleted */
#define TEACHER_HIDDEN   02    /* teacher has manually hidden the message */
#define TIMED_RELEASE    03    /* msg becomes hidden after optional unrelease time */
#define READ_ONLY        04    /* msg is viewable to students, but they can't add new msgs */
#define PROTECTED       010    /* students must 'unlock' the attachments to the message */
           
           
#define BASIC_STATUS(status) (status & 007)
#define IS_PROTECTED(status) (status & 010)  

#define CLEAR_BASIC_STATUS(status)  status &= PROTECTED         
 
#define SET_BASIC_STATUS(status, value)  {CLEAR_BASIC_STATUS(status) ; status |= value; }
#define SET_PROTECTED(status)  (status |= PROTECTED)
#define CLEAR_PROTECTED(status) (status &= 07)

/* The inbox.dat files are files of the following basic data structure used
 * to define a message.  The inbox.dat files are stored in a subdirectory
 * for the particular module within the central INBOXES_DIR directory.
 */

typedef struct central_inbox_struct{

     NEWS_INFO  info;
     
     char info_fname[MAX_FILENAME + 1];        /* The name of the '*.inf' file, stored in the sender's 
						* directory, that provides complete information about
						* the message
						* */
     

     time_t release_time;              /* The teacher can specify a time when a message,
					* can be viewed by the students in the class
					*/
     time_t unrelease_time;            /* teacher can also specify when the message will become hidden from students 
                                       ** a 0 here means no unrelease time
                                       */
     
     MSG_STATUS status;                /* see typedef MSG_STATUS above */
     
     
     }CENTRAL_INBOX_RECORD;




/* Each user also maintains an inbox.dat file for each newsgroup.
 * This file, stored in each user's directory, records whether
 * or not the message has been read, hidden, etc.
 */


typedef struct user_inbox_struct{
	
   int msg_id;	                   /* which message does this record refer to? */
   time_t time_read;      	   /* time this user first read this message */
   unsigned char user_unlocked;     /* did the user 'unlock' the attachments */
   unsigned char  user_hidden;     /* did this user choose to hide this msg? */
   unsigned char flagged;             /* did user flag this message */
   unsigned char future1;
   unsigned char future2;
 } USER_INBOX_RECORD;



/* a data structure to build a simple, flat, linked
 * list from the individual user's inbox.dat file
 */
typedef struct user_inbox_node {
	USER_INBOX_RECORD data;
	struct user_inbox_node *next;
        } USER_INBOX_NODE;



typedef struct msg_tree_node {
	CENTRAL_INBOX_RECORD data;
        USER_INBOX_RECORD user_data;
	
	long offset;             /* file offset into central inbox.dat file
				  * where in the file was this record read
				  * from?
				  */ 
	struct msg_tree_node *next;      /* ptr to msg node with same reply_to value
	 			          * as this message
				          */
	struct msg_tree_node *reply;     /* ptr to msg node with reply_to value == 
				          * this msg_id
					  */
	struct msg_tree_node *prev;      /* ptr to the msg_node that points to this msg */
        } MSG_TREE_NODE;



/* next used to build a linked list, reading ints from a sort.dat file,
** for the purpose of sorting the topics in a discussion group
*/
typedef struct topic_sort_node {
       int msg_id;
       struct topic_sort_node *next;
       } TOPIC_SORT_NODE;


/**** CLIPBOARD ***** CLIPBOARD ****
***************  CLIPBOARD *********
*/   

/** a clipboard.inf file is stored in the (faculty) user's clipboard
** directory.  The file consists of one CLIPBOARD_INFO record, followed
** by zero or more ATTACHMENT records
**/
typedef struct clipboard_info 
 {
   int group;    /* one of CLASS_DISCUSSION, STUDENT_LOUNGE, etc. as #defined in this file */
   char msg_fname[MAX_FILENAME + 1]; /* the name of the message file */
   char subject[MAX_SUBJECT + 1];
   char sender_username[MAX_USERNAME + 1];
   char sender_realname[MAX_NAME + 1];
   time_t time_sent;
   int website_attached;
   int attachments;
 } CLIPBOARD_INFO;    

   
/****** CHAT ***** CHAT ***** CHAT ******
****************************************/

#define MAX_TIME 20             /* max len of, say '9:00:00 am'        */


/**** GRADES *** GRADES **** GRADES *****
***************************************/

#define MAX_GRADES_LINELEN 1000        /* used in grades modules to define max len of some strings */






/* a grades *.red file, written by students in the teacher's account after grades are red,
** consists of one of the following records.   The grades info.dat file stored in the teacher's account
** is a file of these records.
**/
typedef struct grades_info_struct {
     	char username[MAX_USERNAME + 1];
     	char realname[MAX_NAME + 1];
     	time_t time_read;
     	} GRADES_INFO_STRUCT;
     	
     	
     	
/**** STATS 
****/

typedef struct course_dates {
               time_t start_date;
               time_t end_date;
               } COURSE_DATES;
               

/*** HOT POTATOES 
**** (Self-tests module)
***/

typedef struct hotpotato_info_struct {
        char sender[MAX_USERNAME + 1];   /* should always be the teacher */
        char info_fname[MAX_FILENAME + 1];
        char score[MAX_HOTPOT_SCORE + 1];
        char start_time[MAX_HOTPOT_TIME + 1];
        char end_time[MAX_HOTPOT_TIME + 1];
        char exercise[MAX_HOTPOT_EXERCISE + 1];
        char orig_fname[MAX_FILENAME + 1];
        char system_fname[MAX_FILENAME + 1];  /* the name of the file on the server */
        time_t time_submitted;          
        time_t elapsed_time;        
        int hidden;
        
        char future_string1[MAX_FILENAME + 1];
        char future_string2[MAX_FILENAME + 1];
        int future_int1;
        int future_int2;
    } HOTPOTATO_INFO_STRUCT;
                    	                         
typedef struct grades_info_node
{
  GRADES_INFO_STRUCT info;
  struct grades_info_node *next;
}
GRADES_INFO_NODE; 



/*** Administrator's configuration data structures ****/

#define MAX_ADMIN_PAGE_TITLE 60

typedef struct admin_conf_struct
      {
        char page_title[MAX_ADMIN_PAGE_TITLE + 1];  /* title user gave to personalize this page */
        
        int is_super_user;        /* is this the super_user?                  */
        
        int create_new_course;    /* can this person create new courses?      */
        int delete_courses;       /*  ""             delete courses?          */
        int config_courses;       /*     ""          configure courses?       */
        int admin_surveys;        /*    ""           work with surveys?       */
        int add_admin;            /*    ""           add new administrators?  */
        int del_admin;            /*    ""           delete other admins?     */
        int grant_admin;          /*    ""           change admin privileges? */
        int search_profiles;      /*    ""           work with user accounts? */
        int disk_space;           /*    ""           see disk space status?   */
        int whos_on;              /*    ""           see who's on Manhattan?  */
        int statistics;           /*    ""           view browser stats?      */
        int chat_server;          /*    ""           manage the chat server?  */
        int lock_server;          /*    ""           lock the server for maintenance? */
        int clean_up;             /*    ""           delete temporary files?  */
        
        int change_course_access;   /*  ""           change course access? */ 
        int archive_courses;        /*  ""           archive courses? */
        int purge_postoffice_message;
        int course_disk_usage;
        int future5;
        int future6;
        int future7;
        int future8;
        int future9;
        int future10;
        
 } ADMIN_CONFIG_STRUCT;        







#endif /* #ifndef GLOBAL_H */
                    	                         
