#include #include #include #include #include "global.h" #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_teamstring.h" #define MAX_NAME_LIST 25 /* store this many names in the list of team members * */ typedef struct team_node { char team; int total_msgs; int total_unread; int total_flagged; struct team_node *next; char realname[MAX_NAME_LIST][MAX_NAME + 1]; int name_overflow; /** are there more than MAX_NAME_LIST members in this team **/ int total_members; /** how many people are on this team? */ } TEAM_NODE; static void read_parameters (char *course, char *key) { cs_get_required_parameter ("crs", course, MAX_PATH); cs_get_required_parameter ("id", key, MAX_KEY); } static void set_main_menu_url (char *course, char *key) { char url[MAX_PATH +1]; snprintf (url, MAX_PATH +1, "%s?crs=%s&id=%s","main_menu", course, key); cs_set_value("main_menu_url", url); } void update_existing_team (char team, char *realname, TEAM_NODE *team_head) { TEAM_NODE *ptr; for (ptr = team_head; ptr && (ptr->team != team); ptr = ptr->next); if (!ptr) cs_critical_error (ERR_TEAM_NOT_FOUND, ""); ptr ->total_members++; if(ptr->total_members >= MAX_NAME_LIST) ptr->name_overflow = 1; else strncpy (ptr->realname[ptr->total_members - 1], realname, MAX_NAME + 1); } TEAM_NODE * add_new_team (char team, char *realname, TEAM_NODE *team_head) { TEAM_NODE *ptr; int i; if (!team_head) { team_head = (TEAM_NODE *) malloc (sizeof (TEAM_NODE)); if (!team_head) cs_critical_error (ERR_MALLOC_FAILED, ""); ptr = team_head; } else { for (ptr = team_head; ptr->next; ptr = ptr->next); ptr->next = (TEAM_NODE *) malloc (sizeof (TEAM_NODE)); if (!ptr->next) cs_critical_error (ERR_MALLOC_FAILED, ""); ptr = ptr->next; } ptr->team = team; ptr->next = 0; ptr->total_msgs = 0; ptr->total_unread = 0; ptr->total_flagged = 0; ptr->name_overflow = 0; ptr -> total_members = *realname? 1: 0; strncpy (ptr->realname[0], realname, MAX_NAME + 1); for (i = 1; i < MAX_NAME_LIST; i++) *(ptr->realname[i]) = '\0'; return team_head; } TEAM_NODE * add_team_nodes (CONFIG_STRUCT *conf, SESSION *user) { P_NODE *p_head, *ptr; TEAM_NODE *team_head = 0; TEAM_NODE *t_ptr; int team_listed; p_head = build_option_person_list(conf); /* shared_person_list.c */ for(ptr=p_head; ptr; ptr=ptr->next) { for(t_ptr = team_head, team_listed=0; t_ptr && !team_listed; t_ptr=t_ptr->next) team_listed = (t_ptr->team == ptr->data.team); if (!team_listed) team_head = add_new_team (ptr->data.team, ptr->data.realname, team_head); else update_existing_team (ptr->data.team, ptr->data.realname, team_head); } free_option_person_list (p_head); /* shared_person_list.c */ return team_head; } static TEAM_NODE *update_team_count (char team, int msg_count, int unread_count, int flagged_count, TEAM_NODE *team_head) { TEAM_NODE *ptr; for (ptr = team_head; ptr && (ptr->team != team); ptr = ptr->next); if (!ptr) /*team has no current members */ { team_head = add_new_team(team, "", team_head); /* add the team */ for (ptr = team_head; ptr && (ptr->team != team); ptr = ptr->next); /* find this team again */ } if(ptr) /* this MUST be the case! */ { ptr->total_msgs+=msg_count; ptr->total_unread += unread_count; ptr->total_flagged += flagged_count; } return team_head; } TEAM_NODE * build_team_list (CONFIG_STRUCT *conf, SESSION *user) { MSG_TREE_NODE *ptr; int msg_count; int unread_count; int flagged_count; TEAM_NODE *team_head; time_t current_time; /* needed for call to build_msg_tree */ team_head = add_team_nodes (conf, user); /* in next 1-> show_all_team_teach, 0 = don't show teacher hidden */ build_msg_tree(user, TEAM_TEACH, 1, 0, ¤t_time); /* shared_news_util.c */ for(ptr=tree_head; ptr; ptr=ptr->next) /* for each topic in the tree */ { count_topic_msgs(ptr, &msg_count, &unread_count, &flagged_count); /* shared_news_util.c */ team_head = update_team_count (ptr->data.info.sender_team, msg_count, unread_count, flagged_count, team_head); } free_msg_tree(tree_head); /* shared_news_util.c */ return team_head; } static void free_team_list (TEAM_NODE *team_head) { TEAM_NODE *ptr; while (team_head) { ptr = team_head; team_head = team_head->next; free (ptr); } } static int record_cmp (TEAM_NODE * a, TEAM_NODE * b) { if ((a->team) < (b->team)) return -1; if ((a->team) > (b->team)) return 1; return 0; } static TEAM_NODE *sort_team_list (TEAM_NODE *team_head) { TEAM_NODE *q, *tail, *p, *r; if (team_head != NULL) { tail = team_head; while (tail->next) { q = tail->next; if (record_cmp (q, team_head) < 0) { tail->next = q->next; q->next = team_head; team_head = q; } else { r = team_head; p = r->next; while (record_cmp (q, p) > 0) { r = p; p = r->next; } if (q == p) tail = q; else { tail->next = q->next; q->next = p; r->next = q; } } } } return team_head; } void set_team_data (char *course, char *key, CONFIG_STRUCT *conf, SESSION *user) { #define MAX_TMP_NAME 30 TEAM_NODE *ptr; int i; int team_number = 0; TEAM_NODE *team_head; char name[MAX_TMP_NAME + 1]; char teamstring[20]; team_head = build_team_list (conf, user); team_head = sort_team_list(team_head); if (team_head) { for (team_number=0, ptr = team_head; ptr; ptr = ptr->next, team_number++) { snprintf(name, MAX_TMP_NAME, "team.%d.total_members",team_number); cs_set_int_value(name, ptr->total_members); snprintf(name, MAX_TMP_NAME, "team.%d.total_msgs",team_number); cs_set_int_value(name, ptr->total_msgs); snprintf(name, MAX_TMP_NAME, "team.%d.total_unread",team_number); cs_set_int_value(name, ptr->total_unread); snprintf(name, MAX_TMP_NAME, "team.%d.total_flagged",team_number); cs_set_int_value(name, ptr->total_flagged); snprintf(name, MAX_TMP_NAME, "team.%d.is_partial_member_list",team_number); cs_set_int_value(name, ptr->name_overflow); snprintf(name, MAX_TMP_NAME, "team.%d.team_name",team_number); get_team_name(ptr->team, teamstring); /* shared_teamstring.c */ cs_set_value(name, teamstring); snprintf(name, MAX_TMP_NAME, "team.%d.team_letter",team_number); snprintf(teamstring,3, "%c", ptr->team); cs_set_value(name, teamstring); for (i = 0; (i < MAX_NAME_LIST) && strlen (ptr->realname[i]); i++) { snprintf(name, MAX_TMP_NAME, "team.%d.member.%d", team_number, i); cs_set_value(name, ptr->realname[i]); } } free_team_list (team_head); } #undef MAX_TMP_NAME } static void set_team_list (char *course, char *key, CONFIG_STRUCT *conf, SESSION *user) { cs_set_value("crs", course); cs_set_value("id", key); cs_set_course_info(conf); cs_set_current_time(); set_main_menu_url (course, key); set_team_data (course, key, conf, user); } int main (void) { char course[MAX_PATH + 1]; /* from crs=? command line */ char key[MAX_KEY + 1]; /* from id=? command line */ SESSION user; CONFIG_STRUCT conf; /* the configuration read from config file */ cs_cgi_init(); read_parameters (course, key); 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_discussion_names (conf.course_path, user.username, TEAM_TEACH); /* shared_news_util.c */ set_team_list (course, key, &conf, &user); cs_cgi_display("news_team_list", 1); cs_cgi_destroy(); return 0; }