#include #include /** for stat() */ #include #include #include #include #include "ClearSilver.h" #include "global.h" #include "custom.h" #include "manhat-lib/shared_util.h" #include "manhat-lib/shared_news_util.h" #include "manhat-lib/shared_grades_util.h" #include "manhat-lib/shared_unread.h" #include "manhat-lib/shared_lock.h" #include "manhat-lib/shared_login.h" #include "manhat-lib/shared_person_list.h" #include "manhat-lib/shared_authenticate.h" #include "manhat-lib/shared_server_locked.h" #include "manhat-lib/shared_strtrm.h" #include "manhat-lib/shared_access.h" #include "manhat-lib/shared_cs_util.h" #include "manhat-lib/shared_file_util.h" #include "manhat-lib/shared_drop_add_list.h" #include "manhat-lib/shared_survey_take_verify.h" static int button_count (CONFIG_STRUCT *conf) { int button_count = 0; if (conf->assignments) button_count++; if (conf->syllabus) button_count++; if (conf->discussion) button_count++; if (!conf->template && conf->postoffice) button_count++; if (conf->internet) button_count++; if (!conf->template && conf->lounge) button_count++; if (!conf->template && conf->chat) button_count++; if (!conf->template && conf->anonymous) button_count++; if (!conf->template && conf->team) button_count++; if (!conf->template && conf->team_teach) button_count++; if (!conf->template && conf->grades) button_count++; if (conf->selftest) button_count++; if (conf->lectures) button_count++; if (conf->people) button_count++; if (conf->surveys) button_count++; if (conf->podcasts) button_count++; return button_count; } static void set_module_values(int unread, int count, int module, char *name, CONFIG_STRUCT *conf, SESSION *user, time_t current_time, const char *course, const char *key) { char node_name[MAX_PATH + 1]; char url[MAX_PATH + 1]; if(unread == -1) unread = unread_news (user, module, conf, current_time); /*shared_unread.c*/ snprintf(node_name, MAX_PATH + 1, "item.%d.module", count); cs_set_value( node_name, name); snprintf(node_name, MAX_PATH + 1, "item.%d.is_unread", count); cs_set_int_value(node_name, unread? 1 : 0); switch(module) { case CLASS_DISCUSSION: case STUDENT_LOUNGE: case ANONYMOUS_DISCUSSION: case TEAM_DISCUSSION: case HANDOUTS_NOTICES: case INTERNET_RESOURCES: case ASSIGNMENTS: case SELFTEST: case LECTURES: case PODCASTS: case SURVEYS: snprintf(url, MAX_PATH + 1, "%s?crs=%s&id=%s&grp=%d","news_topic", course, key,module); break; case TEAM_TEACH: if(user->group == FACULTY) snprintf(url, MAX_PATH + 1, "%s?crs=%s&id=%s","news_team_list", course, key); else snprintf(url, MAX_PATH + 1, "%s?crs=%s&id=%s&grp=%d","news_topic", course, key, module); break; case CHATTER: snprintf(url, MAX_PATH + 1, "%s?crs=%s&id=%s","chat_transcript", course, key); break; case MAIL: snprintf(url, MAX_PATH + 1, "%s?crs=%s&id=%s","post_inbox", course, key); break; case GRADES: if(user->group == FACULTY ) { if(conf->grades == 2 ) snprintf(url, MAX_PATH + 1,"%s?crs=%s&id=%s","grade_book", course, key); else snprintf(url, MAX_PATH + 1,"%s?crs=%s&id=%s","grades_fac_menu", course, key); } else { if(conf->grades == 1) snprintf(url, MAX_PATH + 1, "%s?crs=%s&id=%s","grades_view", course, key); else if(conf->grades == 3) snprintf(url, MAX_PATH + 1, "%s?crs=%s&id=%s","gradequick_view", course, key); else snprintf(url, MAX_PATH + 1, "%s?crs=%s&id=%s", "grade_book_std", course, key); } break; case PEOPLE: snprintf(url, MAX_PATH + 1," %s?crs=%s&id=%s","bio_list", course, key); break; default: snprintf(url, MAX_PATH + 1, "unknown module"); break; } snprintf(node_name, MAX_PATH + 1, "item.%d.url", count); cs_set_value(node_name, url); } static void insert_button (int feature, char *course, char *key, CONFIG_STRUCT *conf, SESSION *user, time_t current_time) { static int count = 0; char node_name[MAX_PATH + 1]; int unread; snprintf(node_name, MAX_PATH + 1, "item.%d.module", count); switch (feature) { case ASSIGNMENTS: set_module_values(-1, count, ASSIGNMENTS, "assign", conf, user, current_time, course, key); break; case LECTURES: set_module_values(-1, count, LECTURES, "lectures", conf, user, current_time, course, key); break; case HANDOUTS_NOTICES: set_module_values(-1, count, HANDOUTS_NOTICES, "handouts", conf, user, current_time, course, key); break; case INTERNET_RESOURCES: set_module_values(-1, count, INTERNET_RESOURCES, "inet", conf, user, current_time, course, key); break; case CLASS_DISCUSSION: set_module_values(-1, count, CLASS_DISCUSSION, "class", conf, user, current_time, course, key); break; case STUDENT_LOUNGE: set_module_values(-1, count, STUDENT_LOUNGE, "lounge", conf, user, current_time, course, key); break; case ANONYMOUS_DISCUSSION: set_module_values(-1, count, ANONYMOUS_DISCUSSION, "anon", conf, user, current_time, course, key); break; case TEAM_DISCUSSION: set_module_values(-1, count, TEAM_DISCUSSION, "team", conf, user, current_time, course, key); break; case TEAM_TEACH: set_module_values(-1, count, TEAM_TEACH, "teamteach", conf, user, current_time, course, key); break; case SELFTEST: set_module_values(-1, count, SELFTEST, "selftest", conf, user, current_time, course, key); break; case SURVEYS: set_module_values(-1, count, SURVEYS, "surveys", conf,user, current_time, course, key); break; case CHATTER: /* SHOW_REDSTAR_ON_CHAT_BUTTON is #defined in custom.h */ unread = SHOW_REDSTAR_ON_CHAT_BUTTON && non_empty_chatroom (); /* shared_unread.c */ set_module_values(unread, count, CHATTER, "chat", conf, user, current_time, course, key); break; case MAIL: unread = unread_mail (user->username, conf); /* shared_unread.c */ set_module_values(unread, count, MAIL, "post", conf, user, current_time, course, key); break; case GRADES: if (user->group==FACULTY) update_grades_inf (conf, user->username); /* shared_grades_util.c */ unread = unread_grades (user->username, conf); /* shared_unread.c */ set_module_values(unread, count, GRADES, "grades", conf, user, current_time, course, key); break; case PEOPLE: cs_set_value(node_name, "people"); set_module_values(0, count, PEOPLE, "people", conf, user, current_time, course, key); break; case PODCASTS: cs_set_value(node_name, "podcasts"); set_module_values(-1, count, PODCASTS, "podcasts", conf, user, current_time, course, key); break; default: break; } count++; } static void setup_main_menu (char *course_name, char *key, char *username, CONFIG_STRUCT *conf, SESSION *user) { time_t current_time; char url[MAX_PATH + 1]; current_time = time(NULL); cs_set_int_value("classroom_locked", CLASSROOM_LOCKED(conf->misc)? 1 : 0); cs_set_int_value ( "button_count", button_count(conf)); cs_set_course_info(conf); /* shared_cs_util.c */ cs_set_int_value( "is_faculty", user->group == FACULTY? 1 : 0); if (conf->assignments) insert_button (ASSIGNMENTS, course_name, key, conf, user, current_time); if (conf->lectures) insert_button (LECTURES, course_name, key, conf, user, current_time); if (conf->syllabus) insert_button (HANDOUTS_NOTICES, course_name, key, conf, user, current_time); if (conf->internet) insert_button (INTERNET_RESOURCES, course_name, key, conf, user, current_time); if (conf->selftest) insert_button (SELFTEST, course_name, key, conf, user, current_time); if (!conf->template && conf->chat) insert_button (CHATTER, course_name, key, conf, user, current_time); if (!conf->template && conf->postoffice) insert_button (MAIL, course_name, key, conf, user, current_time); if (conf->discussion) insert_button (CLASS_DISCUSSION, course_name, key, conf, user, current_time); if (!conf->template && conf->lounge) insert_button (STUDENT_LOUNGE, course_name, key, conf, user, current_time); if (!conf->template && conf->anonymous) insert_button (ANONYMOUS_DISCUSSION, course_name, key, conf, user, current_time); if (!conf->template && conf->team) insert_button (TEAM_DISCUSSION, course_name, key, conf, user, current_time); if (!conf->template && conf->team_teach) insert_button (TEAM_TEACH, course_name, key, conf, user, current_time); if (!conf->template && conf->grades) insert_button (GRADES, course_name, key, conf, user, current_time); if (!conf->template && conf->people) insert_button (PEOPLE, course_name, key, conf, user, current_time); if (!conf->template && conf->surveys) insert_button (SURVEYS, course_name, key, conf, user, current_time); if (conf->podcasts) insert_button (PODCASTS, course_name, key, conf, user, current_time); if( (user->group == FACULTY && ( ALLOW_TEACHER_CHANGE_PASSWORD && conf->access != ACCESS_CAPTURE)) || ALLOW_STUDENT_CHANGE_PASSWORD) snprintf(url, MAX_PATH + 1, "%s?crs=%s&id=%s", "passwd_form", course_name, key); else *url = '\0'; cs_set_value("change_password_url", url); if(conf->access == ACCESS_CAPTURE) *url = '\0'; else snprintf(url, MAX_PATH + 1, "%s?crs=%s&id=%s", "logout", course_name, key); cs_set_value("exit_url", url); if(user->group == FACULTY) snprintf(url, MAX_PATH + 1, "%s?crs=%s&id=%s", "admin_main_menu", course_name, key); else *url = '\0'; cs_set_value("config_url", url); snprintf(url, MAX_PATH + 1, "%s?crs=%s&id=%s", "calendar", course_name, key); cs_set_value("calendar_url", url); } static void read_parameters (char *course, char *key) { cs_get_required_parameter("crs", course, MAX_PATH); /* shared_cs_util.c */ cs_get_required_parameter("id", key, MAX_KEY); /* shared_cs_util.c */ } static void empty_classroom_message () { cs_critical_error(ERR_NO_MODULES_SELECTED, ""); /* shared_cs_util.c */ } static int course_listed(const char *username, const char *course, char dir) { #define MAX_LINE 200 char course_file[MAX_PATH + 1]; FILE *fp; int fd; char line[MAX_LINE]; int found = 0; snprintf(course_file, MAX_PATH + 1, "../%s/%c/%s/%s", USERS_DIR, dir, username,COURSE_LIST_FNAME); fp = fopen(course_file, "r"); if(!fp) return 0; fd = fileno(fp); get_shared_lock(fd, 1); /* shared_lock.c */ while(fgets(line,MAX_LINE,fp) && !found) { strtrm(line); /* shared_strtrm.c */ found = !strcmp(line,course); } release_lock(fd); /* shared_lock.c */ fclose(fp); return found; #undef MAX_LINE } static void course_login(SESSION *user, const char *course, const char *keypath, CONFIG_STRUCT *conf) { FILE *fp; if(!get_user_info ( user->username, user, conf)) /* shared_person_list.c */ cs_critical_error (ERR_REQUEST_DENIED, "course_login()"); /* shared_cs_util.c */ remove_stale_symlinks (user->username, course, conf->access); /* shared_news_util.c */ // kill_hotpotato_directory(username, &(course_ptr->conf)); /* shared_potato_util.c */ /** write the course specific SESSION info for this user *** to a file named course.key in the user's central directory **/ fp = fopen(keypath, "w"); if(!fp) cs_critical_error(ERR_FOPEN_WRITE_FAILED, keypath); /* shared_cs_util.c */ if(fwrite(user, sizeof(SESSION), 1, fp) != 1) cs_critical_error(ERR_FWRITE_FAILED, keypath); /* shared_cs_util.c */ fclose(fp); log_this_access (user->username, conf->course_path,PEOPLE_DIR); /* shared_login.c */ } static void validate_key_login(const char *key, SESSION *user, const char *course, CONFIG_STRUCT *conf) { char dir; FILE *fp; char keypath[MAX_PATH + 1]; char modified_course[MAX_PATH + 1]; validate_server_key (key, user); /* shared_util.c */ dir = sub_dir_name(user->username); /* shared_authenticate.c */ course_slash_to_dot(course, modified_course); /* shared_util.c */ snprintf(keypath, MAX_PATH + 1, "../%s/%c/%s/%s%s", USERS_DIR, dir, user->username, modified_course,KEY_FILE_EXTENSION); /* try to read the session file */ fp = fopen(keypath, "r"); if(fp) { if(fread(user,sizeof(SESSION), 1, fp) != 1) cs_critical_error (ERR_LOGGED_OUT, ""); /* shared_cs_util.c */ fclose(fp); } else /* session file isn't there - try to log the user in */ { if(!course_listed(user->username, course, dir)) cs_critical_error (ERR_REQUEST_DENIED, ""); /* shared_cs_util.c */ course_login(user,course, keypath, conf); } } int has_add_drop_list(CONFIG_STRUCT *conf) { char path[MAX_PATH +1]; char dummy[MAX_PATH +1]; P_NODE *head; P_NODE *drop_head, *ptr; int count = 0; snprintf(path, MAX_PATH + 1, "%s%s", conf->course_path, ADD_LIST_FNAME); if(file_exists(path)) /* shared_file_util.c */ return 1; snprintf(path, MAX_PATH + 1, "%s%s", conf->course_path, DROP_LIST_FNAME); if(file_exists(path)) /* shared_file_util.c */ { drop_head =build_drop_person_list (path, dummy,MAX_PATH +1); head = build_option_person_list(conf); for(ptr = drop_head; ptr; ptr = ptr->next) { if(find_student_in_passwd(head, ptr)) count++; } free_option_person_list(drop_head); free_option_person_list(head); if(count == 0) { unlink(path); return 0; } return 1; } return 0; } int has_required_survey(CONFIG_STRUCT *conf, SESSION *user, long *offset) { time_t current_time; MSG_TREE_NODE *ptr; int found = 0; *offset = -1; if( (user->group != STUDENT) || !(conf->surveys)) return 0; set_discussion_names (conf->course_path, user->username, SURVEYS); /* shared_news_util.c */ build_msg_tree(user,SURVEYS,0,0, ¤t_time); /* shared_news_util.c */ if(tree_head) { for(ptr = tree_head, found = 0; ptr && !found; ptr = ptr->next) { found = !ptr->user_data.time_read && (BASIC_STATUS(ptr->data.status) != READ_ONLY) && is_unanswered_required_survey(conf, ptr->data.info.sender, ptr->data.info_fname, user); /* shared_survey_take_verify.c */ if(found) *offset = ptr->offset; } free_msg_tree(tree_head); } return found? 1 : 0; } static void setup_required_survey_page(const char *course, const char *key, long survey_offset, CONFIG_STRUCT *conf) { char url[MAX_PATH + 1]; cs_set_course_info(conf); /* shared_cs_util.c */ snprintf (url, MAX_PATH + 1, "%s?crs=%s&id=%s&loc=%ld&grp=%d\n\n", "news_read", course, key,survey_offset, SURVEYS); cs_set_value("take_survey_url", url); if(conf->access == ACCESS_CAPTURE) *url = '\0'; else snprintf(url, MAX_PATH + 1, "%s?crs=%s&id=%s", "logout", course, key); cs_set_value("exit_url", url); } int main () { 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 */ int add_drop = 0; long offset =0; cs_cgi_init(); /* shared_cs_util.c */ read_parameters (course, key); read_configuration_file(course, &conf); /* shared_util.c */ cs_set_course_info(&conf); /* shared_cs_util.c */ if(!conf.standalone) validate_key_login(key, &user, course, &conf); else validate_key (key, &user, &conf); /* shared_util.c */ if(conf.standalone) check_lockout (key, conf.course_path); /* shared_server_locked.c has system been shut down? */ else central_user_check_lockout(key); /* shared_server_locked.c */ has_write_permission(&user, &conf); /* shared_access.c */ if(user.group == FACULTY) add_drop = has_add_drop_list(&conf); else { if(CLASSROOM_LOCKED(conf.misc)) empty_classroom_message(); } if (!modules_enabled (&conf)) /* shared_news_util.c */ { if (user.group == FACULTY) printf ("Location:%s?crs=%s&id=%s&first=1\n\n", "admin_module_form", course, key); else empty_classroom_message (); } else if(add_drop) printf ("Location:%s?crs=%s&id=%s\n\n", "show_add_drop", course, key); else if (only_handouts_enabled (&conf)) /* shared_news_util.c */ printf ("Location:%s?crs=%s&id=%s&grp=%d\n\n", "news_topic", course, key, HANDOUTS_NOTICES); else if ((user.group == STUDENT) && conf.surveys && has_required_survey(&conf, &user, &offset)) { setup_required_survey_page(course, key, offset, &conf); cs_cgi_display ("main_menu_required_survey", 1); /* shared_cs_util.c */ } else { setup_main_menu (course, key, user.username, &conf, &user); cs_cgi_display ("main_menu", 1); /* shared_cs_util.c */ } cs_cgi_destroy(); /* shared_cs_util.c */ return 0; }