#include #include #include #include #include "global.h" #include "manhat-lib/shared_util.h" #include "manhat-lib/shared_cs_util.h" #include "manhat-lib/shared_news_util.h" #include "manhat-lib/shared_lock.h" #include "manhat-lib/shared_file_util.h" static void read_parameters (char *course, char *key, long *offset, int *grp, char *team) { char temp[20]; cs_get_required_parameter ("validate", temp, 9); /* shared_cgi_util.c */ cs_get_required_parameter ("crs", course, MAX_PATH); /* shared_cgi_util.c */ cs_get_required_parameter ("id", key, MAX_KEY); cs_get_required_parameter ("grp", temp, 5); *grp = atoi (temp); cs_get_required_parameter ("loc", temp, 19); *offset = atol (temp); if (*grp == TEAM_TEACH) { cs_get_required_parameter ("team", temp, 5); *team = *temp; } else *team = '!'; /* assign some arbitrary value to team to prevent 'unitialized value' compiler warning */ } static void mark_deleted(MSG_TREE_NODE *msg) { int fd; FILE *fp; char inbox_fname[MAX_PATH + 1]; /* full path to central inbox */ CENTRAL_INBOX_RECORD data; snprintf(inbox_fname,MAX_PATH + 1,"%s%s",central_discussion_path,INBOX_FNAME); fp = fopen(inbox_fname,"r+"); if(!fp) /* inbox.dat doesn't exist */ cs_critical_error(ERR_FOPEN_READ_FAILED,""); fd = fileno(fp); get_exclusive_lock(fd, 1); /* shared_lock.c */ /* read the msg we are working with */ if(fseek(fp, msg->offset, SEEK_SET)) cs_critical_error(ERR_FSEEK_FAILED,""); if(fread(&data, sizeof(CENTRAL_INBOX_RECORD),1,fp) != 1) cs_critical_error(ERR_FREAD_FAILED, ""); data.status = DELETED; if(fseek(fp, msg->offset, SEEK_SET)) cs_critical_error(ERR_FSEEK_FAILED,""); if(fwrite(&data, sizeof(CENTRAL_INBOX_RECORD),1,fp) != 1) cs_critical_error(ERR_FWRITE_FAILED, ""); release_lock(fd); /* shared_lock.c */ fclose(fp); } static void delete_files(MSG_TREE_NODE *msg, const char *course_path) { FILE *fp; int fd; char infopath[MAX_PATH + 1]; NEWS_INFO infofile_info; char deletepath[MAX_PATH + 1]; int i; ATTACHMENT attachment; snprintf (infopath, MAX_PATH + 1, "%s%s/%s/%s/%s", course_path, PEOPLE_DIR, msg->data.info.sender, discussion_fname,msg->data.info_fname); fp = fopen (infopath, "r"); if (!fp) return; /* we'll ignore this error (?) */ fd = fileno(fp); get_shared_lock(fd, 1); /* shared_lock.c */ if (fread (&infofile_info, sizeof (NEWS_INFO), 1, fp) != 1) cs_critical_error (ERR_READING_INFO, ""); /*** delete the message file */ snprintf (deletepath, MAX_PATH + 1, "%s%s/%s/%s/%s", course_path, PEOPLE_DIR, msg->data.info.sender, discussion_fname, infofile_info.msg_fname); unlink (deletepath); if (infofile_info.attachments == -1) { /* a web page was attached */ if (fread (&attachment, sizeof (ATTACHMENT), 1, fp) != 1) cs_critical_error (ERR_ERROR_READING_ATTACHMENT, ""); snprintf (deletepath, MAX_PATH + 1, "%s%s/%s/%s/%s", course_path, PEOPLE_DIR, msg->data.info.sender, discussion_fname, attachment.unique_fname); kill_directory (deletepath); /* shared_file_util.c */ } else /* a web page was not attached */ for (i = 1; i <= infofile_info.attachments; i++) { if (fread (&attachment, sizeof (ATTACHMENT), 1, fp) != 1) cs_critical_error (ERR_ERROR_READING_ATTACHMENT, ""); snprintf (deletepath, MAX_PATH + 1, "%s%s/%s/%s/%s", course_path, PEOPLE_DIR, msg->data.info.sender, discussion_fname, attachment.unique_fname); unlink (deletepath); } release_lock(fd); fclose (fp); unlink (infopath); } static void delete_one_message (MSG_TREE_NODE *msg, const char *course_path) { mark_deleted(msg); delete_files(msg,course_path); } /* if the message we are deleting has one or more replies, ** we must change the reply_to value for those replies ** to the same value as the reply_to of the message ** we are deleting */ static void adjust_replies (MSG_TREE_NODE *msg, const char *course_path) { int fd; FILE *fp; char inbox_fname[MAX_PATH + 1]; /* full path to central inbox */ CENTRAL_INBOX_RECORD data; MSG_TREE_NODE *reply; if(msg->reply) { snprintf(inbox_fname,MAX_PATH + 1,"%s%s",central_discussion_path,INBOX_FNAME); fp = fopen(inbox_fname,"r+"); if(!fp) /* inbox.dat doesn't exist */ cs_critical_error(ERR_FOPEN_READ_FAILED,""); fd = fileno(fp); get_exclusive_lock(fd, 1); /* shared_lock.c */ for(reply=msg->reply; reply; reply=reply->next) { /* read the reply to the msg we are deleting */ if(fseek(fp, reply->offset, SEEK_SET)) cs_critical_error(ERR_FSEEK_FAILED,""); if(fread(&data, sizeof(CENTRAL_INBOX_RECORD),1,fp) != 1) cs_critical_error(ERR_FREAD_FAILED, ""); data.info.reply_to = msg->data.info.reply_to; if(fseek(fp, reply->offset, SEEK_SET)) cs_critical_error(ERR_FSEEK_FAILED,""); if(fwrite(&data, sizeof(CENTRAL_INBOX_RECORD),1,fp) != 1) cs_critical_error(ERR_FWRITE_FAILED, ""); } release_lock(fd); /* shared_lock.c */ fclose(fp); } /* if msg has a reply */ } static void delete_msg_tree(MSG_TREE_NODE *root, const char *course_path) { if(!root) return; delete_one_message(root,course_path); delete_msg_tree(root->next,course_path); delete_msg_tree(root->reply,course_path); } static void delete_message(SESSION *user, int grp, long offset, const char *course_path) { MSG_TREE_NODE *topic, *msg; int msg_count; time_t current_time; /* needed for build_one_topic_tree call */ build_one_topic_tree(user, grp, offset, &msg, &topic, &msg_count, 0, 1, ¤t_time); if(!msg || !tree_head) cs_critical_error(ERR_CANT_FIND_THIS_OFFSET, ""); if(msg == topic) /* if the message we want to delete is a topic */ delete_msg_tree(topic,course_path); else { delete_one_message(msg,course_path); adjust_replies(msg,course_path); } free_msg_tree(topic); } int main (void) { char course[MAX_PATH + 1]; /* from crs=? command line */ char key[MAX_KEY + 1]; /* from id=? command line */ long offset; /* from loc=? command line */ int grp; /* from grp=? command line */ char team; /* optional team=? command line req'd only for team_teach module */ SESSION user; CONFIG_STRUCT conf; /* the configuration read from config file */ cs_cgi_init(); read_parameters (course, key, &offset, &grp, &team); read_configuration_file (course, &conf); /* shared_util.c */ validate_key (key, &user, &conf); /* shared_util.c */ if (user.group != FACULTY) cs_critical_error (ERR_REQUEST_DENIED, ""); /* if this is the TEAM_TEACH module, switch user to the team provided on the command line */ if (grp == TEAM_TEACH) user.team = team; set_discussion_names (conf.course_path, user.username, grp); /* shared_news_util.c */ delete_message(&user, grp, offset, conf.course_path); if (grp == TEAM_TEACH) printf ("Location:%s?crs=%s&id=%s&grp=%d&team=%c\n\n", "news_topic", course, key, grp, team); else printf ("Location:%s?crs=%s&id=%s&grp=%d\n\n", "news_topic", course, key, grp); cs_cgi_destroy(); return 0; }