#include #include #include #include #include "global.h" #include "manhat-lib/shared_util.h" #include "manhat-lib/shared_cs_util.h" #include "manhat-lib/shared_authenticate.h" /* for sub_dir_name() */ #include "manhat-lib/shared_strtrm.h" typedef struct semester_sort_node { char semester[MAX_SEMESTER + 1]; int expanded; int check_new; struct semester_sort_node *next; struct semester_sort_node *prev; } SEMESTER_SORT_NODE; static void read_parameters (char *key, int *item, int *up, int *check_unread) { char msg[50]; cs_get_required_parameter ("id", key, MAX_KEY); /* shared_cgi_util.c */ cs_get_required_parameter ("item", msg, 10); *item = atoi (msg); cs_get_optional_parameter("up", msg, 5); *up = strlen(msg); cs_get_optional_parameter("check_unread", msg, 5); *check_unread = strlen(msg); } static void rewrite_semester_sort_file(SEMESTER_SORT_NODE *head, const char *sort_file) { FILE *fp; SEMESTER_SORT_NODE *ptr; fp = fopen(sort_file, "w"); if(fp) /* ignore errors - this is not that important to interrupt the user on failure */ { for(ptr=head; ptr; ptr=ptr->next) fprintf(fp,"%s\n%d%s\n", ptr->semester, ptr->expanded?1:0, ptr->check_new?"*":""); fclose(fp); } } /** NOTE that this function make no attempt to preserve the 'prev' links *** in the linked list!!! ***/ static void move_semester_up(SEMESTER_SORT_NODE *head, int item, const char *sort_file) { SEMESTER_SORT_NODE *sptr; int i; if (item == 1) return; /* since the first item can't be moved up */ /* point sptr to the correct item */ for(sptr=head, i = 1; sptr && (i < item); sptr=sptr->next, i++); if(!sptr) return; /* since we've reached the end of the list without finding the item */ if(sptr == head) /* although we've already checked for this .. */ return; /* if item is #2 on the list */ if(sptr->prev == head) { head->next = sptr->next; sptr->next = head; head = sptr; } else { sptr->prev->prev->next = sptr; sptr->prev->next = sptr->next; sptr->next = sptr->prev; } rewrite_semester_sort_file(head,sort_file); } /** NOTE that this function make no attempt to preserve the 'prev' links *** in the linked list!!! ***/ static void move_semester_down( SEMESTER_SORT_NODE *head, int item, const char *sort_file) { SEMESTER_SORT_NODE *sptr; int i; /* point sptr to the correct item */ for(sptr=head, i = 1; sptr && (i < item); sptr=sptr->next, i++); if(!sptr) return; /* since we've reached the end of the list without finding the item */ if(!sptr->next) /* since this is already the last item in the list */ return; if(sptr == head) { head = head->next; sptr->next = head->next; head->next = sptr; } else { sptr->prev->next = sptr->next; sptr->next = sptr->next->next; sptr->prev->next->next = sptr; } rewrite_semester_sort_file(head,sort_file); } SEMESTER_SORT_NODE *build_semester_sort_list(const char *username, char *sort_file) { #define MAX_LINE 100 char line[MAX_LINE + 1]; char dirname; FILE *fp; SEMESTER_SORT_NODE *sort_head = 0, *ptr=0; dirname = sub_dir_name(username); /* shared_authenticate.c */ snprintf(sort_file, MAX_PATH + 1, "../%s/%c/%s/%s", USERS_DIR, dirname, username,SEMESTER_SORT_FNAME); fp = fopen(sort_file, "r"); if(fp) { while(fgets(line,MAX_LINE, fp)) { strtrm(line); /* shared_util.c*/ if(!sort_head) { sort_head = (SEMESTER_SORT_NODE *) malloc(sizeof(SEMESTER_SORT_NODE)); if(!sort_head) cs_critical_error(ERR_MALLOC_FAILED, ""); ptr = sort_head; ptr->prev = 0; } else { ptr->next = (SEMESTER_SORT_NODE *) malloc(sizeof(SEMESTER_SORT_NODE)); if(!ptr->next) cs_critical_error(ERR_MALLOC_FAILED, ""); ptr->next->prev = ptr; ptr = ptr->next; } strncpy(ptr->semester, line, MAX_SEMESTER + 1); /* next line contains info on whether or not this semester is 'expanded' */ if(fgets(line, MAX_LINE, fp)) { ptr->expanded = (*line == '1'); ptr->check_new = strchr(line, '*')? 1: 0; } else { ptr->expanded = 1; ptr ->check_new = 0; } ptr->next = 0; } /* while (fgets..) */ fclose(fp); } return sort_head; #undef MAX_LINE } void free_semester_sort_list(SEMESTER_SORT_NODE *head) { SEMESTER_SORT_NODE *ptr; while (head) { ptr = head->next; free (head); head = ptr; } } void move_semester(SESSION *user, int item, int up) { SEMESTER_SORT_NODE *sort_head; char sort_file[MAX_PATH + 1]; sort_head = build_semester_sort_list(user->username, sort_file); if(up) move_semester_up(sort_head,item, sort_file); else move_semester_down(sort_head, item, sort_file); free_semester_sort_list(sort_head); } void set_check_new(SESSION *user, int item) { SEMESTER_SORT_NODE *sort_head, *ptr; char sort_file[MAX_PATH + 1]; int i; sort_head = build_semester_sort_list(user->username, sort_file); for(ptr = sort_head, i=1; ptr; ptr = ptr->next, i++) { if(i == item) ptr->check_new = 1; else ptr->check_new = 0; } rewrite_semester_sort_file(sort_head,sort_file); free_semester_sort_list(sort_head); } int main (void) { SESSION user; char key[MAX_KEY + 1]; /* from id=? command line */ int item; /* from item=? command line */ int up; /* from optional up=? command line - which direction to move msg? */ int check_unread; /* from optional check_unread=? cmd line = check unread msgs for this item? */ cs_cgi_init(); read_parameters ( key, &item, &up, &check_unread); validate_server_key(key,&user); /* shared_util.c */ if(check_unread) set_check_new(&user, item); else move_semester(&user, item, up); printf ("Location: %s?id=%s\n\n", "mymanhattan", key); cs_cgi_destroy(); return 0; }