#include #include #include #include #include #include "shared_person_list.h" #include "shared_access.h" #include "shared_cs_util.h" GROUP_TYPE get_group_type(const char *group) { if (!strcmp (group, "faculty")) return FACULTY; else if (!strcmp (group, "student")) return STUDENT; else if (!strcmp (group, "audit")) return AUDIT; else return UNKNOWN_GROUP; } char * get_group_type_str(GROUP_TYPE group) { char *group_str; group_str= (char*)malloc(sizeof(char)*20); if(group == FACULTY) strncpy(group_str, "faculty", 20); else if(group == STUDENT) strncpy(group_str, "student", 20); else if(group == AUDIT) strncpy(group_str, "audit", 20); return group_str; } P_NODE * sort_person_list (P_NODE *pers_head) { P_NODE *q, *tail, *p, *r; if (pers_head != NULL) { tail = pers_head; while (tail->next) { q = tail->next; if (username_cmp (&(q->data), &(pers_head->data)) < 0) /* shared_authenticate.c */ { tail->next = q->next; q->next = pers_head; pers_head = q; } else { r = pers_head; p = r->next; while (username_cmp (&(q->data), &(p->data)) > 0) /* shared_authenticate.c */ { r = p; p = r->next; } if (q == p) tail = q; else { tail->next = q->next; q->next = p; r->next = q; } } } } return pers_head; } void get_passwd_line_data(char *line, USER_DATA *data) { char *ptr, *ptr2, *lastname; ptr = strchr (line, ':'); if (!ptr) cs_critical_error (ERR_PASSWD_PARSE_ERROR, ""); *ptr = '\0'; strncpy (data->username, line, MAX_USERNAME + 1); ptr++; ptr2 = strchr (ptr, ':'); if (!ptr2) cs_critical_error (ERR_PASSWD_PARSE_ERROR, ""); *ptr2 = '\0'; strncpy (data->password, ptr, MAX_PASSWORD + 1); ptr = ptr2 + 1; ptr2 = strchr (ptr, ':'); if (!ptr2) cs_critical_error (ERR_PASSWD_PARSE_ERROR, ""); *ptr2 = '\0'; strncpy (data->realname, ptr, MAX_NAME + 1); ptr = ptr2 + 1; lastname = get_lastname(data->realname); strncpy (data->lastname, lastname, MAX_NAME + 1); free(lastname); ptr2 = strchr (ptr, ':'); if (!ptr2) cs_critical_error (ERR_PASSWD_PARSE_ERROR, ""); *ptr2 = '\0'; data->group =get_group_type(ptr); ptr = ptr2 + 1; ptr2 = strchr (ptr, ':'); if (!ptr2) cs_critical_error (ERR_PASSWD_PARSE_ERROR, ""); *ptr2 = '\0'; strncpy (data->alias, ptr, MAX_NAME + 1); ptr = ptr2 + 1; ptr2 = strchr (ptr, ':'); if(!ptr2) cs_critical_error (ERR_PASSWD_PARSE_ERROR, ""); *ptr2 = '\0'; data->team = *ptr; ptr = ptr2 + 1; ptr[strlen(ptr)-1] = '\0'; strncpy (data->id, ptr, MAX_ID +1); } P_NODE * build_option_person_list (const CONFIG_STRUCT *conf) { char passwd_fname[MAX_PATH + 1]; FILE *fp; int fd; char line[200]; P_NODE *person, *pptr = 0; P_NODE *pers_head = 0; snprintf (passwd_fname, MAX_PATH + 1, "%s%s", conf->course_path,PASSWORD_FNAME); fp = fopen (passwd_fname, "r"); if (!fp) cs_critical_error (ERR_PASSWD_OPEN_FAILED, passwd_fname); fd = fileno(fp); get_shared_lock(fd, 1); /* shared_lock.c */ while (fgets (line, 200, fp)) { if (*line == '?') /* password lines starting with a '?' are ignored */ continue; person = (P_NODE *) malloc (sizeof (P_NODE)); if (!person) cs_critical_error (ERR_MALLOC_FAILED, ""); get_passwd_line_data(line, &(person->data)); /* now add it to the linked list */ person->next = 0; if (!pers_head) pers_head = person; else pptr->next = person; pptr = person; } release_lock(fd); /* shared_lock.c */ fclose (fp); pers_head = sort_person_list (pers_head); return pers_head; } /* removes first node in list that represents 'username' */ P_NODE *option_list_remove_user(P_NODE *head, const char *username) { P_NODE *ptr, *ptr2; int found; for(ptr= head,found=0; ptr && !found; ptr=ptr->next) { if(!strcmp(ptr->data.username,username)) { found = 1; if(ptr == head) { head = head->next; free(ptr); } else { for(ptr2=head; ptr2 && (ptr2->next != ptr); ptr2=ptr2->next); if(ptr2) { ptr2->next = ptr->next; free(ptr); } } } /* if username was found */ } /* for */ return head; } /** removes the first FACULTY node found in the linked list **/ P_NODE *option_list_remove_first_faculty(P_NODE *head) { P_NODE *ptr, *ptr2; int found; for(ptr= head,found=0; ptr && !found; ptr=ptr->next) { if(ptr->data.group == FACULTY) { found = 1; if(ptr == head) { head = head->next; free(ptr); } else { for(ptr2=head; ptr2 && (ptr2->next != ptr); ptr2=ptr2->next); if(ptr2) { ptr2->next = ptr->next; free(ptr); } } } /* if faculty was found */ } /* for */ return head; } /** This fcn is called to adjust the person list when the list *** is being used to pick a user to delete from the course. *** That program can be run by FACULTY or ADMIN *** We need to make sure that *** 1) a FACULTY using the program doesn't delete himself from *** the classroom *** 2) an ADMIN doesn't delete the last FACULTY member in the course **/ P_NODE *faculty_adjusted_option_list(P_NODE *head, const SESSION *user) { int fac_count; P_NODE *ptr; if(user->group == FACULTY) /* this user could also be ADMIN */ head =option_list_remove_user(head, user->username); /* remove username from list */ if(user->group == ADMIN) { /* how many faculty are on the list? */ for(ptr = head, fac_count = 0; ptr; ptr=ptr->next) if(ptr->data.group == FACULTY) fac_count++; /* if there's only one FACULTY, remove him */ if(fac_count == 1) head = option_list_remove_first_faculty(head); } return head; } void free_option_person_list (P_NODE *pers_head) { P_NODE *ptr; while (pers_head) { ptr = pers_head->next; free (pers_head); pers_head = ptr; } } /* sets values for each user in the list, ** that might be used in an HTML selection list */ void set_option_userlist (P_NODE *pers_head) { #define MAX_TMP_NAME 30 P_NODE *ptr; char name[MAX_TMP_NAME]; char value[MAX_PATH]; int i; for (ptr = pers_head, i = 0; ptr; ptr = ptr->next, i++) { snprintf(name, MAX_TMP_NAME, "user.%d.value", i); snprintf (value, MAX_PATH ,"%s:%s", ptr->data.username, ptr->data.realname); cs_set_value(name, value); snprintf(name, MAX_TMP_NAME, "user.%d.realname", i); snprintf (value, MAX_PATH ,"%s%s", ptr->data.group == FACULTY ? "*": "", ptr->data.realname); cs_set_value(name, value); } #undef MAX_TMP_NAME } void set_post_recipient(RECEIVE_TYPE kind, const char *username, const char *realname) { #define MAX_STR 100 char name[MAX_STR + 1]; char value[MAX_STR + 1]; snprintf(name, MAX_STR, "%s.%s", kind == TO? "to": kind== CC? "cc": "bcc", username); snprintf(value,MAX_STR, "%s:%s", username, realname); cs_set_value(name,value); /* shared_cs_util.c */ #undef MAX_STR } void set_post_group_reply_recipients(const char *sender, const char *sender_realname, const char *thisuser, PERSON_NODE *recipient_head) { PERSON_NODE *rptr; /* include the sender of the message on the TO: list */ set_post_recipient(TO, sender, sender_realname); for(rptr = recipient_head; rptr; rptr = rptr->next) { if(strcmp(thisuser, rptr->data.username)) /* don't include the person running this program */ { set_post_recipient(rptr->data.how_received, rptr->data.username, rptr->data.realname); } } } /* faculty are excluded from this list */ void print_student_option_namelist (P_NODE *pers_head) { P_NODE *ptr; for (ptr = pers_head; ptr; ptr = ptr->next) if (ptr->data.group != FACULTY) printf ("