#include <stdio.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>



#include "global.h"
#include "custom.h"		
#include "survey.h"

#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_msg_line.h"
#include "manhat-lib/shared_potato_util.h"
#include "manhat-lib/shared_lock.h"
#include "manhat-lib/shared_translate_url.h"
#include "manhat-lib/shared_strtrm.h"
#include "manhat-lib/shared_access.h"
#include "manhat-lib/shared_bio.h"
#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_news_util.h"
#include "manhat-lib/shared_survey_take_verify.h"

#define NOTEAM '!'


ATTACHMENT_NODE *attachment_head = 0;	/* linked list of file info */


static void
read_parameters (char *course, char *key, long *offset,
		 char *topic_prog, int *grp, int *del_link, int *printer_friendly, int *fixed_font)
{

  char tmp[MAX_FILENAME + 1];

  cs_get_required_parameter ("crs", course, MAX_FILENAME);	/* shared_cs_util.c */
  cs_get_required_parameter ("id", key, MAX_KEY);		/* shared_cs_util.c */

  cs_get_required_parameter ("grp", tmp, MAX_FILENAME);		/* shared_cs_util.c */
  *grp = atoi (tmp);

  cs_get_required_parameter ("loc", tmp, MAX_FILENAME);         /* shared_cs_util.c */
  *offset = atol (tmp);

  snprintf (topic_prog, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d",
	    "news_topic", course, key, *grp);


  /* just check if the "del_link" parameter is there */
  cs_get_optional_parameter ("del_link", tmp, 5);              /* shared_cs_util.c */
  *del_link = *tmp? 1: 0;


  /* provide printer-friendly version? */
  cs_get_optional_parameter ("print", tmp, 5);              /* shared_cs_util.c */
  *printer_friendly = *tmp? 1: 0;


  /* provide preformatted text (instead of proportional) ? */
  cs_get_optional_parameter ("fixed", tmp, 5);              /* shared_cs_util.c */
  *fixed_font = *tmp? (atoi(tmp)? 1: 0) : 0;

}





/* is this the teacher working with the team/teacher module? */
static void
check_is_fac_team_teach (int grp, int *is_fac_teamteach, char *team,
                         char *topic_prog, SESSION *user)
{
  char tmp[5];
  char teamstring[20];

  if ((user->group == FACULTY) && (grp == TEAM_TEACH))
    {
      *is_fac_teamteach = 1;
      cs_get_required_parameter ("team", tmp, 4);	/* shared_cs_util.c */
      *team = *tmp;
      snprintf (teamstring, 20, "&amp;team=%c", *team);
      strcat (topic_prog, teamstring);
    }
  else
    {
      *is_fac_teamteach = 0;
      *team = NOTEAM;
    }
}


static
MSG_TREE_NODE *find_last_node(MSG_TREE_NODE *root)
{
 MSG_TREE_NODE *ptr;

 ptr = root;
 
 for(;;)
 {
  for(;ptr->next;ptr=ptr->next);
  if(!ptr->reply)
      return ptr;
  ptr=ptr->reply;
 }
}   
 


static 
void get_next_msg_offset(MSG_TREE_NODE *msg_ptr, MSG_TREE_NODE *topic_ptr, int uses_topic, long *offset)
{
MSG_TREE_NODE *ptr,*last;
int done;

 if(!uses_topic)
  *offset =  topic_ptr->next ? topic_ptr->next->offset : -1;
 else
  if(msg_ptr->data.info.reply_to == -1)  /* msg is the topic */
    *offset = msg_ptr->reply? msg_ptr->reply->offset: - 1;
 else
  if(msg_ptr->reply)
        *offset = msg_ptr->reply->offset;
 else
   if(msg_ptr->next)
          *offset = msg_ptr->next->offset;
 /* message is a leaf */
 else
 {
  for(ptr = msg_ptr->prev, last = msg_ptr, done = 0; !done;  last=ptr, ptr=ptr->prev)
   {
    done = (ptr->data.info.reply_to == -1) ||
           ((ptr->reply == last) && (ptr->next));
   if(done) break;        
   }        
  if(ptr->data.info.reply_to == -1)
     *offset = -1;
  else
     *offset = ptr->next->offset;   

 }
}   



