#include #include #include #include #include "global.h" #include "custom.h" /* for date FORMAT strings, etc. */ #define NOTEAM '!' /* flag meaning that there was no 'team' parameter sent to this program */ #include "manhat-lib/shared_util.h" #include "manhat-lib/shared_cs_util.h" #include "manhat-lib/shared_news_util.h" #include "manhat-lib/shared_person_list.h" #include "manhat-lib/shared_translate_url.h" typedef struct topic_node { int total_msgs; int total_unread; int total_flagged; int teacher_hidden; MSG_TREE_NODE *topic_head; struct topic_node *next; struct topic_node *prev; } TOPIC_NODE; TOPIC_NODE *topic_head = 0; TOPIC_NODE *topic_tail = 0; #define MAX_TEAMPART 20 typedef struct common_data { char course[MAX_PATH + 1]; char key[MAX_KEY + 1]; int grp; char fromstring[MAX_PATH + 1]; char teampart[MAX_TEAMPART + 1]; int no_topic_type; char team; int is_fac_teamteach; int is_fac_assignments; } COMMON_DATA; COMMON_DATA common; static void read_topic_parameters () { char msg[80]; cs_get_required_parameter ("crs", common.course, MAX_PATH); /* shared_cgi_util.c */ cs_get_required_parameter ("id", common.key, MAX_KEY); cs_get_required_parameter ("grp", msg, 5); common.grp = atoi (msg); } static void set_general_values (CONFIG_STRUCT *conf, SESSION *user) { char url[MAX_PATH +1]; cs_set_course_info(conf); cs_set_current_time(); if (common.is_fac_teamteach) snprintf (url, MAX_PATH +1, "%s?crs=%s&id=%s&grp=%d&team=%c", "news_topic", common.course, common.key, common.grp, common.team); else snprintf (url, MAX_PATH +1, "%s?crs=%s&id=%s&grp=%d", "news_topic", common.course, common.key, common.grp); cs_set_value("back_url", url); cs_set_int_value("grp", common.grp); cs_set_value("crs",common.course); cs_set_value("id", common.key); if (common.is_fac_teamteach) { snprintf(url, 5, "%c",common.team); cs_set_value("team", url); } cs_set_value("grp_uses_topics", common.no_topic_type? "0":"1"); } /* assumes build_msg_tree() has already been called */ static void build_topic_list (time_t current_time) { TOPIC_NODE *ptr = 0; MSG_TREE_NODE *topic_ptr; int total_msgs = 0; int total_unread = 0; int total_flagged = 0; for(topic_ptr = tree_head; topic_ptr; topic_ptr=topic_ptr->next) { if (!topic_head) { topic_head = (TOPIC_NODE *) malloc (sizeof (TOPIC_NODE)); if(!topic_head) cs_critical_error(ERR_MALLOC_FAILED,""); ptr = topic_head; ptr->prev = 0; } else { ptr->next = (TOPIC_NODE *) malloc (sizeof (TOPIC_NODE)); if(!ptr->next) cs_critical_error(ERR_MALLOC_FAILED, ""); ptr->next->prev = ptr; ptr = ptr->next; } count_topic_msgs(topic_ptr,&total_msgs, &total_unread, &total_flagged); /* shared_news_util.c */ ptr->total_msgs = total_msgs; ptr->total_unread = total_unread; ptr->total_flagged = total_flagged; ptr->teacher_hidden = is_teacher_hidden (topic_ptr->data.status, topic_ptr->data.release_time, /* shared_news_util.c */ topic_ptr->data.unrelease_time, current_time); ptr->topic_head = topic_ptr; ptr->next = 0; topic_tail = ptr; total_msgs = 0; total_unread = 0; total_flagged = 0; } } static void free_topic_list () { TOPIC_NODE *ptr; while (topic_head) { ptr = topic_head; topic_head = topic_head->next; free(ptr); } } static void get_fromstring () { /* AMP_SUB, et. al. are #defined in shared_translate_url.h */ snprintf (common.fromstring, MAX_PATH + 1, "%s%ccrs%c%s%cid%c%s%cgrp%c%d", "news_topic", QMARK_SUB, EQUAL_SUB, common.course, AMP_SUB, EQUAL_SUB, common.key, AMP_SUB, EQUAL_SUB, common.grp); if (common.team != NOTEAM) { snprintf (common.teampart, MAX_TEAMPART, "%cteam%c%c", AMP_SUB, EQUAL_SUB, common.team); strcat (common.fromstring, common.teampart); snprintf (common.teampart, MAX_TEAMPART, "&team=%c", common.team); /* so we can use it directly */ } else *common.teampart = '\0'; } static void set_message_data (TOPIC_NODE *ptr, time_t now, const char *teamstring) { #define MAX_TMP_NAME 40 char timestring[MAX_TIMESTRING + 1]; static int i =0; char name[MAX_TMP_NAME +1]; char *escaped_subject = (char *) 0; char offset_string[MAX_TMP_NAME + 1]; int basic_status; snprintf(name, MAX_TMP_NAME, "message.%d.msg_id", i); cs_set_int_value(name, ptr->topic_head->data.info.msg_id); snprintf(name, MAX_TMP_NAME, "message.%d.offset", i); snprintf(offset_string,MAX_TMP_NAME,"%ld", ptr->topic_head->offset); cs_set_value(name,offset_string); snprintf(name, MAX_TMP_NAME, "message.%d.teacher_hidden", i); cs_set_value(name, ptr->teacher_hidden? "1":"0"); /* should the HTML page provide a means for the teacher to lock ** the attachments to this message? **/ snprintf(name, MAX_TMP_NAME, "message.%d.allow_locked_attachments", i); /* if there are no attachments, or if this is the *** ANONYMOUS or SURVEYS module, don't allow user ** to set the attachment protection feature */ if(!ptr->topic_head->data.info.attachments || common.grp == ANONYMOUS_DISCUSSION || common.grp == SURVEYS || common.grp == INTERNET_RESOURCES) { cs_set_value(name, "0"); /* don't allow locked attachments */ } else { cs_set_value(name, "1"); /* allow locked attachments */ } /* are the attachments to this message currently locked? */ snprintf(name, MAX_TMP_NAME, "message.%d.attachments_locked", i); cs_set_value(name, IS_PROTECTED(ptr->topic_head->data.status) ? "1" : "0"); /* how many messages are associated with this topic? */ snprintf(name, MAX_TMP_NAME, "message.%d.total_msgs", i); cs_set_int_value(name, ptr->total_msgs); /* how many UNREAD messages are associated with this topic? */ snprintf(name, MAX_TMP_NAME, "message.%d.total_unread", i); cs_set_int_value(name, ptr->total_unread); /* how many FLAGGED messages are associated with this topic? */ snprintf(name, MAX_TMP_NAME, "message.%d.total_flagged", i); cs_set_int_value(name, ptr->total_flagged); /* did this user already read THIS message? */ if(!ptr->topic_head->user_data.time_read) { snprintf(name, MAX_TMP_NAME, "message.%d.is_unread", i); cs_set_value(name, ptr->topic_head->user_data.time_read? "0":"1"); } /* did this user flag THIS message? */ if(ptr->topic_head->user_data.flagged) { snprintf(name, MAX_TMP_NAME, "message.%d.is_flagged", i); cs_set_value(name, ptr->topic_head->user_data.flagged? "1":"0"); } /* are there any attachments to this message */ snprintf(name, MAX_TMP_NAME, "message.%d.has_attachments", i); cs_set_value(name, ptr->topic_head->data.info.attachments? "1" : "0" ); /* the raw, unescaped subject - probably won't be used, but we'll ** provide it anyway */ snprintf(name, MAX_TMP_NAME, "message.%d.subject", i); cs_set_value(name, ptr->topic_head->data.info.subject); /* the html escaped subject */ snprintf(name, MAX_TMP_NAME, "message.%d.escaped_subject", i); cs_html_escape_string(ptr->topic_head->data.info.subject, &escaped_subject); cs_set_value(name, escaped_subject); if(escaped_subject) free(escaped_subject); /* real name of the person who sent the message */ snprintf(name, MAX_TMP_NAME, "message.%d.sender", i); cs_set_value(name, ptr->topic_head->data.info.sender_realname); /* date/time message was sent */ if ( !((common.grp == ANONYMOUS_DISCUSSION) && HIDE_ANONYMOUS_TIMES)) /* see custom.h */ { strftime (timestring, MAX_TIMESTRING, DOW_DATE_FORMAT, localtime (&(ptr->topic_head->data.info.time_sent))); snprintf(name, MAX_TMP_NAME, "message.%d.time_sent", i); cs_set_value(name, timestring); } /* 'raw' status information - this integer won't be too useful, but we'll ** provide it anyway */ basic_status = BASIC_STATUS(ptr->topic_head->data.status); /* BASIC_STATUS #defined in global.h */ snprintf(name, MAX_TMP_NAME, "message.%d.raw_status", i); cs_set_int_value(name, basic_status); snprintf(name, MAX_TMP_NAME, "message.%d.basic_status", i); switch(basic_status) { case NORMAL: cs_set_value(name,"NORMAL"); break; case DELETED: cs_set_value(name, "DELETED"); /* should never happen */ break; case TEACHER_HIDDEN: cs_set_value(name, "TEACHER_HIDDEN"); break; case TIMED_RELEASE : cs_set_value(name, "TIMED_RELEASE"); /* there should also be a release time */ snprintf(name, MAX_TMP_NAME, "message.%d.release_time", i); strftime (timestring, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT,localtime (&(ptr->topic_head->data.release_time)) ); cs_set_value(name,timestring); /* the unrelease time is optional */ if(ptr->topic_head->data.unrelease_time) { strftime (timestring, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT, localtime (&(ptr->topic_head->data.unrelease_time)) ); snprintf(name, MAX_TMP_NAME, "message.%d.unrelease_time", i); cs_set_value(name, timestring); } break; case READ_ONLY: cs_set_value(name, "READ_ONLY"); break; default: cs_set_value(name, "UNDEFINED"); break; } i++; #undef MAX_TMP_NAME } void process_all_topics ( SESSION *user) { TOPIC_NODE *ptr; time_t now; char teamstring[10]; char timestring[MAX_TIMESTRING + 1]; if(common.is_fac_teamteach) snprintf(teamstring,10,"&team=%c", common.team); else *teamstring = '\0'; build_msg_tree(user,common.grp, 0, 1, &now); /* shared_news_util.c */ build_topic_list (now); strftime (timestring, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT, localtime (&now)); if (topic_head) { for (ptr = topic_head; ptr; ptr = ptr->next) set_message_data (ptr,now,teamstring); free_topic_list (); } free_msg_tree(tree_head); /* shared_news_util.c */ } static void display_topics ( CONFIG_STRUCT *conf, SESSION *user) { get_fromstring (); common.no_topic_type = !group_uses_topic (common.grp); /* shared_news_util.c */ /* print the header info */ cs_set_course_info(conf); cs_set_current_time(); set_general_values (conf, user); process_all_topics (user); } int main (void) { char tmp[10]; SESSION user; CONFIG_STRUCT conf; cs_cgi_init(); read_topic_parameters (); read_configuration_file (common.course, &conf); /* shared_util.c */ validate_key (common.key, &user, &conf); /* shared_util.c */ if(user.group != FACULTY) cs_critical_error(ERR_REQUEST_DENIED, ""); common.is_fac_assignments = (user.group == FACULTY) && (common.grp == ASSIGNMENTS); if ((user.group == FACULTY) && (common.grp == TEAM_TEACH)) { common.is_fac_teamteach = 1; cs_get_required_parameter ("team", tmp, 5); common.team = *tmp; /* switch this teacher's team to that supplied on the command line */ user.team = common.team; } else { common.is_fac_teamteach = 0; common.team = NOTEAM; } set_discussion_names (conf.course_path, user.username, common.grp); /* shared_news_util.c */ display_topics (&conf, &user); cs_cgi_display("news_manage_topic_list", 1); cs_cgi_destroy(); return 0; }