/***********************************************************************/ /* Course: Computer Science 402a */ /* Assignment: Assignment 2 */ /* Instructor: Mark Giesbrecht */ /* Submitted by: Dan Fraser */ /* Student Number: 001219229 */ /* Due Date: Wednesday, February 16 */ /***********************************************************************/ /* calendar.cc - Calendar implementation for the user client */ /***********************************************************************/ // see calendar.h for interface descriptions #include "calendar.h" #define TEMPSIZE 1024 #define TEMPINT_SIZE 50 pthread_mutex_t busy_mutex = PTHREAD_MUTEX_INITIALIZER; int my_uid = 0; int ns_port; string my_name; Busy busy; int main(int argc, char *argv[]) { pthread_t server_thread; int server_thread_id; pthread_attr_t server_attr; pthread_attr_init(&server_attr); ns_port = atoi(argv[1]); my_name = argv[2]; printf("starting server thread\n"); server_thread_id = pthread_create(&server_thread, &server_attr, server, (void *)NULL); printf("starting main tread\n"); while (1) { string response; print_menu(); cin >> response; switch (atoi(response.c_str())) { case 1: request_meeting(); break; case 2: busy.print(); break; case 3: cancel_meeting(); break; } } } void print_menu() { cout << endl << "main menu------" << endl; cout << "1. request (group) meeting" << endl; cout << "2. print calendar" << endl; cout << "3. cancel meeting(originated by you)" << endl; cout << "4. look up a uid" << endl; } void request_meeting() { int meeting_length; char temp[TEMPSIZE]; char *temp_str; vector times; vector times_backup; vector uids; Meeting *temp_meeting; string query; cout << endl << "enter length for the meeting (num of 15 min intervals): "; cin >> meeting_length; cout << "enter start times, separated by spaces: "; gets(temp); for (temp_str = strtok(temp," "); temp_str != NULL; temp_str = strtok(NULL," ")) { times.insert(times.end(),atoi(temp_str)); cout << "time " << temp_str << " inserted." << endl; } times_backup = times; cout << "enter uids, separated by spaces: "; gets(temp); for (temp_str = strtok(temp," "); temp_str != NULL; temp_str = strtok(NULL," ")) { uids.insert(uids.end(),atoi(temp_str)); cout << "uid " << temp_str << " inserted." << endl; } cout << "** adding meeting to originator's calendar" << endl; int rc = pthread_mutex_lock(&busy_mutex); if (rc) { perror("pthread_mutex lock"); pthread_exit(NULL); } temp_meeting = new Meeting(my_uid, meeting_length); for (vector::iterator p = uids.begin(); p != uids.end(); p++) { temp_meeting->addAttendee(*p); } temp_meeting->addAttendee(my_uid); temp_meeting->makeTentative(); for (vector::iterator p = times.begin(); p != times.end(); p++) { if(busy.check(*p, meeting_length)) { cout << "allocating meeting" << endl; busy.allocate(temp_meeting, *p, meeting_length); } else { cout << "erasing conflicting time" << endl; vector::iterator temp = p; times.erase(temp); } } if (times.size() <= 0) { cout << "** No meeting time possible **" << endl; busy.deallocate(temp_meeting); return; } rc = pthread_mutex_unlock(&busy_mutex); if (rc) { perror("pthread_mutex unlock"); pthread_exit(NULL); } cout << "okay, building request query" << endl; query = "meeting"; sprintf(temp, " %d %d", my_uid, meeting_length); query += temp; for (vector::const_iterator i = times.begin(); i != times.end(); i++) { sprintf(temp," %d",*i); query += temp; } cout << query << endl; for (vector::const_iterator i = uids.begin(); i != uids.end(); i++) { vector available_times; HostInfo hi("","",0); hi = uid_lookup(ns_port, *i); available_times = check_times(query, hi); cout << "checking availability" << endl; vector::iterator j = times.begin(); while ((j != times.end()) && (times.size() > 0)) { cout << "checking time " << *j << endl; if (find(available_times.begin(), available_times.end(), *j) == available_times.end()) { vector::iterator temp; temp = j; cout << "erasing conflicted time: " << *temp << endl; times.erase(temp); } j++; } if (times.size() == 0) { cout << "**** NO COMMON MEETING TIME POSSIBLE ****" << endl; // cancel meetings here cout << "okay, cancel request query" << endl; query = "cancel_temp"; for (vector::const_iterator i = times_backup.begin(); i != times_backup.end(); i++) { sprintf(temp," %d",*i); query += temp; } cout << "cancelling with query: "<::const_iterator i = uids.begin(); i != uids.end(); i++) { HostInfo hi("","",0); hi = uid_lookup(ns_port, *i); send_request(query,hi); } break; } } if (times.size() > 0) { // confirm meeting with myself cout << "* confirming local meeting" << endl; rc = pthread_mutex_lock(&busy_mutex); if (rc) { perror("pthread_mutex lock"); pthread_exit(NULL); } temp_meeting = busy.getMeeting(*times.begin()); if (!busy.deallocate(temp_meeting)) { perror("unable to deallocate local temp meeting"); return; } else { temp_meeting->makeConfirmed(); temp_meeting->setStart() = *times.begin(); busy.allocate(temp_meeting,*times.begin(), temp_meeting->getLength()); } rc = pthread_mutex_unlock(&busy_mutex); if (rc) { perror("pthread_mutex unlock"); pthread_exit(NULL); } // confirm meeting with all uid's char temp_int[TEMPINT_SIZE]; string query = "confirm "; sprintf(temp_int,"%d",*(times.begin())); query += temp_int; cout << "confirming with query: "<::const_iterator i = uids.begin(); i != uids.end(); i++) { HostInfo hi("","",0); hi = uid_lookup(ns_port, *i); send_request(query,hi); } } } void cancel_meeting() { char temp_int[TEMPINT_SIZE]; string cancel_message; int meeting_time; Meeting *del_meeting; vector *attendees; cout << "enter a time during the meeting to be deleted: "; cin >> meeting_time; del_meeting = busy.getMeeting(meeting_time); if (del_meeting == NULL) { cout << "there is no meeting at that time." << endl; return; } attendees = del_meeting->getAttendees(); if (find(attendees->begin(), attendees->end(), my_uid) == attendees->end()) { cout << "only the originator of a meeting can cancel it." << endl; return; } cancel_message = "cancel "; sprintf(temp_int, "%d", meeting_time); cancel_message += temp_int; for (vector::iterator p = attendees->begin(); p != attendees->end(); p++ ) { cout << "sending cancel message to uid " << *p << endl; HostInfo hi("","",0); hi = uid_lookup(ns_port, *p); send_request(cancel_message,hi); } } bool send_request(string request, HostInfo host) { StreamSocket user; char buffer[TEMPSIZE]; char *temp; if (user.connect(host.getHostname(), host.getPort())) { perror("couldn't connect to user"); return 0; } else { user.send(request); user.receive(buffer,sizeof(buffer)); temp = strtok(buffer," "); if (strcmp(temp,"OK") != 0) { perror("error returned by server"); return 0; } else { return 1; } } } vector check_times(string request, HostInfo host) { StreamSocket user; vector times; char buffer[TEMPSIZE]; char *temp; if (user.connect(host.getHostname(), host.getPort()) < 0) { perror("couldn't connect to uid"); } else { cout << "sending request" << endl; user.send(request); cout << "waiting for response" << endl; user.receive(buffer, sizeof(buffer)); cout << "got back: " << buffer << endl; temp = strtok(buffer," "); if (strcmp(temp,"OK") != 0) { perror("invalid response from server"); return times; } else { while ((temp = strtok(NULL, " ")) != NULL) { times.insert(times.begin(), atoi(temp)); cout << "inserted time: " << atoi(temp) << endl; } } } return times; } HostInfo uid_lookup(int port, int uid) { char *request = (char*) malloc(sizeof(char) * REQUEST_SIZE); char **result; char *temp; HostInfo hi("","",0); CLIENT *clnt; clnt = clnt_create(NAMESERVER_ADDR, NAMESERVER, DATE_VERS, "tcp"); sprintf(request, "%d",uid); result = find_1((char**)&request,clnt); temp = strtok(*result, " "); if (strcmp(temp,"OK") != 0) { perror("couldn't find user!"); exit(1); } temp = strtok(NULL," "); hi.setHostname() = temp; temp = strtok(NULL," "); hi.setPort() = atoi(temp); cout << "returning from name lookup" << endl; clnt_destroy(clnt); return hi; }