#include #include #include #include /* for tolower() */ #include #include #include "global.h" #include "custom.h" /* for date FORMAT strings */ #include "manhat-lib/shared_util.h" #include "manhat-lib/shared_cs_util.h" #include "manhat-lib/shared_super_util.h" #include "manhat-lib/shared_super_menu.h" #include "manhat-lib/shared_person_list.h" #include "manhat-lib/shared_encrypt.h" //#include "manhat-lib/shared_news_util.h" //#include "manhat-lib/shared_post_inbox.h" typedef struct inbox_node { INBOX_RECORD data; struct inbox_node *next; struct inbox_node *prev; long offset; } INBOX_NODE; typedef struct outbox_node { OUTBOX_RECORD data; struct outbox_node *next; struct outbox_node *prev; long offset; } OUTBOX_NODE; OUTBOX_NODE * build_outbox_list (const char *outbox) { FILE *fp; OUTBOX_RECORD msg; OUTBOX_NODE *ptr = 0; OUTBOX_NODE *outbox_head = 0; OUTBOX_NODE *outbox_tail = 0; long offset = 0; fp = fopen (outbox, "r"); if (fp) { while (fread (&msg, sizeof (OUTBOX_RECORD), 1, fp) == 1) { /* add the record to the end of the linked list */ if (!outbox_head) { outbox_head = (OUTBOX_NODE *) malloc (sizeof (OUTBOX_NODE)); if (!outbox_head) cs_critical_error (ERR_MALLOC_FAILED, ""); ptr = outbox_head; ptr->prev = 0; } else { ptr->next = (OUTBOX_NODE *) malloc (sizeof (OUTBOX_NODE)); if (!ptr->next) cs_critical_error (ERR_MALLOC_FAILED, ""); ptr->next->prev = ptr; ptr = ptr->next; } ptr->data = msg; ptr->offset = offset; ptr->next = 0; outbox_tail = ptr; offset = ftell (fp); } fclose (fp); } return outbox_head; } static void free_outbox_list (OUTBOX_NODE *outbox_head) { OUTBOX_NODE *ptr; while (outbox_head) { ptr = outbox_head; outbox_head = outbox_head->next; free (ptr); } } INBOX_NODE * build_inbox_list (const char *inbox) { FILE *fp; INBOX_RECORD msg; INBOX_NODE *ptr = 0; long offset = 0; INBOX_NODE *inbox_head = 0; INBOX_NODE *inbox_tail = 0; fp = fopen (inbox, "r"); if (fp) { while (fread (&msg, sizeof (INBOX_RECORD), 1, fp) == 1) { /* add the record to the end of the linked list */ if (!inbox_head) { inbox_head = (INBOX_NODE *) malloc (sizeof (INBOX_NODE)); ptr = inbox_head; ptr->prev = 0; } else { ptr->next = (INBOX_NODE *) malloc (sizeof (INBOX_NODE)); ptr->next->prev = ptr; ptr = ptr->next; } ptr->data = msg; ptr->offset = offset; ptr->next = 0; inbox_tail = ptr; offset = ftell (fp); } fclose (fp); } return inbox_head; } static void free_inbox_list (INBOX_NODE *inbox_head) { INBOX_NODE *ptr; while (inbox_head) { ptr = inbox_head; inbox_head = inbox_head->next; free (ptr); } } DEL_COURSE_NODE * read_parameters(char *key, char *password) { DEL_COURSE_NODE *head; /*shared_super_util.c */ cs_get_required_parameter ("id", key, MAX_KEY); /* shared_cs_util.c */ cs_get_required_parameter ("password", password, MAX_PASSWORD); head = build_selected_course_list(); /* shared_super_util.c */ return head; } int find_sender(P_NODE *p_head, char *username) { P_NODE *ptr; int found = 0; for(ptr = p_head; ptr && !found; ptr = ptr->next) { if( !strcmp(username, ptr->data.username) && ptr->data.group == FACULTY) found = 1; else if( !strcmp(username, ptr->data.username)) found = 2; } if(found == 2) return 0; return 1; } void delete_inbox_msg(INBOX_NODE *inbox_head, P_NODE *p_head) { INBOX_NODE *ptr; int is_from_teacher = 0; for(ptr = inbox_head; ptr; ptr = ptr->next) { is_from_teacher = find_sender(p_head, ptr->data.newfile_info.sender); if(!is_from_teacher) ptr->data.newfile_info.how_sent = DELETED; } } void rewrite_inbox(INBOX_NODE *inbox_head, const char *inbox_path) { FILE *fp; INBOX_NODE *ptr; fp = fopen(inbox_path, "w"); if(!fp) cs_critical_error(ERR_UNABLE_TO_OPEN_INBOX, inbox_path); for(ptr = inbox_head; ptr; ptr = ptr->next) { if(fwrite (&ptr->data, sizeof(INBOX_RECORD), 1, fp) != 1) cs_critical_error (ERR_FWRITE_FAILED, inbox_path); } fclose(fp); } void process_inbox(const char *path_to_mail, P_NODE *p_head) { INBOX_NODE *inbox_head = 0; char inbox_path[MAX_PATH +1]; snprintf(inbox_path, MAX_PATH +1, "%s/%s", path_to_mail, INBOX_FNAME); inbox_head = build_inbox_list (inbox_path); delete_inbox_msg(inbox_head, p_head); rewrite_inbox(inbox_head, inbox_path); free_inbox_list (inbox_head); } void delete_all_files(const char *info_fname, const char *path_to_mail, ATTACHMENT_NODE *attachment_head, INFO *infofile_info) { char path[MAX_PATH +1]; ATTACHMENT_NODE *ptr; snprintf(path, MAX_PATH +1, "%s/%s", path_to_mail, infofile_info->msg_fname); unlink(path); /* delete msg file */ unlink(info_fname); /* delete inf file */ /* delete all the attached files */ for(ptr = attachment_head; ptr; ptr = ptr->next) { snprintf(path, MAX_PATH +1, "%s/%s", path_to_mail, ptr->data.unique_fname); if(infofile_info->no_attachments == -1 && ptr == attachment_head && isdirectory(path_to_mail, ptr->data.unique_fname) ) kill_directory(path); /* shared_file_util.c */ else unlink(path); } } int find_teacher_in_list(PERSON_NODE *person_head, P_NODE *p_head) { PERSON_NODE *ptr; for(ptr = person_head; ptr; ptr = ptr->next) { if(find_sender(p_head, ptr->data.username)) return 1; } return 0; } int process_one_outbox_msg(const char *info_fname, P_NODE *p_head, const char *path_to_mail) { FILE *fp; INFO infofile_info; ATTACHMENT_NODE *aptr = 0, *aptr_current = 0; PERSON_NODE *pptr = 0, *pptr_current = 0; int i; PERSON person_buffer; PERSON_NODE *person_head = 0; ATTACHMENT_NODE *attachment_head = 0; int is_sent_to_teacher; fp = fopen(info_fname, "r"); if(fp) { if (fread (&infofile_info, sizeof (INFO), 1, fp) != 1) cs_critical_error (ERR_READING_INFO, info_fname); for (i = 1; i <= abs(infofile_info.no_attachments); i++) { aptr = (ATTACHMENT_NODE *) malloc (sizeof (ATTACHMENT_NODE)); if (!aptr) cs_critical_error (ERR_MALLOC_FAILED, ""); if (fread (&aptr->data, sizeof (ATTACHMENT), 1, fp) != 1) cs_critical_error (ERR_ERROR_READING_ATTACHMENT, info_fname); aptr->next = 0; if (!attachment_head) attachment_head = aptr; else aptr_current->next = aptr; aptr_current = aptr; } while (fread (&person_buffer, sizeof (PERSON), 1, fp) == 1) { pptr = (PERSON_NODE *) malloc (sizeof (PERSON_NODE)); pptr->data = person_buffer; pptr->next = 0; if(!person_head) person_head = pptr; else pptr_current->next = pptr; pptr_current = pptr; } is_sent_to_teacher = find_teacher_in_list(person_head,p_head); if(!is_sent_to_teacher) { delete_all_files(info_fname, path_to_mail, attachment_head, &infofile_info); return 1; } else return 0; } else return 1; } void delete_outbox_msg(OUTBOX_NODE *outbox_head, P_NODE *p_head, const char *path_to_mail) { OUTBOX_NODE *ptr; char info_fname[MAX_PATH +1]; int is_deleted = 0; for(ptr = outbox_head; ptr; ptr = ptr->next) { snprintf(info_fname, MAX_PATH +1, "%s/%s", path_to_mail, ptr->data.info_fname); is_deleted = process_one_outbox_msg(info_fname, p_head, path_to_mail); if(is_deleted) ptr->data.how_sent = DELETED; } } void rewrite_outbox(OUTBOX_NODE *outbox_head, const char *outbox_path) { OUTBOX_NODE *ptr; FILE *fp; fp = fopen(outbox_path, "w"); if(!fp) cs_critical_error (ERR_FWRITE_FAILED, outbox_path); for(ptr = outbox_head; ptr; ptr = ptr->next) { if(fwrite (&ptr->data, sizeof(OUTBOX_RECORD), 1, fp) != 1) cs_critical_error (ERR_FWRITE_FAILED, outbox_path); } fclose(fp); } void process_outbox(const char *path_to_mail, P_NODE *p_head) { OUTBOX_NODE *outbox_head = 0; char outbox_path[MAX_PATH +1]; snprintf(outbox_path, MAX_PATH +1, "%s/%s", path_to_mail, OUTBOX_FNAME); outbox_head = build_outbox_list (outbox_path); delete_outbox_msg(outbox_head, p_head, path_to_mail); rewrite_outbox(outbox_head, outbox_path); free_outbox_list (outbox_head); } void purge_users_postoffice(P_NODE *one_user, P_NODE *p_head, CONFIG_STRUCT *conf) { char path_to_mail[MAX_PATH +1]; snprintf(path_to_mail, MAX_PATH +1, "%s%s/%s/%s", conf->course_path, PEOPLE_DIR, one_user->data.username, MAIL_DIR); process_inbox(path_to_mail, p_head); process_outbox(path_to_mail, p_head); } void purge_postoffice_message(P_NODE *p_head, CONFIG_STRUCT *conf) { P_NODE *ptr; for(ptr = p_head; ptr; ptr = ptr->next) { if(ptr->data.group == STUDENT) purge_users_postoffice(ptr, p_head, conf); } } void do_action(DEL_COURSE_NODE *course_head) { DEL_COURSE_NODE *ptr; CONFIG_STRUCT conf; P_NODE *p_head; for(ptr = course_head; ptr; ptr = ptr->next) { read_configuration_file (ptr->del_id, &conf); /*shared_util.c*/ p_head = build_option_person_list (&conf); /* shared_person_list.c */ purge_postoffice_message(p_head, &conf); free_option_person_list (p_head); /* shared_person_list.c */ } } void set_purged_course_info(DEL_COURSE_NODE *head) { #define MAX_TMP_NAME 50 DEL_COURSE_NODE *ptr; char name[MAX_TMP_NAME]; int i =0; if(!head) cs_critical_error( ERR_NO_COURSE_MSG, ""); for(ptr = head; ptr; ptr = ptr->next) { snprintf(name, MAX_TMP_NAME, "course_list.%d.id", i); cs_set_value(name, ptr->del_id); snprintf(name, MAX_TMP_NAME, "course_list.%d.info", i); cs_set_value(name, ptr->del_info); i++; } #undef MAX_TMP_NAME } int main (void) { char key[MAX_KEY + 1]; /* from id=? command line */ DEL_COURSE_NODE *course_head = 0; char password[MAX_PASSWORD +1]; SESSION user; cs_cgi_init(); course_head = read_parameters (key, password); validate_super_key (key, &user); /* shared_util.c */ if(!course_head) cs_critical_error( ERR_NO_COURSE_MSG, ""); if(confirm_super_password(password, user.username)) /* shared_encrypt.c */ { set_admin_page(&user, key, 0, "super_purge_postoffice_message_form"); /* shared_super_menu.c */ do_action(course_head); set_purged_course_info(course_head); } else cs_critical_error(ERR_USERNAME_PASSWD_INCORRECT, ""); free_del_list(course_head); /* shared_super_util.c */ cs_cgi_display("super_purge_postoffice", 0); cs_cgi_destroy(); return 0; }