static 
void get_previous_msg_offset(MSG_TREE_NODE *msg_ptr, MSG_TREE_NODE *topic_ptr, int uses_topic, long *offset)
{
MSG_TREE_NODE *leaf;

 if(!uses_topic)
   *offset = topic_ptr->prev ? topic_ptr->prev->offset : -1;
 else
  if(msg_ptr->data.info.reply_to == -1)  /* msg is the topic */
    *offset = -1;
 else
  if( (msg_ptr->prev->reply == msg_ptr) ||    /* msg was first reply to another msg */
      (!msg_ptr->prev->reply))                /* prev. message had no replies */
    *offset = msg_ptr->prev->offset;
 else
 {
   leaf = find_last_node(msg_ptr->prev->reply);
   *offset = leaf->offset;
 }
}   
    
     
       
static
void get_topic_offsets( MSG_TREE_NODE *topic_ptr, int uses_topic, 
                            long *next_topic_offset, long *prev_topic_offset)
{

 if (!uses_topic)	
    {
      *next_topic_offset = -1;
      *prev_topic_offset = -1;
    }
  else
   {
     *prev_topic_offset = topic_ptr->prev ? topic_ptr->prev->offset : -1;
     *next_topic_offset = topic_ptr->next ? topic_ptr->next->offset : -1;
   }
}




static void
get_offsets (MSG_TREE_NODE *msg_ptr, MSG_TREE_NODE *topic_ptr,
	     int grp, long *next_msg_offset, long *prev_msg_offset,
	     long *next_topic_offset, long *prev_topic_offset)
{

 int uses_topic;
 
 uses_topic = group_uses_topic(grp);  /* shared_news_util.c */
  
 get_topic_offsets( topic_ptr, uses_topic, next_topic_offset, prev_topic_offset);
 get_previous_msg_offset(msg_ptr, topic_ptr, uses_topic, prev_msg_offset);
 get_next_msg_offset(msg_ptr, topic_ptr, uses_topic, next_msg_offset);
       
}      


static void
get_supporting_strings (const char *course, const char *key, int grp,
			long offset, int is_fac_teamteach,
			char team, char *fromstring, char *teamstring, const char *username, char *recipient_username)
{
  /* AMP_SUB, et. al. are #defined in shared_translate_url.h */
  snprintf (fromstring, MAX_PATH + 1,
	    "from=%s%ccrs%c%s%cid%c%s%cgrp%c%d%cloc%c%ld",
	    "news_read", QMARK_SUB, EQUAL_SUB, course,
	    AMP_SUB, EQUAL_SUB, key, AMP_SUB, EQUAL_SUB, grp, AMP_SUB,
	    EQUAL_SUB, offset);


  if (is_fac_teamteach)
    {
      snprintf (teamstring, 10, "%cteam%c%c", AMP_SUB, EQUAL_SUB, team);
      strcat (fromstring, teamstring);
      snprintf (teamstring, 10, "&team=%c", team);
    }
  else
    *teamstring = '\0';
    
  /* only students should be running this program from within the ASSIGNMENTS module
  ** they need to send the message to themselves
  */  
  if(grp == ASSIGNMENTS)
     snprintf(recipient_username,MAX_USERNAME * 2, "&to=%s", username);
  else
    *recipient_username = '\0';   
}



static void
set_command_urls (MSG_TREE_NODE *msg_ptr, MSG_TREE_NODE *topic_ptr,
                          const char *course, const char *key,
			  char *topic_prog, int grp, 
			  char team, int is_fac_teamteach,
	                  char *username, int can_write, int read_only)
{
  char url[MAX_PATH + 1];
  long next_msg_offset, prev_msg_offset, next_topic_offset, prev_topic_offset;
  char from_string[MAX_PATH + 1];	/* how to get back to THIS page... passed
					** to the NEWS_NEW_MEMO program
					**/
  char teamstring[10];		        /* eg. "team=A" */
  char to_string[MAX_USERNAME * 2];     /* eg "&to=snarmontas" */


  get_offsets (msg_ptr, topic_ptr, grp,
	       &next_msg_offset, &prev_msg_offset,
	       &next_topic_offset, &prev_topic_offset);


  get_supporting_strings (course, key, grp, msg_ptr->offset, is_fac_teamteach,
			  team, from_string, teamstring,username, to_string);


 /*** back button url*****/
  snprintf (url,MAX_PATH + 1, "%s#%d",  topic_prog, topic_ptr->data.info.msg_id);
  cs_set_value("back_button_url", url);   /* shared_cs_util.h */
  

/* set a url for the main_menu */
 snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s", "main_menu", course, key);
 cs_set_value("main_menu_url", url);      /* shared_cs_util.h */



/***** read previous msg ****/

  if (prev_msg_offset != -1)
   {
    snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;loc=%ld&amp;grp=%d%s",
	    "news_read", course, key, prev_msg_offset, grp, teamstring);
    cs_set_value("prev_msg_url", url);       /* shared_cs_util.h */
   } 

