#include #include #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_post_inbox.h" #include "manhat-lib/shared_person_list.h" #include "manhat-lib/shared_news_util.h" #include "manhat-lib/shared_translate_url.h" /* for AMP_SUB, et. al */ #include "manhat-lib/shared_access.h" #include "manhat-lib/shared_lock.h" typedef struct inbox_node { INBOX_RECORD data; struct inbox_node *next; struct inbox_node *prev; long offset; } INBOX_NODE; INBOX_NODE *inbox_head = 0; INBOX_NODE *inbox_tail = 0; static void read_parameters (char *course, char *key) { cs_get_required_parameter ("crs", course, MAX_PATH); cs_get_required_parameter ("id", key, MAX_KEY); } static void set_inbox_commands (char *course, char *key,int can_write, int access, const char *fromstring) { char url[MAX_PATH +1]; snprintf (url, MAX_PATH +1, "%s?crs=%s&id=%s", "main_menu", course, key); cs_set_value("main_menu_url", url); snprintf (url, MAX_PATH +1, "%s?crs=%s&id=%s", "post_outbox", course, key); cs_set_value("post_outbox_url", url); if(can_write) { snprintf (url, MAX_PATH +1, "%s?crs=%s&id=%s&from=%s","post_new_memo", course, key, fromstring); cs_set_value("new_memo_url", url); } cs_set_int_value("outbox", 0); } static void build_inbox_list (CONFIG_STRUCT *conf, SESSION *user) { FILE *fp; char inbox_path[MAX_PATH + 1]; INBOX_RECORD msg; INBOX_NODE *ptr = 0; long offset = 0; snprintf (inbox_path, MAX_PATH + 1, "%s%s/%s/%s/%s", conf->course_path,PEOPLE_DIR, user->username, MAIL_DIR, INBOX_FNAME); fp = fopen (inbox_path, "r"); if (fp) { get_shared_lock(fileno(fp), 1); /* shared_lock.c */ while (fread (&msg, sizeof (INBOX_RECORD), 1, fp) == 1) { if (msg.newfile_info.how_sent != DELETED) { /* 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); } release_lock(fileno(fp)); fclose (fp); } } static void free_inbox_list () { INBOX_NODE *ptr; while (inbox_head) { ptr = inbox_head; inbox_head = inbox_head->next; free (ptr); } } void set_inbox_msgs (char *course, char *key, NEWS_FILTER * filter, CONFIG_STRUCT *conf, SESSION *user, int can_write, int allow_user_hidden) { #define MAX_TMP_NAME 30 int unread; char timestring[MAX_TIMESTRING + 1]; INBOX_NODE *ptr; char name[MAX_TMP_NAME]; char url[MAX_PATH +1]; int i; char *escaped_subject = (char *) 0; int fixed_width_font; fixed_width_font = USE_FIXED_FONT(conf->misc); /* global.h */ cs_set_int_value("fixed_font", fixed_width_font? 1: 0); cs_set_int_value("allow_user_hidden", allow_user_hidden? 1 : 0); if (inbox_head) { for (i = 0, ptr = filter->oldest_first ? inbox_head : inbox_tail; ptr; ptr = filter->oldest_first ? ptr->next : ptr->prev, i++) { if(!allow_user_hidden || filter->show_user_hidden || !ptr->data.is_sleepy) { unread = !ptr->data.time_read; if(allow_user_hidden && !unread) { if(ptr->data.is_sleepy) { snprintf(name, MAX_TMP_NAME, "msg.%d.unhide_url", i); snprintf(url, MAX_PATH +1, "%s?crs=%s&id=%s&loc=%ld&hide=%d", "post_mark_hidden", course, key, ptr->offset,0); cs_set_value(name, url); } else { snprintf(name, MAX_TMP_NAME, "msg.%d.hide_url", i); snprintf(url, MAX_PATH +1, "%s?crs=%s&id=%s&loc=%ld&hide=%d", "post_mark_hidden", course, key, ptr->offset,1); cs_set_value(name, url); } } snprintf(name, MAX_TMP_NAME, "msg.%d.is_unread", i); cs_set_int_value(name, unread? 1:0); snprintf(name, MAX_TMP_NAME, "msg.%d.has_attachments", i); cs_set_int_value(name, ptr->data.newfile_info.attachments? 1:0); snprintf(name, MAX_TMP_NAME, "msg.%d.info_url", i); snprintf (url, MAX_PATH +1, "%s?crs=%s&id=%s&loc=%ld&from=%s%ccrs%c%s%cid%c%s", "post_inbox_info", course, key, ptr->offset, "post_inbox", QMARK_SUB, EQUAL_SUB, course, AMP_SUB, EQUAL_SUB, key); cs_set_value(name, url); snprintf(name, MAX_TMP_NAME, "msg.%d.read_msg_url", i); snprintf (url, MAX_PATH +1, "%s?crs=%s&id=%s&loc=%ld", "post_read_inbox", course, key, ptr->offset); if(fixed_width_font) strcat(url,"&fixed=1"); cs_set_value(name, url); /* handle subject - need to html escape it */ snprintf(name, MAX_TMP_NAME, "msg.%d.subject", i); if(cgi_html_escape_strfunc(ptr->data.newfile_info.subject,&escaped_subject) == STATUS_OK) cs_set_value(name, escaped_subject); else cs_set_value(name, ptr->data.newfile_info.subject); if(escaped_subject) { free(escaped_subject); escaped_subject = (char *) 0; } snprintf(name, MAX_TMP_NAME, "msg.%d.sender", i); cs_set_value(name, ptr->data.newfile_info.sender_realname); /*shared_format_line.c */ strftime (timestring, MAX_TIMESTRING, DOW_DATE_FORMAT, localtime (&ptr->data.newfile_info.time_sent)); snprintf(name, MAX_TMP_NAME, "msg.%d.time_sent", i); cs_set_value(name, timestring); /* insert delete link */ if(can_write && !unread) { snprintf(name, MAX_TMP_NAME, "msg.%d.delete_url", i); snprintf(url, MAX_PATH +1, "%s?crs=%s&id=%s&loc=%ld&next=-1" , "post_delete", course, key, ptr->offset); cs_set_value(name, url); } } } } /* if inbox_head */ #undef MAX_TMP_NAME } static void read_inbox_filter (NEWS_FILTER * filter, CONFIG_STRUCT *conf, SESSION *user) { FILE *fp; char filter_path[MAX_PATH + 1]; filter->oldest_first = 1; filter->show_user_hidden = 1; /* always show oldest first in capture mode */ if(conf->access == ACCESS_CAPTURE) return; snprintf (filter_path, MAX_PATH + 1, "%s%s/%s/%s/%s", conf->course_path, PEOPLE_DIR, user->username, MAIL_DIR, NEWS_FILTER_FNAME); fp = fopen (filter_path, "r"); if (fp) { if(fread (filter, sizeof (NEWS_FILTER), 1, fp) != 1) { filter->oldest_first = 1; filter->show_user_hidden = 1; } fclose (fp); } } static void set_gather_form (char *course, char *key, CONFIG_STRUCT *conf) { P_NODE *p; cs_set_value("gather_action", "post_inbox_gather"); p = build_option_person_list (conf); /* shared_person_list.c */ set_option_userlist (p); /* shared_person_list.c */ free_option_person_list (p); /* shared_person_list.c */ } static void set_sort_url (char *course, char *key, int oldestfirst, const char *fromstring) { char url[MAX_PATH +1]; snprintf (url, MAX_PATH +1, "%s?crs=%s&id=%s&grp=%d&cmd=%d&from=%s", "news_filter_set", course, key, MAIL, oldestfirst? 1 : 0, fromstring); cs_set_value("sort_order_url", url); } static void set_sleepy_urls(NEWS_FILTER *filter,const char *fromstring, const char *course, const char *key) { INBOX_NODE *ptr; int hidden_count; char url[MAX_PATH*2 +1]; /* count topics marked as 'hidden' by the user */ for(ptr=inbox_head, hidden_count=0; ptr; ptr=ptr->next) if(ptr->data.is_sleepy) hidden_count++; cs_set_int_value("hidden_count", hidden_count); if(filter->show_user_hidden) { snprintf (url, MAX_PATH *2 +1, "%s?crs=%s&id=%s&grp=%d&cmd=%d&from=%s", "news_filter_set", course, key, MAIL, HIDE_USER_HIDDEN, fromstring); cs_set_value("hide_sleepy_url", url); } else { snprintf (url, MAX_PATH *2, "%s?crs=%s&id=%s&grp=%d&cmd=%d&from=%s", "news_filter_set", course, key, MAIL, SHOW_USER_HIDDEN, fromstring); cs_set_value("list_all_url", url); } } static void set_inbox_data (char *course, char *key, CONFIG_STRUCT *conf, SESSION *user, int can_write) { NEWS_FILTER filter; char fromstring[MAX_FROM + 1]; int allow_user_hidden; cs_set_value("crs", course); cs_set_value("id", key); cs_set_course_info(conf); cs_set_current_time(); cs_set_int_value("can_write", can_write? 1 : 0 ); cs_set_int_value("capture_mode", (conf->access == ACCESS_CAPTURE)? 1: 0); allow_user_hidden = (conf->postoffice == 2); read_inbox_filter (&filter, conf, user); build_inbox_list (conf, user); snprintf(fromstring, MAX_FROM + 1, "%s%ccrs%c%s%cid%c%s", "post_inbox",QMARK_SUB,EQUAL_SUB,course,AMP_SUB,EQUAL_SUB,key); set_inbox_commands (course, key, can_write, conf->access, fromstring); /* show gather form, reverse order button and show sleepy options ** only if we are not ** capturing this course */ if(conf->access != ACCESS_CAPTURE) { set_gather_form (course, key, conf); set_sort_url(course,key, filter.oldest_first, fromstring); if(allow_user_hidden) set_sleepy_urls(&filter, fromstring, course, key); } set_inbox_msgs (course, key, &filter, conf, user, can_write, allow_user_hidden); free_inbox_list (); } int main (void) { char course[MAX_PATH + 1]; /* from crs=? command line */ char key[MAX_KEY + 1]; /* from id=? command line */ SESSION user; CONFIG_STRUCT conf; /* the configuration read from config file */ int can_write; /* can this user add msgs to this course? */ cs_cgi_init(); read_parameters (course, key); read_configuration_file (course, &conf); /* shared_util.c */ validate_key (key, &user, &conf); /* shared_util.c */ can_write = has_write_permission(&user, &conf); /* shared_access.c */ #ifndef SUPPORT_PRE24_POST_OFFICE_MSGS update_post_inbox (user.username, &conf); /* shared_post_inbox.c */ #else if(SUPPORT_PRE24_POST_OFFICE_MSGS) update_post_inbox (user.username, &conf); /* shared_post_inbox.c */ #endif if(!conf.postoffice) cs_critical_error(ERR_REQUEST_DENIED, ""); set_inbox_data (course, key, &conf, &user, can_write); /* NOTE: post_inbox_outbox.cs is used for both post_inbox.c and post_outbox.c */ cs_cgi_display("post_inbox_outbox", 1); cs_cgi_destroy(); return 0; }