#include #include #include #include #include #include #include "global.h" #include "custom.h" /* for date FORMAT strings */ #include "survey.h" #include "manhat-lib/shared_util.h" #include "manhat-lib/shared_lock.h" #include "manhat-lib/shared_news_util.h" #include "manhat-lib/shared_file_util.h" #include "manhat-lib/shared_cs_util.h" #include "manhat-lib/shared_time.h" #include "manhat-lib/shared_copy_file.h" #include "manhat-lib/shared_person_list.h" #include "manhat-lib/shared_fold_file.h" #include "manhat-lib/shared_podcast_util.h" void check_upload_file() { FILE *fp; struct stat file_stat; char *filename = hdf_get_value(global_cgi->hdf, "Query.podcasting", 0); if(!filename) cs_critical_error(ERR_PARAM_MISSING, "podcasting"); fp = cgi_filehandle(global_cgi, "podcasting"); if(!fp) cs_critical_error(ERR_NO_FILE, "check_upload_file"); if(fstat(fileno(fp), &file_stat)) cs_critical_error(ERR_NO_FILE, "check_upload_file"); if(file_stat.st_size == 0) cs_critical_error(ERR_NO_FILE, "check_upload_file"); } static char* read_parameters (char *course, char *key, int *hide, char *subject, int *width, int *is_pasted) { char tmp[80], filename[MAX_PATH], extension[MAX_FILENAME+1], pasted_file[MAX_PATH +1]; char *string; char *msg; cs_get_required_parameter ("crs", course, MAX_PATH); cs_get_required_parameter ("id", key, MAX_KEY); cs_get_required_parameter ("subject", subject, MAX_SUBJECT); cs_get_required_parameter ("width", tmp, 79); *width = atoi(tmp); cs_get_optional_parameter ("podcasting", filename, MAX_PATH); cs_get_optional_parameter ("pod_paste", pasted_file, MAX_PATH); if(!strlen(filename) && (!strlen(pasted_file) || !strcmp(pasted_file, "-1"))) cs_critical_error(ERR_PODCASTING_NEED_ONE_FILE, "empty string"); else if(strlen(filename) && strlen(pasted_file) && strcmp(pasted_file, "-1") ) cs_critical_error(ERR_PODCASTING_NEED_ONE_FILE, "both not empty"); if(strlen(filename)) { get_extension(filename, extension); /* shared_news_util.c */ if( !is_valid_podcast_file_extension(extension)) /* shared_podcast_util.c */ cs_critical_error(ERR_PODCASTING_FILE_FORMAT, "podcasting_send_mail"); check_upload_file(); *is_pasted = 0; } else if( strcmp(pasted_file, "-1")) *is_pasted = 1; cs_get_optional_parameter ("hide", tmp, 19); if(strlen(tmp)>0) *hide = 1; else *hide =0; string = hdf_get_value(global_cgi->hdf, "Query.msg", 0); if(!string) { msg = (char *) malloc(sizeof(char)*2); if(!msg) cs_critical_error(ERR_MALLOC_FAILED, ""); *msg= '\0'; } else { msg = (char *) malloc( (strlen(string) + 1) * sizeof(char)); if(!msg) cs_critical_error(ERR_MALLOC_FAILED, ""); strcpy(msg,string); } return msg; } static void write_msg_file ( char *msg, const char *unique_fname, int width) { FILE *outfp; char filepath[MAX_PATH + 1]; int len =0; snprintf (filepath, MAX_PATH + 1, "%s/%s", discussion_path, unique_fname); if(msg) len = strlen(msg); outfp = fopen (filepath, "w"); if (!outfp) cs_critical_error (ERR_FOPEN_WRITE_FAILED, ""); if(len < width || USE_TEXTAREA_HARD_WRAP) fprintf (outfp, "%s", msg); else write_folded(outfp, msg, width); /* shared_fold_file.c */ fclose (outfp); } /* note that this creates the file */ void get_unique_fname(char *unique_fname, const char *base_dir, const char *filetype, time_t *time_sent) { int fd; fd = get_unique_fd(base_dir, filetype, unique_fname, time_sent); close(fd); } static void process_message_file ( char *msg, char *msg_fname, time_t * time_sent, int width) { get_unique_fname (msg_fname, discussion_path, "msg", time_sent); write_msg_file (msg, msg_fname, width); } static void complete_send (const char *msg_fname, SESSION *user, time_t time_sent, int hide, const char *subject, const char *unique, const char *org) { FILE *inbox_fp; int info_fd, inbox_fd; struct stat buf; NEWS_PERSON person; char info_fname[MAX_FILENAME + 1]; char inbox_fname[MAX_PATH + 1]; int msg_id; CENTRAL_INBOX_RECORD inbox_record, new_inbox_record; int inbox_record_size, attachment_size; ATTACHMENT attach; /* memorize the sizes of these data structures, ** so we don't have to repeatedly call sizeof() */ inbox_record_size = sizeof(CENTRAL_INBOX_RECORD); attachment_size = sizeof(ATTACHMENT); /* this user has already read this message ** set a NEWS_PERSON record to be written ** to the end of the new inf file. */ strncpy(person.username,user->username, MAX_USERNAME + 1); strncpy(person.realname, user->realname, MAX_NAME + 1); person.time_read = time_sent; person.user_unlocked = 0; /* set up as much of the new inbox record as we can before locking ** the inbox.dat file */ strncpy(new_inbox_record.info.msg_fname, msg_fname, MAX_FILENAME + 1); strncpy(new_inbox_record.info.sender, user->username, MAX_USERNAME + 1); strncpy(new_inbox_record.info.sender_realname, user->realname, MAX_NAME + 1); strncpy(new_inbox_record.info.receiver_username,"",MAX_USERNAME + 1); strncpy(new_inbox_record.info.subject, subject, MAX_SUBJECT + 1); new_inbox_record.info.time_sent = time_sent; new_inbox_record.info.attachments = 1; new_inbox_record.info.sender_team = user->team; new_inbox_record.info.reply_to = -1; /* get the name of the 'inf' file to do so, we need to open ** (create) the file */ info_fd = get_unique_fd (discussion_path,"inf", info_fname, &time_sent); /* don't bother to lock it, since no one knows it's there yet! */ strncpy(new_inbox_record.info_fname,info_fname,MAX_FILENAME + 1); new_inbox_record.release_time = 0; new_inbox_record.unrelease_time = 0; new_inbox_record.status = hide? TEACHER_HIDDEN: NORMAL; /* now open and lock the inbox.dat file */ snprintf(inbox_fname,MAX_PATH + 1,"%s%s",central_discussion_path,INBOX_FNAME); inbox_fp = fopen(inbox_fname,"a+"); if(!inbox_fp) /* couldn't open or create inbox.dat */ cs_critical_error(ERR_FOPEN_WRITE_FAILED, inbox_fname); inbox_fd = fileno(inbox_fp); get_exclusive_lock(inbox_fd, 1); /* shared_lock.c */ /* get the next available msg_id, by incrementing the msg_id of the ** last msg in the inbox.dat file */ fstat(inbox_fd, &buf); if(!buf.st_size) /* this is the first message */ msg_id = 1; else { if(fseek(inbox_fp,-inbox_record_size,SEEK_END) == -1) cs_critical_error(ERR_FSEEK_FAILED, ""); if(fread( &inbox_record, inbox_record_size, 1, inbox_fp) != 1) cs_critical_error(ERR_FREAD_FAILED, ""); msg_id = inbox_record.info.msg_id + 1; } new_inbox_record.info.msg_id = msg_id; new_inbox_record.info.topic_id = msg_id; if(fseek(inbox_fp,0,SEEK_END) == -1) cs_critical_error(ERR_FSEEK_FAILED, ""); if(fwrite(&new_inbox_record, inbox_record_size,1,inbox_fp) != 1) cs_critical_error(ERR_FWRITE_FAILED, ""); /* now write the info file */ if (write (info_fd, &new_inbox_record.info, sizeof (NEWS_INFO)) != sizeof(NEWS_INFO)) cs_critical_error (ERR_FWRITE_FAILED, ""); strncpy (attach.unique_fname, unique, MAX_FILENAME + 1); strncpy (attach.orig_fname, org, MAX_FILENAME + 1); if (write (info_fd, &attach, attachment_size) != attachment_size) cs_critical_error (ERR_FWRITE_FAILED, ""); if(write (info_fd,&person, sizeof(NEWS_PERSON))!= sizeof(NEWS_PERSON)) cs_critical_error (ERR_FWRITE_FAILED, ""); release_lock(inbox_fd); /* shared_lock.c */ fclose(inbox_fp); write_user_inbox_record(msg_id, time_sent); /* shared_news_util.c */ } static int student_count(CONFIG_STRUCT *conf) { P_NODE *head; int count; head = build_option_person_list(conf); /* shared_person_list.c */ count = count_students(head); /* shared_person_list.c */ free_option_person_list(head); /* shared_person_list.c */ return count; } void upload_podfile(char *unique_fname, char *orig_fname, time_t *time_sent) { char filename[MAX_PATH +1]; FILE *fp; struct stat file_stat; cs_get_required_parameter("podcasting", filename, MAX_PATH ); get_unique_fname (unique_fname, discussion_path, "fil", time_sent); /* shared_news_util.c */ get_orig_fname (filename, orig_fname); /* shared_news_uitl.c */ fp = cgi_filehandle(global_cgi, "podcasting"); if(!fp) cs_critical_error(ERR_NO_FILE, "upload_podfile"); if(fstat(fileno(fp), &file_stat)) cs_critical_error(ERR_NO_FILE, "upload_podfile"); write_cgi_file (fp, file_stat.st_size, unique_fname); } static void parse_raw_filename (char *raw_fname, char *orig_fname, char *unique_fname) { char *ptr; ptr = strstr (raw_fname, "::"); if (!ptr) cs_critical_error (ERR_PARAM_FORMAT, raw_fname); *ptr = '\0'; strncpy (orig_fname, raw_fname, MAX_FILENAME + 1); ptr += 2; /* skip past "::" */ strncpy (unique_fname, ptr, MAX_FILENAME + 1); } void handle_pasted_file(char *unique_fname, char *origional_fname, time_t *time_sent, SESSION *user) { char raw_fname[MAX_PATH +1]; char pasted_origfname[MAX_FILENAME +1]; char pasted_uniquefname[MAX_FILENAME +1]; char sourcepath[MAX_PATH +1]; char destpath[MAX_PATH +1]; char clipboard_path[MAX_PATH +1]; cs_get_required_parameter("pod_paste", raw_fname, MAX_PATH); parse_raw_filename (raw_fname, pasted_origfname, pasted_uniquefname); strncpy(origional_fname, pasted_origfname, MAX_FILENAME +1); get_unique_fname (unique_fname, discussion_path, "fil", time_sent); /* shared_news_util.c */ snprintf (clipboard_path, MAX_PATH + 1, "%s%s/", CLIPBOARD_PATH, user->id); snprintf (sourcepath, MAX_PATH + 1, "%s%s", clipboard_path,pasted_uniquefname); snprintf (destpath, MAX_PATH + 1, "%s%s", discussion_path,unique_fname); copy_file (sourcepath, destpath); /* shared_copy_file.c */ } int main (void) { char course[MAX_PATH + 1]; /* from crs=? command line */ char key[MAX_KEY + 1]; /* from id=? command line */ int hide; /* from hide=? command line */ char subject[MAX_SUBJECT +1]; /*from subject= command line */ char *msg; /* from msg = command line */ char unique_filename[MAX_FILENAME + 1]; /* mkstemp() name given to the directory where the survey ** xml files are copied */ char origional_filename[MAX_FILENAME + 1]; int is_pasted =0; time_t time_sent; char msg_fname[MAX_FILENAME + 1]; /* mkstemp() name given to the msg file */ int number_students; /* how many students are in this class ? */ int width; SESSION user; CONFIG_STRUCT conf; /* the configuration read from config file */ cs_cgi_init(); msg = read_parameters (course, key, &hide, subject, &width, &is_pasted); 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, ""); set_discussion_names (conf.course_path, user.username, PODCASTS); /* #included */ time_sent = time (NULL); process_message_file (msg, msg_fname, &time_sent, width); /* writes the message */ number_students = student_count(&conf); if(is_pasted == 0) upload_podfile(unique_filename, origional_filename, &time_sent); else handle_pasted_file(unique_filename, origional_filename, &time_sent, &user); complete_send(msg_fname,&user,time_sent,hide, subject, unique_filename, origional_filename); if(msg) free(msg); printf ("Location: %s?crs=%s&id=%s&grp=%d\n\n", "news_topic",course, key, PODCASTS); cs_cgi_destroy(); return 0; }