/**** Add a New Message to this topic **/

   if(can_write && group_uses_topic(grp) && !read_only)     /* shared_news_util.c */
    {
     snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;topic=%d%s%s&amp;reply_to=%d&amp;%s",
	    "news_new_memo", course, key, grp, msg_ptr->data.info.topic_id, teamstring, to_string,
            msg_ptr->data.info.topic_id, from_string);
     cs_set_value("new_msg_url", url);                  /* shared_cs_util.h */
    }         



/*** previous Topic ***/
  if (!group_uses_topic (grp))
    prev_topic_offset = -1;


  if (prev_topic_offset != -1)
  {  
    snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;loc=%ld&amp;grp=%d%s",
	    "news_read", course, key, prev_topic_offset, grp, teamstring);
    cs_set_value("prev_topic_url", url);   /* shared_news_util.h */
  }  


/**** INFO ***/

  if(grp == SURVEYS)
     snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;loc=%ld",
       	                  "survey_info", course, key, msg_ptr->offset);
  else
     snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;loc=%ld&amp;grp=%d",
	                             "news_info", course, key, msg_ptr->offset, grp);

   cs_set_value("info_url", url);     /* shared_cs_util.h */
   
   
   
/**** read next ****/

  if (next_msg_offset != -1)
  {
    snprintf
      (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;loc=%ld&amp;grp=%d%s",
          "news_read", course, key, next_msg_offset, grp, teamstring);
    cs_set_value("next_msg_url", url);		/* shared_cs_util.h */
  }
          

/*** reply to this message */
 if(can_write && group_uses_topic(grp) && !read_only)
    {
      snprintf
      (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;topic=%d&amp;loc=%ld%s%s&amp;reply_to=%d&amp;%s",
       "news_new_memo", course, key, grp, msg_ptr->data.info.topic_id, msg_ptr->offset, teamstring,to_string,
       msg_ptr->data.info.msg_id, from_string);
       
      cs_set_value("reply_url", url);          /* shared_cs_util.h */
    }




/*** next Topic ***/
  if (!group_uses_topic (grp))
    next_topic_offset = -1;


  if (next_topic_offset != -1)
  {
    snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;loc=%ld&amp;grp=%d%s",
	                "news_read", course, key, next_topic_offset, grp, teamstring);

    cs_set_value("next_topic_url", url);             /* shared_cs_util.h */
 
  }



/** set flag value and url */

   cs_set_int_value("flagged", msg_ptr->user_data.flagged? 1:0);

   snprintf(url, 
       MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;msg_id=%d&amp;%s",
        "news_flag", course, key, grp, msg_ptr->data.info.msg_id, from_string);
   cs_set_value("flag_url", url);  




}  




