#include "shared_xml_course_create_util.h" static USER_NODE * find_all_teachers(XML_COURSE_INFO *info) { USER_NODE *head =0, *ptr, *current=0; for(info->user_current = info->user_head; info->user_current; info->user_current=info->user_current->next) { if(info->user_current->data.group == FACULTY) { ptr = (USER_NODE*)malloc(sizeof(USER_NODE)); if(!ptr) cs_critical_error(ERR_MALLOC_FAILED, ""); ptr->next = 0; strncpy(ptr->user.first, info->user_current->data.realname, MAX_NAME + 1); strncpy(ptr->user.last, info->user_current->data.lastname, MAX_NAME + 1); strncpy(ptr->user.id, info->user_current->data.id, MAX_ID +1); strncpy(ptr->user.username, info->user_current->data.username, MAX_USERNAME +1); ptr->user.group = FACULTY; ptr->user.central_state = UN_CHANGE; /* assume this to start */ if(!head) head = ptr; else current->next = ptr; current = ptr; } } return head; } static USER_NODE * find_all_users_in_standalone(XML_COURSE_INFO *info) { USER_NODE *head =0, *ptr, *current=0; for(info->user_current = info->user_head; info->user_current; info->user_current=info->user_current->next) { ptr = (USER_NODE*)malloc(sizeof(USER_NODE)); if(!ptr) cs_critical_error(ERR_MALLOC_FAILED, ""); ptr->next =0; strncpy(ptr->user.first, info->user_current->data.realname, MAX_NAME +1); strncpy(ptr->user.last, info->user_current->data.lastname, MAX_NAME +1); strncpy(ptr->user.id, info->user_current->data.id, MAX_ID +1); strncpy(ptr->user.username, info->user_current->data.username, MAX_USERNAME +1); ptr->user.group = info->user_current->data.group; ptr->user.central_state = UN_CHANGE; if(!head) head = ptr; else current->next = ptr; current = ptr; } return head; } static USER_GROUP_INFO * find_exist_users(USER_GROUP_INFO_LIST *list, P_NODE* info) { USER_GROUP_INFO *ptr; for(ptr=list->head; ptr; ptr = ptr->next) { if(strcmp(ptr->user.id, info->data.id) ==0) return ptr; } return 0; } static USER_GROUP_INFO_LIST * process_one_course(USER_GROUP_INFO_LIST *list, XML_COURSE_INFO *info) { USER_GROUP_INFO *ptr, *find; /* for each user in the course */ for(info->user_current=info->user_head; info->user_current; info->user_current=info->user_current->next) { if(info->user_current->data.group != FACULTY) { find = find_exist_users(list, info->user_current); if(!find) { ptr = (USER_GROUP_INFO*)malloc(sizeof(USER_GROUP_INFO)); strncpy(ptr->user.first, info->user_current->data.realname,MAX_NAME +1); strncpy(ptr->user.last, info->user_current->data.lastname,MAX_NAME +1); strncpy(ptr->user.id, info->user_current->data.id,MAX_ID +1); if(strlen(info->user_current->data.username)>0) strncpy(ptr->user.username, info->user_current->data.username,MAX_USERNAME +1); else ptr->user.username[0]='\0'; ptr->user.is_new =NEW; ptr->user.central_state =UN_CHANGE; ptr->user.group=info->user_current->data.group; ptr->next =0; /** add a new course for this user */ ptr->head = (COURSE_GROUP*)malloc(sizeof(COURSE_GROUP)); ptr->current = ptr->head; ptr->head->next =0; strncpy(ptr->head->course_subdir, info->subdir, MAX_COURSE_SUBDIR +1); //strncpy(ptr->head->course_dir, info->dir_id, MAX_COURSE_NO +1); strncpy(ptr->head->course_dir, info->real_dir_id, MAX_COURSE_NO +1); ptr->head->course_type = info->course_type; ptr->head->group=info->user_current->data.group; if(!list->head) list->head = ptr; else list->current->next = ptr; list->current = ptr; } else /* user was already listed */ { find->user.central_state =UN_CHANGE; find->current->next=(COURSE_GROUP*)malloc(sizeof(COURSE_GROUP)); find->current = find->current->next; strncpy(find->current->course_subdir, info->subdir, MAX_COURSE_NO +1); //strncpy(find->current->course_dir, info->dir_id, MAX_COURSE_NO +1); strncpy(find->current->course_dir, info->real_dir_id, MAX_COURSE_NO +1); find->current->course_type = info->course_type; find->current->group = info->user_current->data.group; find->current->next =0; } } } return list; } USER_GROUP_INFO_LIST * build_user_list(XML_COURSE_INFO_LIST *list) { USER_GROUP_INFO_LIST *head; /* start with an empty user list */ head = (USER_GROUP_INFO_LIST *)malloc(sizeof(USER_GROUP_INFO_LIST)); if(!head) cs_critical_error(ERR_MALLOC_FAILED, "build_user_list"); head->head =0; head->current =0; /* for each course */ for(list->current=list->head; list->current; list->current = list->current->next) { if(list->current->course_type != STANDALONE) head = process_one_course(head, list->current); } return head; } /* start list with normal and template courses ** and only teacher info */ CREATED_COURSE_NODE* build_normal_template_course_list(XML_COURSE_INFO_LIST *list) { USER_NODE *teacher_head; char error[300]; CREATED_COURSE_NODE *head = 0, *ptr, *current = 0; get_lang_string(&hdf); for(list->current=list->head; list->current; list->current = list->current->next) { /* if NOT Standalone course */ if(list->current->course_type != STANDALONE && list->current->course_type != -1) { teacher_head = find_all_teachers(list->current); if(!teacher_head) { snprintf(error, 300, "%s %s", list->current->course_code, list->current->title); cs_critical_error(ERR_COURSE_X_Y_HAS_NO_TEACHER, error); } ptr = (CREATED_COURSE_NODE *)malloc(sizeof(CREATED_COURSE_NODE)); if(!ptr) cs_critical_error(ERR_MALLOC_FAILED, "build_temp"); strncpy(ptr->course_subdir, list->current->subdir, MAX_COURSE_SUBDIR + 1); strncpy(ptr->course_dir, list->current->real_dir_id, MAX_COURSE_ID +1); strncpy(ptr->org_id, list->current->dir_id, MAX_COURSE_ID +1); strncpy(ptr->course_no, list->current->course_code, MAX_COURSE_NO +1); strncpy(ptr->course_title, list->current->title, MAX_COURSE_TITLE +1); strncpy(ptr->instructor_title, list->current->instructor_title, MAX_INSTRUCTOR +1); ptr->course_type = list->current->course_type; /* change semester to a standard value for course templates */ if(list->current->course_type == TEMPLATE) strncpy(ptr->course_semester, hdf_get_value(hdf, "course_create_temp", ""), MAX_SEMESTER + 1); else strncpy(ptr->course_semester, list->current->semester, MAX_SEMESTER + 1); ptr->next = 0; ptr->head = teacher_head; ptr->add_head = 0; ptr->add_current = 0; if(!head) head = ptr; else current-> next = ptr; current = ptr; } } hdf_destroy(&hdf); return head; } static int find_this_username(USER_NODE *all, const char *username) { USER_NODE *ptr; for(ptr = all; ptr; ptr = ptr->next) { if(strlen(ptr->user.username) > 0 && strcmp(ptr->user.username, username) ==0) return 1; } return 0; } static void process_standalone_username(USER_NODE *one, USER_NODE *all) { char username[MAX_USERNAME +1]; int try; one->user.is_new = NEW; /* assume this to start */ if(!strlen(one->user.username)) /* if username wasn't supplied in XML file */ { derive_username (one->user.first, one->user.last, one->user.id, username, MAX_USERNAME+1); for(try = 1; (try <= MAX_USERNAME_TRIES) && (find_this_username(all, username)); try++) { derive_another_username(one->user.first, one->user.last, one->user.id, username, MAX_USERNAME + 1, try); } if(try > MAX_USERNAME_TRIES) one->user.is_new = ERROR_UID; } else /* username was supplied in XML file */ { strncpy(username, one->user.username, MAX_USERNAME + 1); *(username + MAX_USERNAME) = '\0'; } if(one->user.is_new != ERROR_UID) { one->user.is_new = NEW; strncpy(one->user.username, username, MAX_USERNAME + 1); derive_password (one->user.username, one->user.first,one->user.last, one->user.id, one->user.password, MAX_PASSWORD +1); /* shared_authenticate.c */ } } static USER_NODE * find_teacher_in_course_head(USER_NODE *head, const char *id) { USER_NODE *ptr; for(ptr = head; ptr; ptr = ptr->next) { if(strcmp(ptr->user.id, id) ==0) return ptr; } return 0; } void update_standalone_username(CREATED_COURSE_NODE *sta_list) { CREATED_COURSE_NODE *ptr; USER_NODE *t_node, *t_ptr; for(ptr = sta_list; ptr; ptr = ptr->next) { for(t_node = ptr->add_head; t_node; t_node = t_node->next) { process_standalone_username(t_node, ptr->add_head); if(t_node->user.group == FACULTY) { t_ptr =find_teacher_in_course_head(ptr->head, t_node->user.id); if(t_ptr) { strncpy(t_ptr->user.username, t_node->user.username, MAX_USERNAME +1); strncpy(t_ptr->user.password, t_node->user.password, MAX_PASSWORD +1); t_ptr->user.is_new = t_node->user.is_new; } } } } } /* build list of standalone courses with teachers and students */ CREATED_COURSE_NODE * standalone_course_list(XML_COURSE_INFO_LIST *list) { CREATED_COURSE_NODE *head =0, *ptr, *current=0; for(list->current=list->head; list->current; list->current = list->current->next) { if(list->current->course_type == STANDALONE) { ptr = (CREATED_COURSE_NODE *)malloc(sizeof(CREATED_COURSE_NODE)); strncpy(ptr->course_subdir, list->current->subdir, MAX_COURSE_SUBDIR +1); strncpy(ptr->course_dir, list->current->real_dir_id, MAX_COURSE_ID +1); strncpy(ptr->org_id, list->current->dir_id, MAX_COURSE_ID +1); snprintf(ptr->course_path, MAX_PATH + 1, "%s%s/%s", COURSE_PATH, ptr->course_subdir, ptr->course_dir); strncpy(ptr->course_no, list->current->course_code, MAX_COURSE_NO +1); strncpy(ptr->course_title, list->current->title, MAX_COURSE_TITLE +1); strncpy(ptr->instructor_title, list->current->instructor_title, MAX_INSTRUCTOR +1); ptr->course_type = list->current->course_type; strncpy(ptr->course_semester, list->current->semester, MAX_SEMESTER +1); ptr->next = 0; ptr->head = find_all_teachers(list->current); ptr->add_head =find_all_users_in_standalone(list->current); ptr->add_current = ptr->add_head; if(!head) head = ptr; else current->next = ptr; current = ptr; } } return head; } void set_course_table(CREATED_COURSE_NODE *head, const char *prefix) { #define MAX_TMP_NAME 50 CREATED_COURSE_NODE *ptr; USER_NODE *t_node; int course_count =0; int people_count, i =0; char name[MAX_TMP_NAME]; for(ptr = head; ptr; ptr = ptr->next) { snprintf(name, MAX_TMP_NAME, "%s.%d.type", prefix, i); cs_set_int_value(name, ptr->course_type); snprintf(name, MAX_TMP_NAME, "%s.%d.course_subdir", prefix , i); cs_set_value(name, ptr->course_subdir); snprintf(name, MAX_TMP_NAME, "%s.%d.course_dir", prefix , i); cs_set_value(name, ptr->course_dir); snprintf(name, MAX_TMP_NAME, "%s.%d.course_no", prefix , i); cs_set_value(name, ptr->course_no); snprintf(name, MAX_TMP_NAME, "%s.%d.course_title", prefix , i); cs_set_value(name, ptr->course_title); snprintf(name, MAX_TMP_NAME, "%s.%d.course_semester", prefix , i); cs_set_value(name, ptr->course_semester); snprintf(name, MAX_TMP_NAME, "%s.%d.exists", prefix , i); cs_set_int_value(name, ptr->exists); snprintf(name, MAX_TMP_NAME, "%s.%d.t_state", prefix , i); cs_set_int_value(name, ptr->t_state); course_count++; people_count =0; for(t_node = ptr->add_head; t_node; t_node = t_node->next) { if(strcmp(t_node->user.password, "drop") != 0) { snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.is_new", prefix , i, people_count); cs_set_int_value(name, t_node->user.is_new); snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.first", prefix , i, people_count); cs_set_value(name, t_node->user.first); snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.last", prefix , i, people_count); cs_set_value(name, t_node->user.last); snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.id", prefix , i, people_count); cs_set_value(name, t_node->user.id); snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.username", prefix , i, people_count); cs_set_value(name, t_node->user.username); snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.group", prefix , i, people_count); cs_set_int_value(name, t_node->user.group); snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.add_state", prefix , i, people_count); cs_set_int_value(name, t_node->user.add_state); if(ptr->course_type != STANDALONE) { snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.central_state", prefix , i, people_count); cs_set_int_value(name, t_node->user.central_state); } people_count++ ; } } snprintf(name, MAX_TMP_NAME, "%s.%d.total_users", prefix , i); cs_set_int_value(name, people_count); i++; } if(!strcmp(prefix, "ctr")) cs_set_int_value("ctr_total", course_count); else cs_set_int_value("std_total", course_count); #undef MAX_TMP_NAME } static DIRECTORY_NAME_NODE * build_directory_name_list( int course_count, int *standalone) { int i; char name[MAX_FILENAME + 1]; char tmp[20 + 1], *str =0; DIRECTORY_NAME_NODE *head = 0, *ptr, *current = 0; for(i=1; i <= course_count; i++) { snprintf(name, MAX_FILENAME + 1, "Query.c%d_orig_id", i); str = hdf_get_value(global_cgi->hdf, name, 0); if(str) { /* allocate new node */ ptr = (DIRECTORY_NAME_NODE *)malloc(sizeof(DIRECTORY_NAME_NODE)); if(!ptr) cs_critical_error(ERR_MALLOC_FAILED, ""); ptr->next = 0; /* store original internal name as it appears in the ** XML file */ snprintf(name, MAX_FILENAME + 1, "c%d_orig_id", i); cs_get_required_parameter(name, ptr->name, MAX_COURSE_NO); /* shared_cgi_util.c */ /* store new internal name, as modified by user */ snprintf(name, MAX_FILENAME + 1, "c%d_new_id", i); cs_get_required_parameter(name, ptr->dir_id, MAX_COURSE_ID); /* shared_cgi_util.c */ /* store new subdirectory name, as modified by user */ snprintf(name, MAX_FILENAME + 1, "c%d_subdir_or", i); cs_get_required_parameter(name, ptr->subdir, MAX_COURSE_SUBDIR); /* shared_cgi_util.c */ snprintf(name, MAX_FILENAME + 1, "c%d_subdir", i); cs_get_required_parameter(name, ptr->modified_subdir, MAX_COURSE_SUBDIR); /* shared_cgi_util.c */ /* store course type "Standalone", "Normal" or "Template" */ snprintf(name, MAX_FILENAME + 1, "c%d_type", i); cs_get_required_parameter(name,tmp,20); ptr->course_type = !strcmp(tmp,"Standalone")? STANDALONE: (!strcmp(tmp, "Template"))? TEMPLATE: CENTRAL; /* *standalone gets set if one or more courses is "Standalone" */ if(ptr->course_type == STANDALONE) *standalone = 1; if(!head) head = ptr; else current->next = ptr; current = ptr; } } return head; } DIRECTORY_NAME_NODE * get_parameters(char *key, int *standalone, char *roster_path) { DIRECTORY_NAME_NODE *head; char tmp[20 + 1]; int course_count; cs_get_required_parameter ("id", key, MAX_KEY); /* shared_cs_util.c */ cs_get_required_parameter ("count", tmp, 20); course_count = atoi(tmp); cs_get_required_parameter ("roster_path", roster_path, MAX_PATH); head = build_directory_name_list( course_count, standalone); if(!head) cs_critical_error(ERR_PARAM_MISSING, "course parameters"); return head; } void free_directory_name_list(DIRECTORY_NAME_NODE *head) { DIRECTORY_NAME_NODE *ptr; while(head) { ptr = head->next; free(head); head = ptr; } } void check_invalid_chars(const char *string) { const char *cptr; char msg[200]; /* check for invalid characters */ for(cptr = string; *cptr; cptr++) { if((*cptr != '_') && !isdigit(*cptr) && !isalpha(*cptr)) { snprintf(msg, 200, string); cs_critical_error(ERR_COURSE_X_HAS_INVALID_CHARS, msg); } } } /* assumes strings have been trimmed ** in read_parameters() */ void check_internal_course_names(XML_COURSE_INFO_LIST *list) { for(list->current=list->head; list->current; list->current=list->current->next) { if(!strlen(list->current->dir_id) || !strlen(list->current->subdir) ) cs_critical_error(ERR_COURSE_NAMES_EMPTY, ""); /* Central or Standalone Course subdir names can't start with a 'T' */ if( (list->current->course_type == CENTRAL) || (list->current->course_type == STANDALONE)) { if(*(list->current->subdir) == 'T') cs_critical_error(ERR_COURSE_CANT_START_WITH_T, ""); } check_invalid_chars(list->current->dir_id); check_invalid_chars(list->current->subdir); } /* for each course ... */ } /* parses the xml file into a linked list of ** course nodes */ XML_COURSE_INFO_LIST * parse_xml_file(const char *xml_file_path) { char msg[200]; XML_COURSE_INFO_LIST *list; /* shared_roster_xml_parser.h */ FILE *fp; struct stat file_stat; char *buf; if(stat(xml_file_path, &file_stat)) { snprintf(msg,200, xml_file_path); cs_critical_error(ERR_FILE_X_NOT_FOUND, msg); } buf = (char*)malloc( (file_stat.st_size + 1) * sizeof(char)); /* allocate an additional byte for terminating NULL */ if(!buf) cs_critical_error(ERR_MALLOC_FAILED, ""); fp = fopen(xml_file_path, "r"); if(!fp) cs_critical_error(ERR_FOPEN_READ_FAILED, xml_file_path); if(fread(buf, file_stat.st_size, 1, fp) != 1) cs_critical_error(ERR_FREAD_FAILED, ""); fclose(fp); *(buf + file_stat.st_size) = '\0'; /* null terminate the buf string */ list = xml_course_data_parser(buf); /*shared_roster_xml_parser.c */ free(buf); return list; } /** adds correct internal name and course type to *** the master course list **/ void update_xml_info_list(XML_COURSE_INFO_LIST *list, DIRECTORY_NAME_NODE *modified_head) { DIRECTORY_NAME_NODE *modified_ptr = 0; char dir[MAX_COURSE_ID + 1]; // char error_msg[200]; if(list->head && modified_head) { for(list->current=list->head; list->current; list->current=list->current->next) { /* find this course name in the user-supplied list */ for(modified_ptr = modified_head; modified_ptr; modified_ptr=modified_ptr->next) if(!strcmp(modified_ptr->name, list->current->dir_id) && !strcmp(list->current->subdir , modified_ptr->subdir)) break; if(modified_ptr) { /* if a course is a Template, must force first char to be an uppercase 'T' */ if( (modified_ptr->course_type == TEMPLATE) && *(modified_ptr->dir_id) !='T') { /* if course name is already at it's maximum length, strip one char from end */ if(strlen(modified_ptr->dir_id) == MAX_COURSE_ID) *(modified_ptr->dir_id + MAX_COURSE_ID - 1) = '\0'; snprintf(dir, MAX_COURSE_ID + 1, "%s%s","T", modified_ptr->dir_id); strncpy(modified_ptr->dir_id, dir, MAX_COURSE_ID + 1); } list->current->course_type = modified_ptr->course_type; //strncpy(list->current->dir_id, modified_ptr->dir_id, MAX_COURSE_ID + 1); strncpy(list->current->real_dir_id, modified_ptr->dir_id, MAX_COURSE_ID + 1); *(list->current->real_dir_id + MAX_COURSE_ID) = '\0'; strncpy(list->current->subdir, modified_ptr->modified_subdir, MAX_COURSE_SUBDIR + 1); *(list->current->subdir + MAX_COURSE_SUBDIR) = '\0'; } else { list->current->course_type = -1; //snprintf(error_msg, 200, list->current->dir_id); //cs_critical_error(ERR_DATA_FOR_X_NOT_FOUND, error_msg); } } /* for each course found in the XML file */ } else cs_critical_error(ERR_NO_DATA_FOUND, ""); } void free_teacher_node(USER_NODE *t_head) { USER_NODE *ptr; while(t_head) { ptr = t_head->next; free(t_head); t_head = ptr; } } void free_course_f_list(CREATED_COURSE_NODE *head) { CREATED_COURSE_NODE *ptr; while(head) { ptr = head->next; if(head->head) free_teacher_node(head->head); if(head->add_head) free_teacher_node(head->add_head); free(head); head = ptr; } } void free_course_group(COURSE_GROUP *head) { COURSE_GROUP *ptr; while(head) { ptr = head->next; free(head); head = ptr; } } void free_user_group_info_list(USER_GROUP_INFO_LIST *list) { USER_GROUP_INFO *ptr; while(list->head) { ptr = list->head->next; if(list->head->head) free_course_group(list->head->head); free(list->head); list->head = ptr; } free(list); } static INDEX_USER * find_this_user_from_index(INDEX_USER_LIST *list, USER *node) { INDEX_USER *ptr; for(ptr = list->head; ptr;ptr = ptr->next) { if(strcmp(ptr->id, node->id) ==0) return ptr; } return 0; } static int username_exist(INDEX_USER_LIST *index_list, const char *username) { INDEX_USER *ptr; for(ptr = index_list->head; ptr; ptr = ptr->next) { if(strcmp(ptr->username, username) ==0) return 1; } return 0; } INDEX_USER_LIST * process_one_username(USER *ptr, INDEX_USER_LIST *index_list) { INDEX_USER *a_user; char realname[MAX_NAME +1]; char username[MAX_USERNAME +1]; int try; ptr->is_new = NEW ; /* assume this to start */ a_user = find_this_user_from_index(index_list, ptr); if(!a_user) { if(!strlen(ptr->username)) /* if username wasn't supplied in XML file */ { derive_username (ptr->first, ptr->last, ptr->id, username, MAX_USERNAME+1); /* shared_authenticate.c */ for(try = 1; (try <= MAX_USERNAME_TRIES) && ( username_invalid(username) /* shared_authenticate.c */ || username_exist (index_list, username ) ); try++) { derive_another_username(ptr->first, ptr->last, ptr->id, username, MAX_USERNAME + 1, try); /* shared_authenticate.c */ } if(try > MAX_USERNAME_TRIES) ptr->is_new = ERROR_UID; /* couldn't derive username */ } else /* a username was supplied in the XML file */ { strncpy(username, ptr->username, MAX_USERNAME + 1); *(username + MAX_USERNAME) = '\0'; strtrm(username); /* shared_strtrm.c */ if(username_invalid(username) /* shared_authenticate.c */ || username_exist(index_list, username)) ptr->is_new = ERROR_UID; } if(ptr->is_new != ERROR_UID) { ptr->is_new = NEW; strncpy(ptr->username, username, MAX_USERNAME + 1); derive_password (ptr->username, ptr->first,ptr->last,ptr->id, ptr->password, MAX_PASSWORD +1); /* shared_authenticate.c */ snprintf(realname, MAX_NAME+1, "%s %s", ptr->first,ptr->last); index_list = add_to_index_list(index_list, ptr->username, ptr->id, realname); /* shared_user_index.c */ } } else /* person already has a central account */ { strncpy(ptr->username, a_user->username, MAX_USERNAME +1); derive_password (ptr->username, ptr->first,ptr->last,ptr->id, ptr->password, MAX_PASSWORD +1); /* shared_authenticate.c */ snprintf(realname, MAX_NAME+1, "%s %s", ptr->first,ptr->last); if(strcmp(realname, a_user->realname) == 0) ptr->is_new = EXISTS; else { /* copy correct real name into first, last fields */ get_first_last_names(a_user->realname, ptr->first, ptr->last); /* shared_authenticate.c */ ptr->is_new = ERROR_NAME; /* user exists, but they had a different real name on Manhattan */ } } return index_list; } INDEX_USER_LIST * derive_teacher_username_password(CREATED_COURSE_NODE *course_head, INDEX_USER_LIST *index_list) { CREATED_COURSE_NODE *course; USER_NODE *ptr; for(course = course_head; course; course = course->next) { for(ptr = course->head; ptr; ptr = ptr->next) index_list = process_one_username(&(ptr->user), index_list); } return index_list; } INDEX_USER_LIST * derive_student_username_password(USER_GROUP_INFO_LIST *user_list, INDEX_USER_LIST *index_list) { for(user_list->current = user_list->head; user_list->current; user_list->current = user_list->current->next) { index_list = process_one_username (&(user_list->current->user), index_list); } return index_list; } static int write_org_info(CREATED_COURSE_NODE *course) { char org_id_file[MAX_PATH +1]; FILE *fp; snprintf(org_id_file, MAX_PATH +1, "%s/%s", course->course_path, "org_id.txt"); fp = fopen(org_id_file, "w"); if(!fp) return 1; fprintf(fp, "%s\n", course->org_id); fclose(fp); return 0; } static int create_course_dir(CREATED_COURSE_NODE *course) { char path[MAX_PATH + 1]; /* create subdir, if necessary */ snprintf(path, MAX_PATH + 1, "%s%s", course->course_type == TEMPLATE? TEMPLATE_PATH : COURSE_PATH, course->course_subdir); if(!file_exists(path)) { if(mkdir (path, 0777)) return 0; } if(mkdir(course->course_path, 0777)) return 0; return 1; } static void get_config_default_value(CREATED_COURSE_NODE *course, CONFIG_STRUCT *conf) { char professor[MAX_INSTRUCTOR +1]; strncpy(conf->course_no, course->course_no, MAX_COURSE_NO+1); strncpy(conf->title, course->course_title, MAX_COURSE_TITLE+1); strncpy(conf->semester, course->course_semester, MAX_SEMESTER+1); if(strlen(course->instructor_title)) snprintf(professor, MAX_INSTRUCTOR +1, "%s", course->instructor_title); else snprintf(professor, MAX_INSTRUCTOR +1, "%s %s", "Prof.", course->head->user.last); strncpy(conf->instructor, professor, MAX_INSTRUCTOR +1); conf->login_expire = 0; conf -> key_expire = MAX_KEY_EXPIRE; conf -> mail_attachments = MAX_ATTACHMENTS; conf -> assignments = 0; conf -> syllabus = 0; conf -> discussion = 0; conf -> postoffice = 0; conf -> internet = 0; conf -> lounge = 0; conf -> chat = 0; conf -> anonymous = 0; conf -> team = 0; conf -> team_teach = 0; conf -> grades = 0; conf -> selftest = 0; conf -> lectures = 0; conf -> people = 0; conf -> surveys = 0; conf->access = ACCESS_ALL; /*Full access for teachers and students */ conf ->standalone = (course->course_type == STANDALONE)? 1 : 0; conf -> template = (course->course_type == TEMPLATE)? 1 : 0; conf->misc = 0; conf->podcasts = 0; conf->future6 = 0; conf->theme = 0; } static int write_config_file(const char *course, CONFIG_STRUCT *conf) { FILE *fp; char file_path[MAX_PATH +1]; snprintf(file_path, MAX_PATH +1, "%s/%s", course, CONFIG_FNAME); fp = fopen(file_path,"w"); if(!fp) return 0; if(fwrite(conf, sizeof(CONFIG_STRUCT), 1, fp) != 1) { fclose(fp); return 0; } fclose(fp); return 1; } static int create_inboxes_directory (const char *crs ) { char path[MAX_PATH + 1]; snprintf (path, MAX_PATH + 1, "%s/%s", crs, INBOXES_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s/%s", crs, INBOXES_DIR ,ANONYMOUS_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s/%s", crs, INBOXES_DIR, ASSIGNMENTS_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s/%s", crs, INBOXES_DIR, DISCUSSION_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s/%s", crs, INBOXES_DIR, TEAM_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s/%s", crs, INBOXES_DIR, INET_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s/%s", crs, INBOXES_DIR, LOUNGE_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s/%s", crs, INBOXES_DIR, MAIL_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s/%s", crs, INBOXES_DIR, HANDOUTS_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s/%s", crs, INBOXES_DIR, TEAM_TEACH_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s/%s", crs, INBOXES_DIR, GRADES_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s/%s", crs, INBOXES_DIR, SELFTEST_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s/%s", crs, INBOXES_DIR, LECTURES_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s/%s", crs, INBOXES_DIR, SURVEYS_DIR); if(mkdir (path, 0777)) return 0; return 1; } static int create_key_people(const char *course_path) { char path[MAX_PATH +1]; snprintf (path, MAX_PATH + 1, "%s/%s", course_path, KEY_DIR); if(mkdir (path, 0777)) return 0; snprintf (path, MAX_PATH + 1, "%s/%s", course_path, PEOPLE_DIR); if(mkdir (path, 0777)) return 0; return 1; } static int write_chat_message_log(const char *course) { FILE *fp; char log_fname[MAX_PATH +1]; snprintf(log_fname, MAX_PATH + 1, "%s/%s", course, CHAT_MSG_LOG); fp = fopen (log_fname, "w"); if(!fp) return 0; fclose(fp); return 1; } static int write_logout_html (const char *crs) { FILE *fp; char fname[MAX_PATH +1]; snprintf(fname, MAX_PATH + 1, "%s/%s", crs, EXIT_FILE); fp = fopen (fname, "w"); if(!fp) return 0; fprintf (fp, "
\n");
for(list->current = list->head; list->current; list->current=list->current->next)
{
printf("\n\nCourse Code: %s\n", list->current->course_code);
printf("Title: %s\n", list->current->title);
printf("Semester: %s\n", list->current->semester);
printf("subdir: %s\n", list->current->subdir);
printf("dir_id: %s\n", list->current->dir_id);
printf("real_dir: %s\n", list->current->real_dir_id);
for(list->current->user_current = list->current->user_head, students = 0;
list->current->user_current;
list->current->user_current = list->current->user_current->next, students++)
{
printf("real name: %s
\n", list->current->user_current->data.realname);
printf("last name: %s
\n", list->current->user_current->data.lastname);
printf("id number: %s
\n", list->current->user_current->data.id);
}
printf("Total users: %d
\n", students);
}
// puts("");
// exit(1);
}
/*** for debugging only
***/
void dump_user_list(USER_GROUP_INFO_LIST *user_list)
{
USER_GROUP_INFO *ptr;
COURSE_GROUP *course_ptr;
for(ptr=user_list->head; ptr; ptr = ptr->next)
{
printf("lastname= %s
\n", ptr->user.last);
printf("first= %s
\n", ptr->user.first);
printf("id = %s
\n", ptr->user.id);
for(course_ptr = ptr->head; course_ptr; course_ptr=course_ptr->next)
{
printf("subdir : %s
\n", course_ptr->course_subdir);
printf("coursedir : %s
\n", course_ptr->course_dir);
}
}
}
void
set_course_data_record_log(CREATED_COURSE_NODE *head, const char *prefix, const char *action)
{
#define MAX_TMP_NAME 50
CREATED_COURSE_NODE *ptr;
USER_NODE *t_node;
int course_count =0;
int drop_count =0;
int people_count, i =0;
char name[MAX_TMP_NAME];
for(ptr = head; ptr; ptr = ptr->next)
{
snprintf(name, MAX_TMP_NAME, "%s.%d.type", prefix, i);
cs_set_int_value(name, ptr->course_type);
snprintf(name, MAX_TMP_NAME, "%s.%d.course_subdir", prefix , i);
cs_set_value(name, ptr->course_subdir);
snprintf(name, MAX_TMP_NAME, "%s.%d.course_dir", prefix , i);
cs_set_value(name, ptr->course_dir);
snprintf(name, MAX_TMP_NAME, "%s.%d.course_org", prefix , i);
cs_set_value(name, ptr->org_id);
snprintf(name, MAX_TMP_NAME, "%s.%d.course_no", prefix , i);
cs_set_value(name, ptr->course_no);
snprintf(name, MAX_TMP_NAME, "%s.%d.course_title", prefix , i);
cs_set_value(name, ptr->course_title);
snprintf(name, MAX_TMP_NAME, "%s.%d.course_semester", prefix , i);
cs_set_value(name, ptr->course_semester);
snprintf(name, MAX_TMP_NAME, "%s.%d.exists", prefix , i);
cs_set_int_value(name, ptr->exists);
course_count++;
people_count =0;
drop_count = 0;
for(t_node = ptr->add_head; t_node; t_node = t_node->next)
{
if(strcmp(t_node->user.password, "drop") == 0)
drop_count++;
if(strcmp(t_node->user.password, "add") == 0 || (t_node->user.group == FACULTY && strcmp(t_node->user.password, "drop") != 0) )
{
snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.first", prefix , i, people_count);
cs_set_value(name, t_node->user.first);
snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.last", prefix , i, people_count);
cs_set_value(name, t_node->user.last);
snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.id", prefix , i, people_count);
cs_set_value(name, t_node->user.id);
snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.username", prefix , i, people_count);
cs_set_value(name, t_node->user.username);
snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.group", prefix , i, people_count);
cs_set_int_value(name, t_node->user.group);
snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.is_new", prefix , i, people_count);
cs_set_int_value(name, t_node->user.is_new);
snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.add_state", prefix , i, people_count);
cs_set_int_value(name, t_node->user.add_state);
snprintf(name, MAX_TMP_NAME, "%s.%d.users.%d.central_state", prefix , i, people_count);
cs_set_int_value(name, t_node->user.central_state);
people_count++ ;
}
}
if(people_count || drop_count)
update_roster_log(action, "", ptr->course_no, ptr->course_title, people_count, drop_count, "Success"); /* shared_wnec_roster_log.h */
i++;
}
if(!strcmp(prefix, "ctr"))
cs_set_int_value("ctr_total", course_count);
#undef MAX_TMP_NAME
}