#include <stdio.h>
#include <time.h>
#include <unistd.h>		/* for mktemp() */
#include <string.h>

#include "global.h"


#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_file_util.h"
#include "manhat-lib/shared_access.h"
#include "manhat-lib/shared_lock.h"


static void
read_parameters (char *course, char *key, long *offset, int *hide, int *outbox)
{

  char off_set[MAX_FILENAME + 1];	/* for holding the long value */


  cs_get_required_parameter ("crs", course, MAX_PATH);
  cs_get_required_parameter ("id", key, MAX_KEY);
  
  cs_get_required_parameter ("loc", off_set, MAX_FILENAME);
  *offset = atol (off_set);
  
  cs_get_required_parameter ("hide", off_set, MAX_FILENAME);
  *hide = atol (off_set);
  
  cs_get_optional_parameter ("outbox", off_set, MAX_FILENAME);
  *outbox = strlen(off_set)? 1: 0;
  

}







static void
mark_inbox_msg (const char *course, long offset, CONFIG_STRUCT *conf, SESSION *user, int hide)
{

  INBOX_RECORD inbox;
  FILE *fp;
  char inbox_path[MAX_PATH + 1];	/* full path to inbox.dat */
 
  snprintf (inbox_path, MAX_PATH + 1, "%s%s/%s/%s/%s", 
                         conf->course_path,PEOPLE_DIR,
	                     user->username, MAIL_DIR, INBOX_FNAME);
  fp = fopen (inbox_path, "r+");
  if (!fp)
    cs_critical_error (ERR_FOPEN_APPEND_FAILED, inbox_path);

  get_exclusive_lock(fileno(fp), 1);
  
  if (fseek (fp, offset, SEEK_SET))
    cs_critical_error (ERR_FSEEK_FAILED, inbox_path);


  if (fread (&inbox, sizeof (INBOX_RECORD), 1, fp) != 1)
    cs_critical_error (ERR_RED_READ, inbox_path);

  
  inbox.is_sleepy = hide;
  fseek (fp, offset, SEEK_SET);
  if (fwrite (&inbox, sizeof (INBOX_RECORD), 1, fp) != 1)
    cs_critical_error (ERR_FWRITE_FAILED, inbox_path);

  release_lock(fileno(fp));
  fclose (fp);

}



static void
mark_outbox_msg (const char *course, long offset, CONFIG_STRUCT *conf, SESSION *user, int hide)
{

  OUTBOX_RECORD outbox;
  FILE *fp;
  char outbox_path[MAX_PATH + 1];

  snprintf (outbox_path, MAX_PATH + 1, "%s%s/%s/%s/%s", 
                         conf->course_path,PEOPLE_DIR,
	                     user->username, MAIL_DIR, OUTBOX_FNAME);
  fp = fopen (outbox_path, "r+");
  if (!fp)
    cs_critical_error (ERR_FOPEN_APPEND_FAILED, outbox_path);

  get_exclusive_lock(fileno(fp), 1);
  if (fseek (fp, offset, SEEK_SET))
    cs_critical_error (ERR_FSEEK_FAILED, outbox_path);


  if (fread (&outbox, sizeof (OUTBOX_RECORD), 1, fp) != 1)
    cs_critical_error (ERR_RED_READ, outbox_path);

  
  outbox.is_sleepy = hide;
  
  fseek (fp, offset, SEEK_SET);
  if (fwrite (&outbox, sizeof (OUTBOX_RECORD), 1, fp) != 1)
    cs_critical_error (ERR_FWRITE_FAILED, outbox_path);

  release_lock(fileno(fp));
  fclose (fp);

}





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 hide;			/* from hide=? command line */
  int outbox;                   /* from optional outbox=? command line */
  SESSION user;
  CONFIG_STRUCT conf;

  cs_cgi_init();
  read_parameters (course, key, &offset, &hide, &outbox);

  read_configuration_file (course, &conf);	/* shared_util.c */
  validate_key (key, &user, &conf);	/* shared_util.c */

  if(!has_write_permission(&user, &conf))   /* shared_access.c */
      access_denied_error();                /* shared_access.c */

  if(outbox)
   {
     mark_outbox_msg (course, offset, &conf, &user, hide);
     printf ("Location: %s?crs=%s&id=%s\n\n", "post_outbox" , course, key);

   }
  else
   {
     mark_inbox_msg (course, offset, &conf, &user, hide);
     printf ("Location: %s?crs=%s&id=%s\n\n", "post_inbox", course, key);
   }

 

  cs_cgi_destroy();

  return 0;
}