static void
process_msg_node (MSG_TREE_NODE *msg_ptr, int *website_attached, CONFIG_STRUCT *conf, 
							SESSION *user, int *attachments_locked, int grp)
{
  FILE *fp;
  int fd;
  char infopath[MAX_PATH + 1];
  int i;
  NEWS_INFO infofile_info;
  ATTACHMENT_NODE *aptr = 0;

  *attachments_locked = 0;
  if(!msg_ptr->user_data.time_read && (conf->access != ACCESS_CAPTURE))   /* if msg is unread and we're not in capture mode */
   {
    if(IS_PROTECTED(msg_ptr->data.status) && msg_ptr->data.info.attachments)
       *attachments_locked = 1;
    else
     /* don't mark the message as read if this is a student reading 
     ** a SURVEY message
     **/
      if( (user->group == FACULTY) || (grp != SURVEYS))
       mark_msg_as_read(&(msg_ptr->data),conf,user);   /*shared_news_util.c */
   }    
       
 
 if( (grp == SURVEYS) && 
     (user->group == STUDENT) && 
     !msg_ptr ->user_data.time_read &&
     is_unanswered_required_survey(conf, msg_ptr -> data.info.sender, msg_ptr->data.info_fname, user) )  /* shared_survey_take_verify.c */
     
        cs_set_int_value("is_unanswered_required_survey", 1);
       
  /*** BUGFIX: Prior to version 3, a data variable was left uninitialized.  
  **** The result was that when upgrading to version 3, all Internet Resources and
  **** Survey module messages would say "The attachments were locked, you unlocked them at:"
  ***  which was a problem.  Since Internet Resources and Surveys can NEVER have attachments,
  **** we'll deal with this bug by saying the attachments are not locked for these modules
  ***/
  
  if( (grp == INTERNET_RESOURCES) || (grp == SURVEYS))
      *attachments_locked = 0;
      
      

  /*** if there are attachments, read the info file to 
  **** build the attachment list
  ***/

 *website_attached = 0;  /* assume this to start */
 if(msg_ptr->data.info.attachments)
 {
   snprintf(infopath,MAX_PATH + 1,"%s%s/%s/%s/%s",conf->course_path,PEOPLE_DIR,
                                                          msg_ptr->data.info.sender,discussion_fname,msg_ptr->data.info_fname);
  fp = fopen(infopath,"r");
  if(!fp)                             
     cs_critical_error (ERR_FOPEN_READ_FAILED, infopath);
  
  fd = fileno(fp);
  get_shared_lock(fd, 1);                      /* shared_lock.c */    

  if(fread(&infofile_info, sizeof(NEWS_INFO),1,fp) != 1) 
   cs_critical_error (ERR_FREAD_FAILED, infopath);   /* shared_cs_util.c */


  /* process attachments, build linked list */
  *website_attached = (infofile_info.attachments == -1);
  if (*website_attached)
    infofile_info.attachments = 1;	/* since we have to pick up the dirname */

  for (i = 1; i <= infofile_info.attachments; i++)
    {
      if (!attachment_head)
	{
	  attachment_head =
	    (ATTACHMENT_NODE *) malloc (sizeof (ATTACHMENT_NODE));
	  if (!attachment_head)
	    cs_critical_error (ERR_MALLOC_FAILED, "process_msg_node()");   /* shared_cs_util.c */
	  aptr = attachment_head;
	}
      else
	{
	  aptr->next = (ATTACHMENT_NODE *) malloc (sizeof (ATTACHMENT_NODE));
	  if (!aptr->next)
	    cs_critical_error (ERR_MALLOC_FAILED, "process_msg_node()");   /* shared_cs_util.c */
	  aptr = aptr->next;
	}

      if(fread(&aptr->data,sizeof(ATTACHMENT),1,fp) != 1)
	 cs_critical_error (ERR_FREAD_FAILED, infopath);                /* shared_cs_util.c */
      aptr->next = 0;
    }				/* for .. */

  release_lock(fd);   /* shared_lock.c */
  fclose (fp);
 } /* if attachments */ 
}



static
int teacher_hidden_setting(GROUP_TYPE group, CONFIG_STRUCT *conf)
{
  FILE *fp;
  char filter_path[MAX_PATH + 1];
  NEWS_FILTER filter;
  
  if(group != FACULTY)
     return 0;        /* only teachers can see teacher hidden items */
     
  if(conf->access == ACCESS_CAPTURE)   /* show teacher hidden for teachers while in capture node */
      return 1;
      
  snprintf (filter_path, MAX_PATH + 1, "%s/%s", discussion_path,
	    NEWS_FILTER_FNAME);
  fp = fopen (filter_path, "r");
  if (fp)
    {
      if(fread (&filter, sizeof (NEWS_FILTER), 1, fp) != 1)
      { 
        fclose (fp);
        return 1;   /* an error occurred, assume show_teacher_hidden is set */
      }  
      else
      { 
        fclose(fp);
        return (filter.show_teacher_hidden);
      }  
    }
  else
    return 1;

}






