#include #include #include #include "global.h" #include "custom.h" #include "manhat-lib/shared_util.h" #include "manhat-lib/shared_super_util.h" #include "manhat-lib/shared_authenticate.h" #include "manhat-lib/shared_person_list.h" #include "manhat-lib/shared_lock.h" #include "manhat-lib/shared_super_list.h" #include "manhat-lib/shared_strtrm.h" #include "manhat-lib/shared_central_user.h" #include "manhat-lib/shared_escape_realname.h" #include "manhat-lib/shared_search_profile.h" #include "manhat-lib/shared_bio.h" #include "manhat-lib/shared_access.h" #include "manhat-lib/shared_cs_util.h" #include "manhat-lib/shared_super_menu.h" COURSE_NODE *master_course_head = (COURSE_NODE *) 0; /* COURSE_NODE is declared in shared_search_profile.h */ static void set_one_link(const char *key, const char *search, int field, int users, int report, int sensitive, int sort, int where, int start, int records_per_page,int num) { #define MAX_TMP_NAME 40 char url[MAX_PATH +1]; char name[MAX_TMP_NAME]; snprintf(name, MAX_TMP_NAME, "page.%d.url", num); snprintf(url, MAX_PATH +1, "%s?id=%s&search=%s&field=%d&users=%d&results=%d&sensitive=%d&sort=%d&where=%d&start=%d&step=%d", "super_info", key, search, field, users, report, sensitive, sort, where, start, records_per_page); cs_set_value(name, url); #undef MAX_TMP_NAME } static void print_goto_page_links(int count, const char *search, int field, int users, int report, int sensitive, int where, int sort, int start_record, int records_per_page, const char *key) { #define MAX_TMP_NAME 40 int page; int last_page; int start; int previous_start; int next_start; char name[MAX_TMP_NAME]; int i =0; /* print previous page link */ previous_start = start_record - records_per_page; if(previous_start >= 1) { snprintf(name, MAX_TMP_NAME, "page.%d.name", i); cs_set_value(name, "<<"); set_one_link(key,search,field,users,report,sensitive, sort, where, previous_start, records_per_page, i); i++; } /*** print numbered pages ***/ last_page = count/records_per_page; if(count % records_per_page) last_page++; for(page = 1, start = 1; page <= last_page; page++, start += records_per_page) { if ((start_record >= start) && (start_record < (start + records_per_page))) /* if page == this page */ { snprintf(name, MAX_TMP_NAME, "page.%d.name", i); cs_set_int_value(name, page); } else { snprintf(name, MAX_TMP_NAME, "page.%d.name", i); cs_set_int_value(name, page); set_one_link(key,search,field,users,report,sensitive, sort, where, start, records_per_page, i); } i++; } /*** print "next page" link ****/ next_start =start_record + records_per_page; if(next_start > count) { snprintf(name, MAX_TMP_NAME, "page.%d.name", i); cs_set_value(name, ">>"); } else { snprintf(name, MAX_TMP_NAME, "page.%d.name", i); cs_set_value(name, ">>"); set_one_link(key,search,field,users,report,sensitive, sort, where, next_start, records_per_page, i); } #undef MAX_TMP_NAME } static void set_heading(int count, char *search, int field, int users, int report, int sensitive, int where, int sort, int start_record, int records_per_page, const char *key) { char url[MAX_PATH +1]; if(count > records_per_page) { snprintf (url, MAX_PATH +1, "%s?id=%s","super_info_form", key); cs_set_value("back_url", url); } cs_set_value("search", search); cs_set_int_value("field", field); cs_set_int_value("users", users); cs_set_int_value("sensitive", sensitive); cs_set_int_value("sort", sort); cs_set_int_value("where", where); cs_set_int_value("num_match", count); if(count) cs_set_int_value("showing_from", start_record); else cs_set_int_value("showing_from", 0); if((start_record + records_per_page - 1) < count) cs_set_int_value("showing_to", (start_record + records_per_page - 1) ); else cs_set_int_value("showing_to", count ); if(records_per_page < count) print_goto_page_links(count, search, field, users, report, sensitive, where, sort, start_record, records_per_page, key); } void set_no_search_string(const char *key, PROFILE_NODE *profile_head, int sort) { #define MAX_TMP_NAME 50 char name[MAX_TMP_NAME]; char url[MAX_PATH +1]; PROFILE_NODE *ptr; CONFIG_STRUCT dummy_conf; /* used in call to get_bio_dir() */ char bio_dir[MAX_PATH + 1]; /* path to a user's bio */ int i =0; for(ptr = profile_head; ptr; ptr=ptr->next) { get_bio_dir("",&dummy_conf,ptr->person.username, bio_dir); /* shared_bio.c */ snprintf(name, MAX_TMP_NAME, "user.%d.username", i); cs_set_value(name, ptr->person.username); snprintf(url, MAX_PATH +1, "%s?id=%s&search=%s&field=%d&users=%d&results=%d&sort=%d", "super_info", key, ptr->person.username, USERNAME_FIELD, ALL_USERS, FULL_RESULTS, sort); snprintf(name, MAX_TMP_NAME, "user.%d.url", i); cs_set_value(name, url); snprintf(name, MAX_TMP_NAME, "user.%d.realname", i); cs_set_value(name, ptr->person.realname); snprintf(name, MAX_TMP_NAME, "user.%d.id", i); cs_set_value(name, ptr->person.id); if(bio_exists(bio_dir)) /* shared_bio.c */ { snprintf(name, MAX_TMP_NAME, "user.%d.bio_url", i); snprintf(url, MAX_PATH +1, "/%s/%s?id=%s&user=%s&admin=1", ALIAS, "bio_view", key, ptr->person.username); cs_set_value(name, url); } i++; } #undef MAX_TMP_NAME } void set_search_string(const char *key, PROFILE_NODE *profile_head, int sort, int search_len) { #define MAX_TMP_NAME 50 char name[MAX_TMP_NAME]; char url[MAX_PATH +1]; PROFILE_NODE *ptr; CONFIG_STRUCT dummy_conf; /* used in call to get_bio_dir() */ char bio_dir[MAX_PATH + 1]; /* path to a user's bio */ int i =0; for(ptr = profile_head; ptr; ptr=ptr->next) { get_bio_dir("",&dummy_conf,ptr->person.username, bio_dir); /* shared_bio.c */ set_highlighted(ptr->person.username, ptr->username_match, search_len, "username", i); /* shared_search_profile.c */ snprintf(url, MAX_PATH +1, "%s?id=%s&search=%s&field=%d&users=%d&results=%d&sort=%d", "super_info", key, ptr->person.username, USERNAME_FIELD, ALL_USERS, FULL_RESULTS, sort); snprintf(name, MAX_TMP_NAME, "user.%d.url", i); cs_set_value(name, url); set_highlighted(ptr->person.realname, ptr->realname_match, search_len, "realname", i); /* shared_search_profile.c */ set_highlighted(ptr->person.id, ptr->id_match, search_len, "id", i); /* shared_search_profile.c */ if(bio_exists(bio_dir)) /* shared_bio.c */ { snprintf(name, MAX_TMP_NAME, "user.%d.bio_url", i); snprintf(url, MAX_PATH +1, "/%s/%s?id=%s&user=%s&admin=1", ALIAS, "bio_view", key, ptr->person.username); cs_set_value(name, url); } i++; } #undef MAX_TMP_NAME } static void set_quick_list(const char *key, PROFILE_NODE *profile_head, int user_count, char *search, int field, int users, int sensitive, int where, int sort, int results, int start_record, int records_per_page) { int search_len; search_len = strlen(search); set_heading(user_count, search, field, users,INDEX_RESULTS, sensitive, where, sort, start_record, records_per_page, key); if(profile_head) { if(users == 3 && results==1) cs_set_int_value("check_all", 1); if(!search_len) /* if user did not enter a search string */ set_no_search_string(key, profile_head, sort); else /* search string was not blank, do same as above, but highlight match string */ set_search_string(key, profile_head, sort, search_len); } #undef MAX_TMP_NAME } static void get_configuration_data(COURSE_NODE *new_item, const char *crs) { CONFIG_STRUCT conf; read_configuration_file (crs, &conf); /* shared_util.c */ strncpy(new_item->course_data.course_dir, crs, MAX_PATH + 1 ); strncpy(new_item->course_data.course_no, conf.course_no, MAX_COURSE_NO + 1); strncpy(new_item->course_data.title, conf.title, MAX_COURSE_TITLE + 1); strncpy(new_item->course_data.semester, conf.semester, MAX_SEMESTER + 1); strncpy(new_item->course_data.instructor, conf.instructor, MAX_INSTRUCTOR + 1); new_item->course_data.standalone = conf.standalone; new_item->course_data.template = conf.template; new_item->course_data.access = conf.access; new_item->course_data.next = 0; } static void add_user_list(COURSE_NODE *new_item, const char *crs) { #define MAXLINE 200 char passwd_fname[MAX_PATH + 1]; FILE *fp; char line[MAXLINE + 1]; USER_DATA user_data; USERNAME_GROUP_NODE *last = 0; new_item ->user_head = 0; snprintf(passwd_fname, MAX_PATH + 1, "%s%s/%s", *crs == 'T'? TEMPLATE_PATH: COURSE_PATH, crs, PASSWD_FNAME); fp = fopen(passwd_fname, "r"); if(fp) { get_shared_lock(fileno(fp),1); /* shared_lock.c */ while (fgets (line, MAXLINE, fp)) { if (*line == '?') /* password lines starting with a '?' are ignored */ continue; if(!new_item->user_head) { new_item->user_head = (USERNAME_GROUP_NODE *) malloc(sizeof(USERNAME_GROUP_NODE)); if(!new_item->user_head) cs_critical_error(ERR_MALLOC_FAILED, ""); last = new_item->user_head; } else { last->next = (USERNAME_GROUP_NODE *) malloc(sizeof(USERNAME_GROUP_NODE)); if(!last->next) cs_critical_error(ERR_MALLOC_FAILED, ""); last = last->next; } get_passwd_line_data(line, &user_data); /* shared_person_list.c */ strncpy(last->username, user_data.username, MAX_USERNAME + 1); last->group = user_data.group; last->next = 0; } /* while fgets() */ release_lock(fileno(fp)); fclose(fp); } /* if fp */ #undef MAXLINE } static void get_master_course_list_data(COURSE_NODE *new_item, const char *crs) { get_configuration_data(new_item, crs); add_user_list(new_item, crs); new_item->next = 0; } static COURSE_NODE *new_master_course_node(const char *crs) { static COURSE_NODE *last_node = (COURSE_NODE *) 0; if(!master_course_head) { master_course_head = (COURSE_NODE *) malloc(sizeof(COURSE_NODE)); if(!master_course_head) cs_critical_error(ERR_MALLOC_FAILED, ""); last_node = master_course_head; } else { last_node -> next = (COURSE_NODE *) malloc(sizeof(COURSE_NODE)); if(!last_node->next) cs_critical_error(ERR_MALLOC_FAILED, ""); last_node = last_node->next; } get_master_course_list_data(last_node,crs); last_node -> next = 0; return last_node; } static GROUP_TYPE teacher_or_student(const char *username, USERNAME_GROUP_NODE *head) { USERNAME_GROUP_NODE *ptr; for(ptr=head; ptr; ptr=ptr->next) if(!strcmp(username, ptr->username)) return ptr->group; return UNKNOWN_GROUP; } static void add_course_to_profile(PROFILE_NODE *profile, COURSE_NODE *course_to_add) { USER_COURSE_NODE *ptr; if(!profile->course_head) { profile->course_head = (USER_COURSE_NODE *)malloc (sizeof(USER_COURSE_NODE)) ; if(!profile->course_head) cs_critical_error(ERR_MALLOC_FAILED, ""); ptr = profile->course_head; } else { for(ptr = profile->course_head; ptr->next; ptr=ptr->next); ptr->next = (USER_COURSE_NODE *)malloc (sizeof(USER_COURSE_NODE)) ; if(!ptr->next) cs_critical_error(ERR_MALLOC_FAILED, ""); ptr = ptr->next; } ptr->course_data = course_to_add; ptr->group = teacher_or_student(profile->person.username, course_to_add->user_head); ptr->next = (USER_COURSE_NODE *) 0; } static void add_one_course_data(PROFILE_NODE *profile, COURSE_LIST_NODE *course) { COURSE_NODE *ptr; int found = 0; for(ptr = master_course_head, found = 0; ptr && !found; ptr=ptr->next) if(!strcmp(course->crs, ptr->course_data.course_dir)) { found = 1; add_course_to_profile(profile, ptr); } if(!found) { ptr = new_master_course_node(course->crs); if(ptr) { add_course_to_profile(profile, ptr); } } } static void add_one_person_course_data(PROFILE_NODE *profile) { FILE *fp; char path[MAX_PATH + 1]; COURSE_LIST_NODE *course_head; /* COURSE_LIST_NODE is defined in shared_super_list.h */ COURSE_LIST_NODE *ptr; /* sub_dir_name() is in shared_authenticate.c */ snprintf(path, MAX_PATH + 1, "../%s/%c/%s/%s", USERS_DIR, sub_dir_name(profile->person.username), profile->person.username, COURSE_LIST_FNAME); fp = fopen(path, "r"); if(!fp) { return; /* user has no courses */ } get_shared_lock(fileno(fp), 1); /* shared_lock.c */ course_head = build_course_list(fp); /*shared_super_list.c */ release_lock(fileno(fp)); /*shared_lock.c */ fclose(fp); for(ptr=course_head; ptr; ptr=ptr->next) add_one_course_data(profile, ptr); super_free_course_list(course_head); /* shared_super_list.c */ } static void free_master_list_person_lists() { COURSE_NODE *master_ptr; USERNAME_GROUP_NODE *people_ptr; for(master_ptr = master_course_head; master_ptr; master_ptr=master_ptr->next) { while(master_ptr->user_head) { people_ptr = master_ptr->user_head; master_ptr->user_head = master_ptr->user_head->next; free(people_ptr); } } } static PROFILE_NODE *add_full_result_data(PROFILE_NODE *profile_head) { PROFILE_NODE *ptr; for(ptr = profile_head; ptr; ptr=ptr->next) { ptr -> course_head = (USER_COURSE_NODE *) 0; /* make sure we start with no courses */ add_one_person_course_data (ptr); } free_master_list_person_lists(); /* free up the individual person lists */ return profile_head; } static void free_master_course_list() { COURSE_NODE *ptr; while(master_course_head) { ptr = master_course_head; master_course_head = master_course_head -> next; free(ptr); } } void set_user_course_list(PROFILE_NODE *ptr, int num, const char *escaped_realname, const char *key) { #define MAX_TMP_NAME 50 char name[MAX_TMP_NAME]; char url[MAX_PATH +1]; int i =0; USER_COURSE_NODE *cptr; for(cptr=ptr->course_head; cptr; cptr=cptr->next) { if(cptr->group != FACULTY) { snprintf(name, MAX_TMP_NAME, "user.%d.course.%d.delete_url", num, i); snprintf(url, MAX_PATH +1, "%s?id=%s&crs=%s&username=%s&realname=%s", "super_delete_student",key,cptr->course_data->course_data.course_dir, ptr->person.username, escaped_realname); cs_set_value(name, url); } snprintf(name, MAX_TMP_NAME, "user.%d.course.%d.course_dir", num, i); cs_set_value(name, cptr->course_data->course_data.course_dir); snprintf(name, MAX_TMP_NAME, "user.%d.course.%d.course_no", num, i); cs_set_value( name, cptr->course_data->course_data.course_no); snprintf(name, MAX_TMP_NAME, "user.%d.course.%d.is_temp", num, i); cs_set_int_value(name, cptr->course_data->course_data.template); snprintf(name, MAX_TMP_NAME, "user.%d.course.%d.semester", num, i); cs_set_value(name, cptr->course_data->course_data.semester); snprintf(name, MAX_TMP_NAME, "user.%d.course.%d.access", num, i); cs_set_int_value(name, cptr->course_data->course_data.access); snprintf(name, MAX_TMP_NAME, "user.%d.course.%d.title", num, i); cs_set_value(name, cptr->course_data->course_data.title); snprintf(name, MAX_TMP_NAME, "user.%d.course.%d.instructor", num, i); cs_set_value(name, cptr->course_data->course_data.instructor); i++; } #undef MAX_TMP_NAME } void set_user_profile(PROFILE_NODE *head, const char *key) { #define MAX_TMP_NAME 50 PROFILE_NODE *ptr; int i =0; char name[MAX_TMP_NAME]; char url[MAX_PATH +1]; char escaped_realname[MAX_NAME + 1]; CONFIG_STRUCT dummy_conf; char bio_dir[MAX_PATH +1]; for(ptr = head; ptr; ptr=ptr->next) { get_bio_dir("",&dummy_conf,ptr->person.username, bio_dir); /* shared_bio.c */ escape_realname(escaped_realname, ptr->person.realname); /* shared_escape_realname.c */ snprintf(name, MAX_TMP_NAME, "user.%d.username", i); cs_set_value(name, ptr->person.username); snprintf(name, MAX_TMP_NAME, "user.%d.realname", i); cs_set_value(name, ptr->person.realname); snprintf(name, MAX_TMP_NAME, "user.%d.id", i); cs_set_value(name, ptr->person.id); snprintf(name, MAX_TMP_NAME, "user.%d.bio_url", i); snprintf(url, MAX_PATH +1, "/%s/%s?id=%s&user=%s&admin=1", ALIAS,"bio_view", key, ptr->person.username); cs_set_value(name, url); if(bio_exists(bio_dir)) /* shared_bio.c */ { snprintf(name, MAX_TMP_NAME, "user.%d.bio_exist", i); cs_set_int_value(name, 1); } snprintf(name, MAX_TMP_NAME, "user.%d.modify_url", i); snprintf(url, MAX_PATH +1, "%s?id=%s&username=%s&id_number=%s&realname=%s", "super_modify_profile_form", key, ptr->person.username, ptr->person.id, escaped_realname); cs_set_value(name, url); snprintf(name, MAX_TMP_NAME, "user.%d.passwd_url", i); snprintf(url, MAX_PATH +1, "%s?id=%s&username=%s&id_number=%s&realname=%s", "super_reset_password",key, ptr->person.username, ptr->person.id, escaped_realname); cs_set_value(name, url); snprintf(name, MAX_TMP_NAME, "user.%d.log_url", i); snprintf(url, MAX_PATH +1, "%s?id=%s&username=%s&logfile=%s", "super_log_data", key, ptr->person.username, "all"); cs_set_value(name, url); set_user_course_list(ptr, i, escaped_realname, key); i++; } #undef MAX_TMP_NAME } static void set_full_results(const char *key, PROFILE_NODE *profile_head, int user_count, char *search, int field, int users, int sensitive, int where, int sort, int start_record, int records_per_page) { #define MAX_ALERT 200 profile_head = add_full_result_data(profile_head); set_heading(user_count, search, field, users,FULL_RESULTS, sensitive, where, sort, start_record, records_per_page, key); if(profile_head) set_user_profile(profile_head, key); free_master_course_list(); #undef MAX_ALERT } static void set_search_results (const char *key, char *search, int field, int users, int results, int sensitive, int where, int sort, int start_record, int records_per_page) { PROFILE_NODE *profile_head; int user_count; profile_head = build_profile_list(search, sensitive, where, field, users, sort, start_record, records_per_page, &user_count); /* shared_search_profile.c */ if(results == FULL_RESULTS) { cs_set_int_value("full_record", 1); set_full_results(key, profile_head, user_count, search, field, users, sensitive, where, sort, start_record, records_per_page); } else set_quick_list(key, profile_head, user_count, search, field, users, sensitive, where, sort, results, start_record, records_per_page); free_profile_list(profile_head); } int main() { char search[MAX_PATH + 1]; /* from command line - string to search for */ int field; /* from command line - what fields to search on? */ int users; /* from command line - what users to include? */ int results; /* from command line - what form should results take */ int sensitive; /* from command line - case sensitive search? */ int where; /* from command line - match must contain, start with, end with? */ int sort; /* from command line - sort by? */ int start_record; /* from command line - start record */ int records_per_page; /* from command line - records per page? */ char key[MAX_KEY +1]; /* dummy variables */ char crs[MAX_PATH +1]; char group[MAX_ID +1]; char oper[20]; SESSION user; cs_cgi_init(); read_search_parameters(key, crs, group, oper, search, &field, &users, &results, &sensitive, &where, &sort, &start_record, &records_per_page); /*shared_search_profile.c */ validate_super_key(key, &user); set_admin_page(&user, key, 0, "super_info_form"); /* shared_super_menu.c */ set_search_results (key, search, field, users, results, sensitive, where, sort, start_record, records_per_page); cs_cgi_display("super_info", 1); cs_cgi_destroy(); return 0; }