#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_server_string.h" #include "manhat-lib/shared_mp3_util.h" ATTACHMENT_NODE *attachment_head = (ATTACHMENT_NODE *) 0; static void extract_play_one_params(char *string, char *course, char *sender, int *grp, char *fname, char *infname, char *sender_realname, char *title, char *key) { char *ptr, *ptr2; ptr = strstr(string, "sender^"); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "can't find 'sender^' within 'crs' parameter"); *ptr = '\0'; strncpy(course, string, MAX_FILENAME +1); ptr++; ptr2 = strchr(ptr, '^'); if(!ptr2) cs_critical_error(ERR_PARAM_MISSING, "can't find first ^ in 'crs' parameter"); *ptr2 = '\0'; ptr2++; ptr = strstr(ptr2, "grp^"); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "can't find 'grp^' within 'crs' parameter"); ptr--; *ptr = '\0'; strncpy(sender, ptr2, MAX_USERNAME + 1); ptr++; ptr2 = strchr(ptr, '^'); if(!ptr2) cs_critical_error(ERR_PARAM_MISSING, "can't find second ^ within 'crs' parameter"); *ptr2 = '\0'; ptr2++; ptr = strstr(ptr2, "fname^"); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "can't find 'fname' within 'crs' parameter"); ptr--; *ptr = '\0'; *grp = atoi(ptr2); ptr++; ptr2 = strchr(ptr, '^'); if(!ptr2) cs_critical_error(ERR_PARAM_MISSING, "can't find third ^ within 'crs' parameter"); *ptr2 = '\0'; ptr2++; ptr = strstr(ptr2, "inf^"); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "can't find 'inf^' within 'crs' parameter"); ptr--; *ptr = '\0'; strncpy(fname, ptr2, MAX_FILENAME + 1); ptr++; ptr2 = strchr(ptr, '^'); if(!ptr2) cs_critical_error(ERR_PARAM_MISSING, "can't find fourth ^ within 'crs' parameter"); *ptr2 = '\0'; ptr2++; ptr = strstr(ptr2, "rlname^"); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "can't find 'rlname^' within 'crs' parameter"); ptr--; *ptr = '\0'; strncpy(infname, ptr2, MAX_FILENAME + 1); ptr++; ptr2 = strchr(ptr, '^'); if(!ptr2) cs_critical_error(ERR_PARAM_MISSING, "can't find fifth ^ within 'crs' parameter"); *ptr2 = '\0'; ptr2++; ptr = strstr(ptr2, "title^"); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "can't find 'title^' within 'crs' parameter"); ptr--; *ptr = '\0'; strncpy(sender_realname, ptr2, MAX_NAME + 1); ptr++; ptr2 = strchr(ptr, '^'); if(!ptr2) cs_critical_error(ERR_PARAM_MISSING, "can't find sixth ^ within 'crs' parameter"); *ptr2 = '\0'; ptr2++; ptr = strstr(ptr2, "id^"); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "can't find 'id^' within 'crs' parameter"); ptr--; *ptr = '\0'; strncpy(title, ptr2, MAX_PATH+1); ptr++; ptr2 = strchr(ptr, '^'); if(!ptr2) cs_critical_error(ERR_PARAM_MISSING, "can't find seventh ^ within 'crs' parameter"); *ptr2 = '\0'; ptr2++; ptr = strstr(ptr2, ".xml"); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "'crs' parameter doesn't end in '.xml'"); *ptr = '\0'; strncpy(key, ptr2, MAX_KEY + 1); } static void extract_podcast_play_all_params(char *string, char *course, char *key, int *grp) { char *ptr, *ptr2; ptr = strstr(string, "id^"); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "podcast_frama_playlist"); *ptr = '\0'; ptr++; strncpy(course, string, MAX_FILENAME +1); ptr2 = strchr(ptr, '^'); if(!ptr2) cs_critical_error(ERR_PARAM_MISSING, "podcast_frama_playlist"); *ptr2 = '\0'; ptr2++; ptr = strstr(ptr2, "grp^"); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "podcast_frama_playlist"); ptr--; *ptr = '\0'; strncpy(key, ptr2, MAX_KEY+1); ptr++; ptr2 = strchr(ptr, '^'); if(!ptr2) cs_critical_error(ERR_PARAM_MISSING, "podcast_frama_playlist"); *ptr2 = '\0'; ptr2++; ptr = strstr(ptr2, ".xml"); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "podcast_frama_playlist"); *ptr = '\0'; *grp = atoi(ptr2); } static void read_parameters (char *course, char *key, char *sender, char *fname, char *infname, char *sender_realname, char *title, int *grp, char *link) { char temp[MAX_PATH * 2 + 1]; char *ptr; *key = '\0'; *sender = '\0'; *fname = '\0'; *infname = '\0'; *sender_realname = '\0'; *title = '\0'; *grp = 0; *link = '\0'; /* if 'link' parameter exists, we're displaying a voice.mp3 lectern file ** the 'link' refers to the symbolic link created in the images/links ** directory. */ cs_get_optional_parameter ("link", temp, MAX_PATH * 2); if(strlen(temp)) { ptr = strstr(temp, ".xml"); if(!ptr) cs_critical_error(ERR_PARAM_MISSING, "link parameter doesn't contain '.xml'"); *ptr = '\0'; strncpy(link, temp, MAX_PATH +1); } else { cs_get_required_parameter ("crs", temp, MAX_PATH * 2); if(strstr(temp,"sender^")) extract_play_one_params(temp, course, sender, grp,fname, infname, sender_realname, title, key); else extract_podcast_play_all_params(temp, course, key, grp); } } static void memory_error () { cs_critical_error (ERR_MALLOC_FAILED, ""); }; static void free_attachment_list() { ATTACHMENT_NODE *ptr; while(attachment_head) { ptr = attachment_head; attachment_head = attachment_head -> next; free(ptr); } } static void build_attachment_list (MSG_TREE_NODE * msg, CONFIG_STRUCT *conf) { FILE *fp; int fd; char infopath[MAX_PATH + 1]; int i; ATTACHMENT_NODE *aptr = 0; NEWS_INFO info; int n_attachments; free_attachment_list(); if(!msg->data.info.attachments) return; n_attachments = abs(msg->data.info.attachments); /* since a -1 is used to flag an attached website */ snprintf (infopath, MAX_PATH + 1, "%s%s/%s/%s/%s", conf->course_path, PEOPLE_DIR, msg->data.info.sender, discussion_fname, msg->data.info_fname); fp = fopen (infopath, "r"); if (!fp) cs_critical_error (ERR_FOPEN_READ_FAILED, infopath); fd = fileno(fp); get_shared_lock(fd, 1); /* shared_lock.c */ if (fread (&info, sizeof (NEWS_INFO), 1, fp) != 1) cs_critical_error (ERR_FREAD_FAILED, infopath); /* process attachments, build linked list */ for (i = 1; i <= n_attachments; i++) { if (!attachment_head) { attachment_head = (ATTACHMENT_NODE *) malloc (sizeof (ATTACHMENT_NODE)); if (!attachment_head) memory_error (); aptr = attachment_head; } else { aptr->next = (ATTACHMENT_NODE *) malloc (sizeof (ATTACHMENT_NODE)); if (!aptr->next) memory_error (); aptr = aptr->next; } if (fread (&aptr->data, sizeof (ATTACHMENT), 1, fp) != 1) cs_critical_error (ERR_FREAD_FAILED, infopath); aptr->next = 0; } /* for .. */ release_lock(fd); /* shared_lock.c */ fclose(fp); } static void send_xml_escaped_string(char *string) { char *ptr; if(string) { for(ptr=string; *ptr; ptr++) switch(*ptr) { case '<': fputs("<", stdout); break; case '>': fputs(">", stdout); break; case '&': fputs("%26", stdout); break; case '=': fputs("%3D", stdout); break; case '?': fputs("%3F", stdout); break; case '"': fputs(""", stdout); break; case '\'': fputs("'", stdout); break; // case ' ': fputs("%20", stdout); // break; default: fputc(*ptr, stdout); break; } } } void send_one_item(MSG_TREE_NODE *msg_ptr, CONFIG_STRUCT *conf, const char *course, const char *server_string, const char *key, int grp) { char extension[MAX_FILENAME +1]; char path[MAX_PATH + 1]; int bitrate; build_attachment_list (msg_ptr, conf); if(attachment_head) { get_extension(attachment_head->data.orig_fname, extension); /* shared_news_util.c */ if(!strcmp(extension,"mp3")) /* player only supports mp3 files */ { snprintf (path, MAX_PATH + 1, "%s%s/%s/%s/%s", conf->course_path, PEOPLE_DIR, msg_ptr->data.info.sender, discussion_fname, attachment_head->data.unique_fname); bitrate = mp3_bitrate(path); /* shared_mp3_util.c */ puts(""); printf("%s/%s/send_file?crs=%s&id=%s&grp=%d&fname=%s&user=%s&info=%s&attach=1&dummy.%s\n", server_string, ALIAS, course, key, grp, attachment_head->data.unique_fname, msg_ptr->data.info.sender, msg_ptr->data.info_fname, extension); printf(""); send_xml_escaped_string(msg_ptr->data.info.subject); puts(""); printf(""); send_xml_escaped_string(msg_ptr->data.info.sender_realname); puts(""); printf("%d\n", bitrate== -1? 128: bitrate); printf("%s/%s/send_file?crs=%s&id=%s&grp=%d&fname=%s&user=%s&info=%s&attach=1&dummy.%s\n", server_string, ALIAS, course, key, grp, attachment_head->data.unique_fname, msg_ptr->data.info.sender, msg_ptr->data.info_fname, extension); puts(""); free_attachment_list(); } } } static void send_frama_playlist_data (CONFIG_STRUCT *conf, SESSION *user, const char *course, const char *key, int grp) { MSG_TREE_NODE *msg_ptr; time_t current_time; char server_string[MAX_PATH + 1]; /* current_time is declared globally */ build_msg_tree(user, PODCASTS, 0, 0, ¤t_time); /* shared_news_util.c */ puts ("Content-type:text/xml\n"); puts (""); puts (""); get_server_string(server_string, MAX_PATH +1); for(msg_ptr=tree_head; msg_ptr; msg_ptr=msg_ptr->next) send_one_item(msg_ptr, conf, course, server_string, key, grp); puts (""); free_msg_tree (tree_head); /* shared_news_util.c */ } void one_item_playlist(const char *course, const char *sender, const char *fname, const char *infname, char *sender_realname, char *title, int grp, const char *key, const char *link, CONFIG_STRUCT *conf) { char server_string[MAX_PATH + 1]; char grp_string[MAX_NAME+1]; char path[MAX_PATH + 1]; int bitrate; get_server_string(server_string, MAX_PATH +1); snprintf(grp_string, MAX_NAME +1, "&grp=%d", grp); puts ("Content-type:text/xml\n"); puts (""); puts (""); puts(""); if(strlen(link)) { printf("%s%s%s/%s/voice.mp3\n", server_string, IMAGE_PATH, "links", link); snprintf(path, MAX_PATH + 1, "%s/links/%s/voice.mp3", IMAGES_DIR, link); } else { printf("%s/%s/send_file?crs=%s&id=%s%s&fname=%s&user=%s&info=%s&attach=1&dummy.%s\n", server_string, ALIAS, course, key, grp!=MAIL? grp_string:"", fname, sender, infname, "mp3"); snprintf (path, MAX_PATH + 1, "%s%s/%s/%s/%s", conf->course_path, PEOPLE_DIR, sender, discussion_fname, fname); } printf(""); if(strlen(link)) printf("????"); else send_xml_escaped_string(title); puts(""); printf(""); if(strlen(link)) printf("????"); else send_xml_escaped_string(sender_realname); puts(""); bitrate = mp3_bitrate(path); /* shared_mp3_util.c */ printf("%d\n", bitrate == -1? 128 : bitrate ); if(strlen(link)) printf("%s%s%s/%s/voice.mp3\n", server_string, IMAGE_PATH, "links", link); else printf("%s/%s/send_file?crs=%s&id=%s%s&fname=%s&user=%s&info=%s&attach=1&dummy.%s\n", server_string, ALIAS, course, key, grp!=MAIL? grp_string:"", fname, sender, infname, "mp3"); puts(""); puts (""); } int main (void) { SESSION user; CONFIG_STRUCT conf; char course[MAX_PATH + 1]; int grp = 0; char fname[MAX_FILENAME +1]; char infname[MAX_FILENAME +1]; char sender[MAX_USERNAME +1]; char sender_realname[MAX_NAME +1]; char title[MAX_PATH +1]; char key[MAX_KEY +1]; char link[MAX_PATH +1]; *sender = '\0'; *link = '\0'; cs_cgi_init(); read_parameters (course, key, sender, fname, infname, sender_realname, title, &grp, link); if(!*link) /*then we are NOT playing a voice.mp3 file from the lectern_handler program */ { read_configuration_file (course, &conf); /* shared_util.c */ validate_key(key, &user, &conf); set_discussion_names (conf.course_path, user.username, grp); /* shared_news_util.c */ } if(*link) /* play voice.mp3 posted by lectern handler */ one_item_playlist(course, sender, fname, infname, sender_realname, title, grp, key, link, &conf); else if(!strlen(sender)) /* generate full playlist for podcast module */ send_frama_playlist_data (&conf, &user, course, key, grp); else /* play a single mp3 file - could be in any group */ one_item_playlist(course, sender, fname, infname, sender_realname, title, grp, key, link, &conf); cs_cgi_destroy(); return 0; }