static void
set_news_msg_values (const char *course, const char *key, long offset,
		  char *topic_prog, int grp, char team, int is_fac_teamteach,
                  CONFIG_STRUCT *conf, SESSION *user, int can_write, int printer_friendly)
{
 MSG_TREE_NODE *msg_ptr;
 MSG_TREE_NODE *topic_ptr;
 int msg_count;
 int website_attached;
 int show_teacher_hidden;   /* include msgs that are hidden by the teacher? */
 int teacher_hidden;        /* is THIS message hidden by the teacher? */
 int read_only;             /* did teacher mark this topic as read-only? */
 int attachments_locked;   /* did the teacher protect the attachments, and did the student not yet unlock them? */
 time_t current_time;
 int topic_with_replies;   /* is this a topic in a discussion that has replies? */
 char url[MAX_PATH + 1];
 char msg_path[MAX_PATH + 1];
 char inet_url[MAX_URL + 1];
    
 show_teacher_hidden = teacher_hidden_setting(user->group, conf);
 
 /* In the next function call, the parameter is 'show_teacher_hidden || printer_friendly'
 ** because... when the teacher is gathering ALL MESSAGES, even teacher hidden messages are 
 ** shown.  The PRINT feature must work from that page.
 */
 
 build_one_topic_tree(user,grp,offset,&msg_ptr,&topic_ptr,&msg_count,1, 
                                      show_teacher_hidden || printer_friendly, &current_time);  /* shared_news_util.c */

 if(!msg_ptr || !tree_head)
   cs_critical_error(ERR_MSG_NOT_FOUND, "display_news_msg()");     /* shared_cs_util.c */

                                      
 teacher_hidden = is_teacher_hidden(topic_ptr->data.status, topic_ptr->data.release_time, 
                                                       topic_ptr->data.unrelease_time, current_time); /* shared_news_util.c */
 
 read_only = BASIC_STATUS(topic_ptr->data.status) == READ_ONLY ? 1 : 0;  /* see global.h */
 

 process_msg_node (msg_ptr,&website_attached,conf,user, &attachments_locked, grp);

 /* shared_news_util.c */
 set_news_msg_header_data (msg_ptr, "msg.", teacher_hidden, read_only, topic_ptr->data.info.subject); 
    
 /* clear msg.time sent, which was set by the above call, if appropriate */
  if ((grp == ANONYMOUS_DISCUSSION) && HIDE_ANONYMOUS_TIMES) /* see custom.h */
   {
    cs_set_value("msg.time_sent", "");    /* shared_cs_util.h */
   } 
    
    
   /*** BUGFIX: Prior to version 3, a data variable was left uninitialized.  
  **** The result was that when upgrading to version 3, all Internet Resources and
  **** Survey module messages would say "The attachments were locked, you unlocked them at:"
  ***  which was a problem.  Since Internet Resources and Surveys can NEVER have attachments,
  **** we'll deal with this bug by saying the user didn't unlock attachments for these modules
  ***/
   
  if((grp == INTERNET_RESOURCES) || (grp == SURVEYS))
     cs_set_int_value("msg.user_unlocked", 0); 
    
  if(group_uses_topic(grp))                 	/* shared_news_util.c */
     cs_set_value("group_uses_topic", "1");   	/* shared_cs_util.h */


  set_command_urls (msg_ptr, topic_ptr, course, key, topic_prog, grp,
			    team, is_fac_teamteach,user->username, can_write, read_only && (user->group == STUDENT));

  cs_set_bio_link(msg_ptr->data.info.sender, course, conf, key, grp, 0, "user", 30);   /* shared_bio.c */
 
  /* shared_news_util.c */
  set_news_attachment_data (msg_ptr, 
                           topic_ptr->data.info.subject, 
                           course, 
                           key, 
                           grp,  
                           website_attached,
			   "news_read", 
			   team, 
			   is_fac_teamteach,  
 	                   "",                   /* no assign_read_student value */
			   conf, attachments_locked, 
			   user->username,  
			   attachment_head, 
			   "");     /* no name prefix value */



  /* handle body of message */

  snprintf (msg_path, MAX_PATH + 1, "%s%s/%s/%s/%s",
	    conf->course_path, PEOPLE_DIR, msg_ptr->data.info.sender, discussion_fname, msg_ptr->data.info.msg_fname);
	    
  if(grp == INTERNET_RESOURCES)
       snprintf(inet_url, MAX_URL + 1, "%s?crs=%s&amp;id=%s&amp;loc=%ld&amp;url=", 
                                               "link_visit", course, key,  offset);  
  else
     *inet_url = '\0';        
                                       
  set_msg_body_data (msg_path, "", inet_url); /* shared_msg_line.c */


  /* put in a list of things only the teacher can do */
  if (user->group == FACULTY)
    {
    
      topic_with_replies = (msg_ptr == topic_ptr) &&
                           (msg_count > 1) &&
                           group_uses_topic(grp);

      if(topic_with_replies)
         cs_set_value("is_topic_with_replies", "1");   /* shared_cs_util.h */

      if(can_write)
          cs_set_value("insert_kill_form", "1");       /* shared_cs_util.h */

           
      if(website_attached)
      {
         snprintf(url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;sender=%s&amp;dir=%s&amp;grp=%d",
             "web_page_zip", course, key, msg_ptr->data.info.sender, 
              attachment_head->data.unique_fname, grp);		
         cs_set_value("website_zip_download_url", url);   /* shared_cs_util.h */
         
         cs_set_value("website_dirname", attachment_head->data.unique_fname); /* shared_cs_util.h */
              
      }
      
    }  /* if(user.grp == FACULTY) */


  free_msg_tree(tree_head); /*shared_news_util.c */
}





