#include #include #include "global.h" #include "custom.h" #include "manhat-lib/shared_util.h" #include "manhat-lib/shared_cs_util.h" #include "manhat-lib/shared_lock.h" #include "manhat-lib/shared_news_util.h" #include "manhat-lib/shared_time.h" typedef enum {VISIBLE, HIDDEN, R_ONLY, SCHED_NORMAL, SCHED_HIDDEN, UNKNOWN} VISIBILITY; static void read_parameters (char *course, char *key, int *grp, long *offset) { char tmp[20]; /* scratch variable */ cs_get_required_parameter ("crs", course, MAX_PATH); cs_set_value("crs", course); cs_get_required_parameter ("id", key, MAX_KEY); cs_set_value("id", key); cs_get_required_parameter ("grp", tmp, 5); cs_set_value("grp", tmp); *grp = atoi(tmp); cs_get_required_parameter ("loc",tmp, 19); cs_set_value("offset", tmp); *offset = atol(tmp); } static void read_msg(CENTRAL_INBOX_RECORD *msg, long offset) { FILE *fp; int fd; char inbox_fname[MAX_PATH + 1]; /* full path to central inbox */ snprintf(inbox_fname,MAX_PATH + 1,"%s%s",central_discussion_path,INBOX_FNAME); fp = fopen(inbox_fname,"r"); if(!fp) /* inbox.dat doesn't exist */ cs_critical_error(ERR_FOPEN_READ_FAILED,""); fd = fileno(fp); get_shared_lock(fd, 1); /* shared_lock.c */ if(fseek( fp, offset, SEEK_SET)) cs_critical_error(ERR_FSEEK_FAILED,""); if(fread(msg,sizeof(CENTRAL_INBOX_RECORD),1,fp) != 1) cs_critical_error(ERR_FREAD_FAILED, ""); release_lock(fd); /* shared_lock.c */ fclose(fp); } static void set_subject(char *subject) { char *escaped_subject = (char *) 0; cs_set_value("subject", subject); cs_html_escape_string(subject, &escaped_subject); if(escaped_subject) { cs_set_value("escaped_subject", escaped_subject ); free(escaped_subject); } } static void get_msg_visibility(CENTRAL_INBOX_RECORD *msg, VISIBILITY *status, time_t now) { switch(BASIC_STATUS(msg->status)) /* see macro definition in global.h */ { case NORMAL : *status = VISIBLE; break; case TEACHER_HIDDEN: *status = HIDDEN; break; case READ_ONLY: *status = R_ONLY; break; case TIMED_RELEASE : if( (msg->unrelease_time && (msg->unrelease_time < now)) || (msg->release_time > now) ) *status = SCHED_HIDDEN; else *status = SCHED_NORMAL; break; default: *status = UNKNOWN; /* should never happen */ break; } } static void set_manual_hide_url(VISIBILITY status, const char *course, const char *key, int grp, long offset) { char url[MAX_PATH +1]; if(status == HIDDEN) return; /* since the message is already manually hidden */ snprintf(url, MAX_PATH +1, "%s?crs=%s&id=%s&grp=%d&loc=%ld&hide=1", "news_manage_topic_hide",course,key,grp,offset); cs_set_value("manual_hide_url", url); } static void set_manual_unhide_url(VISIBILITY status, const char *course, const char *key, int grp, long offset) { char url[MAX_PATH +1]; if(status == VISIBLE) return; /* since the message is already a normal msg */ snprintf(url, MAX_PATH +1, "%s?crs=%s&id=%s&grp=%d&loc=%ld&hide=0", "news_manage_topic_hide",course,key,grp,offset); cs_set_value("manual_unhide_url", url); } static void set_manual_ro_url(VISIBILITY status, const char *course, const char *key, int grp, long offset) { char url[MAX_PATH +1]; /* faculty_only_group() is in shared_news_util.c */ if( (status == R_ONLY) || faculty_only_group(grp) ) return; snprintf(url, MAX_PATH +1, "%s?crs=%s&id=%s&grp=%d&loc=%ld&hide=2", "news_manage_topic_hide",course,key,grp,offset); cs_set_value("manual_readonly_url", url); } void set_mm_dd_yyyy(struct tm target_tm, char *prefix) { #define MAX_TMP 30 char str[MAX_TMP + 1]; char name[MAX_TMP + 1]; int month, day, year; year = target_tm.tm_year + 1900; /* handle month */ month = target_tm.tm_mon + 1; snprintf(name, MAX_TMP, "%s_month", prefix); if(month < 10) { snprintf(str,MAX_TMP, "0%d", month); cs_set_value(name, str); } else cs_set_int_value(name, month); /* handle day */ day = target_tm.tm_mday; snprintf(name, MAX_TMP, "%s_day", prefix); if(day < 10) { snprintf(str,MAX_TMP, "0%d", day); cs_set_value(name, str); } else cs_set_int_value(name, day); /* handle year */ year = target_tm.tm_year + 1900; snprintf(name, MAX_TMP, "%s_year", prefix); cs_set_int_value(name, year); #undef MAX_TMP } static void set_start_date_options(CENTRAL_INBOX_RECORD *msg, VISIBILITY status, time_t now) { struct tm target_tm; if( (status == SCHED_NORMAL) || (status == SCHED_HIDDEN)) target_tm = *localtime (&(msg->release_time)); else target_tm = *localtime(&now); set_mm_dd_yyyy(target_tm, "release"); set_hour_minute_ampm(&target_tm, "release"); /* shared_time.c */ } void set_end_date_options(CENTRAL_INBOX_RECORD *msg, VISIBILITY status, time_t now) { struct tm target_tm; if( ((status == SCHED_NORMAL) || (status == SCHED_HIDDEN)) && (msg->unrelease_time) ) { target_tm = *localtime (&(msg->unrelease_time)); set_mm_dd_yyyy(target_tm, "unrelease"); } else target_tm = *localtime(&now); set_hour_minute_ampm(&target_tm, "unrelease"); /* shared_time.c */ } static void set_schedule_option(CENTRAL_INBOX_RECORD *msg, VISIBILITY status) { time_t now; now = time(NULL); set_start_date_options(msg,status,now); set_end_date_options(msg,status,now); } static void set_visibility_values(VISIBILITY status, time_t release_time, time_t unrelease_time) { char timestring[MAX_TIMESTRING + 1]; cs_set_int_value("raw_status", status); /* probably useless, but we'll provide it anyway */ /* these are more human readable representations of status */ switch(status) { case VISIBLE: cs_set_value("status", "VISIBLE"); break; case HIDDEN: cs_set_value("status", "HIDDEN"); break; case R_ONLY: cs_set_value("status", "R_ONLY"); break; case SCHED_NORMAL: cs_set_value("status", "SCHED_NORMAL"); break; case SCHED_HIDDEN: cs_set_value("status", "SCHED_HIDDEN"); break; case UNKNOWN: cs_set_value("status", "UNKNOWN"); break; default: cs_set_value("status", "UNKNOWN"); break; } /* If scheduled, set the release and unrelease times */ if( (status == SCHED_HIDDEN) || (status == SCHED_NORMAL) ) { strftime (timestring, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT, localtime (&release_time) ); cs_set_value("release_time", timestring); if(unrelease_time) { strftime (timestring, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT, localtime (&unrelease_time) ); cs_set_value("unrelease_time", timestring); } } } static void set_form_data( char *course, char *key, int grp, long offset, SESSION *user, CONFIG_STRUCT *conf) { #define MAX_OFFSET_STRING 20 CENTRAL_INBOX_RECORD msg; VISIBILITY visible; time_t now; now = time(NULL); set_discussion_names (conf->course_path, user->username, grp); /* shared_news_util.c */ read_msg(&msg, offset); cs_set_course_info(conf); cs_set_current_time(); cs_set_value("grp_uses_topic", group_uses_topic(grp)? "1" :"0"); get_msg_visibility(&msg,&visible,now); set_visibility_values(visible, msg.release_time, msg.unrelease_time); set_subject(msg.info.subject); set_manual_hide_url(visible, course,key, grp, offset); set_manual_unhide_url(visible, course,key,grp,offset); set_manual_ro_url(visible, course, key,grp,offset); set_schedule_option(&msg,visible); #undef MAX_OFFSET_STRING } int main () { 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 */ SESSION user; CONFIG_STRUCT conf; cs_cgi_init(); read_parameters (course, key, &grp, &offset); read_configuration_file (course, &conf); /* shared_util.c */ validate_key (key, &user, &conf); /* shared_util.c */ if (user.group != FACULTY) cs_critical_error (ERR_REQUEST_DENIED, ""); set_form_data(course, key, grp, offset, &user, &conf); cs_cgi_display("news_manage_sched_form", 1); cs_cgi_destroy(); return 0; }