static void
free_attachment_list ()
{
  ATTACHMENT_NODE *aptr;

  while (attachment_head)
    {
      aptr = attachment_head;
      attachment_head = attachment_head->next;
      free (aptr);
    }
}







int
main (void)
{
  char course[MAX_PATH + 1];	/* from crs=? command line */
  char key[MAX_KEY + 1];	/* from id=? command line */
  long offset;			/* from loc=? command line */

  int grp;			/* from grp=? command line */

  char team;			/* from team=? command line: used only for instructors 
				   in the team/teach module  */

  int del_link;			/* from del_link=?command line  do we need to rm a symbolic link
				   ** to an attached web page?
				 */
				 
  int printer_friendly;         /* from print=? command line  provide "printer friendly" version? */				 
  int fixed_font;               /* from fixed=? command line  print body as fixed font? */				 

  int is_fac_teamteach;		/* is this user faculty using the team/teacher discussion module? */
  char topic_prog[MAX_PATH + 1];	/* arguments to NEWS_TOPIC program */

  SESSION user;
  CONFIG_STRUCT conf;		/* the configuration read from config file */
  int can_write;
  char teamstring[2];            


   cs_cgi_init();    /* shared_cs_util.c */

  read_parameters (course, key, &offset, topic_prog, &grp, &del_link, &printer_friendly, &fixed_font);
  
  read_configuration_file (course, &conf);	/* shared_util.c */
  validate_key (key, &user, &conf);	        /* shared_util.c */
  
  if(user.group == FACULTY)
       cs_set_value("is_faculty","1");          /* shared_cs_util.h */
       
  if(conf.access == ACCESS_CAPTURE)
    {
      cs_set_value("capture_mode", "1");        /* shared_cs_util.h */
      printer_friendly = 0;                    /* no printer option if capturing */
   }

   cs_set_int_value("printer_friendly", printer_friendly);
   cs_set_int_value("fixed_font", fixed_font);
  
  can_write = has_write_permission(&user, &conf);  /* shared_access.c */ 
  if(can_write)
      cs_set_value("can_write", "1");    	/* shared_cs_util.h */
   

   
  cs_set_course_info(&conf);      /* shared_cs_util.c */    
  cs_set_value("crs", course);    /* shared_cs_util.h */
  cs_set_int_value("grp", grp);   /* shared_cs_util.h */
  cs_set_value("key", key);	  /* shared_cs_util.h */
  cs_set_value("username",user.username);  	  /* shared_cs_util.h */
    
  set_discussion_names (conf.course_path, user.username, grp);	/* shared_news_util.c */

  check_is_fac_team_teach (grp, &is_fac_teamteach, &team, topic_prog, &user);
  if(is_fac_teamteach)
   {
     user.team = team;
     cs_set_value("is_fac_teamteach", "1");
   }
   
  if(team != NOTEAM)
   {
      *teamstring = team;
      *(teamstring + 1) = '\0';
      cs_set_value("team", teamstring);		/* shared_cs_util.h */
   }
   
  set_news_msg_values (course, key, offset, topic_prog, grp, team,
			is_fac_teamteach, &conf, &user, can_write, printer_friendly);

  if (del_link)
  {
    remove_stale_symlinks (user.username, course, conf.access); /* shared_news_util.c */
    if(grp == SELFTEST)
       kill_hotpotato_directory(user.username, &conf);  /* shared_potato_util.c */
  }      

  free_attachment_list ();

  cs_cgi_display ("news_read", 1);    	/* shared_cs_util.c */
  cs_cgi_destroy();        		/* shared_cs_util.c */

  return 0;
}

