PHONEDATION

Directory Services – Team 4

Matt Steinberg & David Botsch

 

 

1. The Task Before Us

 

Our job was to provide directory service to the Phonedation team. What exactly is directory service in the case of internet telephony? Directory service is just that, the phone book for the Phonedation team. We are an electronic version of the phone book sent out by phone companies. We are a modified version of a domain name server. We are a database containing pertinent pieces of information and methods by which these pieces of information may be modified or retrieved.

 

The main goal of directory service is to provide information on each user of the Phonedation system. We wanted to implement lookups where if one knew the last name of a person, one could determine the phone number of that user or if one knew the ip address at which a person was located, one could lookup that person’s email address. But these services are not provided solely for the purpose of the end user. They are also being provided so that other teams can keep track of who is where in the system and what that person is doing. For example, we planned to keep track of conference information so that the conference team could determine if a person was in a conference, the location of that conference, and who and how many people are in the conference.

 

How do we keep track of all this information? As previously mentioned, we decided to use a database, but the database to be was to be written from scratch. We set out to write our database from the ground level up eliminating the need for the usage of any proprietary software with licenses such as SQL database servers. From scratch, we set out to find the most efficient way to store and organize this information, and then the best way to work with this information, all using the C++ programming language.

 

As mentioned, among this was the need to service the needs of other teams in the Phonedation group. It is the job of directory service to keep track of most of the information the other teams will be working with. So, we had to send out a call for a request for functions. We had to show the other teams what we had decided to store in our database and ask them if this information met their needs. We then had to request information from the other teams regarding what functionality they would need us to support. For example, did a team need to be able to retrieve a user-id based on someone’s email? Did a team need to be able to add new users to the database as well as delete and modify their entries? Did a team need to know who was in a conference? Did a team need first and last names looked up from a user-id? Was there a need for user-ids at all? Was there a need for passwords?

 

Directory service also needed to determine how to communicate with other teams. Normally, someone looks up a phone number by last name in the phone book or dials 411 and then finds the phone number through that type of interface. We found that different teams needed to talk to directory service in different ways. Our goal was to write our database code to run under UNIX using the C++ programming language. So, we needed to know who was using what programming language and whether they were running their code on UNIX or Windows NT. This would determine the interface we would provide. Originally, we set out to provide a network (sockets) interface. This was then changed after meetings to better meet the needs of other teams to a Java interface running under Windows NT. The final solution we would have to provide would be a mishmash of the preceding. It would turn out that some teams would need to communicate with us through sockets directly, some would need to communicate with us through C++ code, and some would need to communicate with us through a Java interface. We therefore had to support all of these interfaces.

 

Our first goal was then to build a working database and be able to manipulate the data within it. With this marginally achieved, we would then set out to write a socket interface in C++ to run under UNIX and Windows NT. This would then have to be converted to a Java interface for those teams that needed to communicate with us in that manner. So, our goals kept changing, but finally, we set out to do a combination of all.

 

Our last goal was to help other teams integrate successfully with our directory service. We had to decide what to support and what not to support based on the time limitations. We had to decide what would theoretically be included in version 2. Based on what we were able to provide and the interfaces we were supporting, we had to provide specs to other teams regarding exactly what to do if they wanted a user's phone number or email address.

 

 

2. Our Accomplishments

 

We actually feel that we accomplished everything we set out to do. By the time of the demo, we had completed all of our code and tested it sufficiently. Our server was up and running on babbage, awaiting calls from any of the application teams as well as the signaling and billing groups.

 

In regards to the database, although we elected not to implement a pre-existing database (e.g. – SQL server), we feel that we successfully integrated our own, original, fully functional database. This database, as well as all of the server code, was written in the C++ programming language on a UNIX platform. We started with a simple text file. From there we developed the following entry format for each instance in the database:

 

Sample record:

?

:lname: last name

:fname: first name

:mi: middle initial

:pw: password - numerical

:em: email address

:ph0: current phone number in use (dynamic)

:ph1: phone number + extension -priority 1 (4-noon)

:ph2: phone number priority 2 (noon-8)

:ph3: phone number priority 3 (8-4)

:ip0: current ip in use (dynamic)

:ip1: ip priority 1 (same times)

:ip2: ip priority 2

:ip3: ip priority 3

:uname: username - numerical

:cgrname: conference group name – dynamic

:cgrprio: conference group priority (public (1) or private (0-default))

:cgrpass: conference group password - dynamic

 

We started each entry with a ‘?’. This proved useful in locating a particular entry number in the database that was used when we wanted to access a particular record either to look-up values or to edit the entry. After that we included the remaining fields. Each entry begins with a ‘:’, is followed by the name of the field, another ‘:’, and finally the data. We also took measure to ensure that every line (including the ‘?’) ended with the C/C++ character ‘\n’, denoting the end of a line, such that we could recognize the end of an entry by searching for the ‘\n’ character.

 

From this point, we set the next 3 entries as the base user information; the first name, last name and middle initial of each user are stored here. In addition to the name, we also stored email account addresses. This data was primarily provided for the billing services and the voice-to-email application.

Other data we stored were a user-id number and password for each user. The primary purpose of this information was for authentication. We used a user-id lookup in the database and then compared the stored password with the given input and returned an "okay" verification or an authorization failed message.

 

In order to account for the possibility of a person changing locations, we allocated 4 different ip addresses as well as 4 different telephone numbers for each user. The ph0 and ip0 entries represent the first-priority entry. This entry can be manually edited by any of the other system groups to acknowledge a user’s presence at a particular ip address or telephone number. The remaining entries are default entries, prioritized by the time of day. As is indicated above, the ip1/ph1 entry is the default for the hours of 4:00 A.M. until 12:00 P.M., ip2/ph2 represent the user’s location from 12:00 P.M. until 8:00 P.M. and finally, ip3/ph3, which represent the 8:00 P.M. to 4:00 A.M. time-slot. We based these hours upon the probability of a given user being at a certain place during different hours of the day. Ip1/ph1 and ip2/ph2 were designed to encompass the typical workday hours while ip3/ph3 suggest that the user would be at home.

 

The final data we included was conferencing group information. This data is exclusive to the Conferencing/whiteboard application, which sets up whiteboard conferencing for a set of users. To assist them in their task, we stored which conference group (if any) our system users belonged to as well as a password needed to join a conference group (authentication was implemented similarly to the user-id/password method). We finally added a priority value which denotes an active or inactive user as well as the owner, or creator, of the group.

 

Having established our database format, we then designed some very low-level data manipulation methods to be called by our higher-level functions. We began by implementing the means to read a record in from the database, write a record out to the database and search for a given value in a given field. It was also necessary to incorporate various methods to open and close the database via input and output streams and construct and deconstruct a database entry.

 

From these basic methods, we then constructed the higher level functions that would eventually represent the user-interface. Based on what each group needed and a few extras that we chose to include, we set out to write these various functions. More detail about the specific methods can be found in Chapter 6.

 

Finally, we implemented socket functionality between this base server and a native C program that would provide the actual interface to other teams. By calling either the C or JAVA code functions provided, the other teams were then able to include either the appropriate header file or dynamically linked library (.dll file) to make the function calls. The C code took this incoming data and set up a client-server connection with the C++ server and then sent in the requests. The server then decoded the request, called the appropriate function(s) and returned the output.

Upon completion of the database, surrounding functions, and necessary socket programming, we set about the task of thoroughly testing our code from each level (server level, C to server socket level, and JAVA to C interface). Once all of the bugs, glitches, and mismatches were ironed out, we copied our code into the directory set up for our group and set it running.

 

As a final note to our list of accomplishments, we would like to recognize two tasks, which we never thought we would be working on, but actually completed with success. First of all, we never intended to support more than one or two different methods of interface. We had originally figured on perhaps supporting two, one for JAVA and one for C++, or possibly one for Windows NT platform and one for the UNIX platform. We wound up supporting about eight different styles of interfacing: 1) Direct socket calls from C/C++ code running on UNIX, 2) Direct socket calls from JAVA running on UNIX, 3) Direct socket calls from C/C++ running on Windows NT, 4) Direct socket calls from JAVA running on Windows NT, 5) Direct function calls via a header file in C/C++ on Windows NT, 6) Direct function calls via header file in C/C++ on UNIX, 7) Direct function calls via dynamically linked library in JAVA on Windows NT, and finally, 8) Direct function calls via dynamically linked library in JAVA on UNIX. Thus, we had to write our base server in C++, a C file to make the socket connections to the C++ server and JAVA native classes to call the C code. Needless to say, this was a tedious process. Also, as a result of creating so many interfaces, we wound up having to educate many of our teammates as to the functionality of the individual interfaces and as a result, spend many an hour debugging code for our fellow Phonedationers.

 

 

3. The Problems

 

This subject is quite large. Then again, what programming project is not filled with bugs galore? It is hard to know where to start. The initial problem was in figuring out how to design the database. What data do we need to store? How do we format the database? How do we mark the beginning of new records and the beginning and end of each field? We had to search to find characters that would not be used in the fields but were yet not reserved characters such as the backslash and the dollar sign. The next major problem came in parsing data read in from the database. We ran into all sorts of problems related to the file pointer being in the wrong place and the correct usage of ifstream.getchar() versus ifstream.getline(). We simply could not get either to work We thought that we had fixed the problem by using for loops and getchar() in place of getline(). This fix only worked for a short time. If one character was off, then things went, well, the typical C++ wacky. Since the characters we were fetching were being placed into strings that were being compared using strcmp(), being off by one character caused functions such as datalocate to fail miserably. I have to give special commendation to Kiri Wagstaff for helping us to sort out this minor yet major bug which was throwing off everything. We also had problems with the atoi() function call. Once again, Kiri came to the rescue, worked some magic, and getline() and atoi() both functioned as they should. Unfortunately, we spent a lot of time building our code around the erroneus atoi() and getchar(). Once things stopped working, we took to major panic. Thank goodness for Kiri.

 

We continued to debug functions and found that methods that used double lookups (example being searching for a last name and then checking to make sure the first name matched). Our program was skipping records due to the input file stream pointer not being placed correctly. We finally managed to fix this by declaring a second input file stream pointer and using it. This, however, introduced another problem. The first input file stream was declared as a member of the class in our C++ code. The parameter being passed to functions used the name of this stream, such that any attempt to modify either pointer resulted in the modification of the original pointer only. So the input parameter to any member functions taking in an input file stream had to be modified with a unique name. The same problem was true for the rest of the data members of the class. When passing them, the input parameters had to use different names so that we were modifying only the value passed and returning it if we wanted. Keeping the same name, like with the input file stream, would result in instant modification of the class data members and instant (or gradual) disaster.

The rest of the coding bugs consisted of minor things such as misplacing parentheses or misplacing a null character. As we tested integrating with other teams, we would find that a tad of extra functionality such as the need to not check passwords with public conferences was needed.

 

This brings us to the other major problems. Integration. Integration required supporting approximately 8 different interfaces depending on the needs of each individual group. As each new minor bug was then found, each interface had to be updated and redone. A major problem was the Java to C to sockets interface. The C++ had to be rewritten so that it could be called from native Java calls. The C++ also had to be written to run under Windows NT as well as UNIX. Once again, Kiri came to the rescue by helping us to convert the C++ to properly run under Windows NT and writing the Java interface that would overlay it.

 

The main point of integration was then turned to focusing on actually communicating with other teams and making sure that what they requested was actually supported and worked. Almost each function had to be tested on its own by us first and was found to be buggy in some way or another. A problem later discovered was in the C++ interface. The exact problem involved working with a global pointer to a string from which the data received from the socket was written. When we tested, we only tested one function at a time, so the bug did not show itself until a member of Team 7 asked us why when looking up first name, last name, and email address, he was getting the same email address returned three times. The fix was rather simple – a separate buffer (25 to be exact) had to be declared for each function that read from the socket so that successive calls to different functions would not overwrite the buffer before its results were used.

More integration problems were to follow. We actually found ourselves becoming teachers, having to show others how to follow the calling conventions we had set up for our code. If the calling conventions were not properly followed, random happenings from the wrong record being modified to the server hanging or segment faulting would happen. We had to track down each individual group and make sure each individual group was using the correct calls with the correct parameters down to the character.

One instance of these problems resulted when interfacing with Team 10. After approximately an hour of attempting to get our code to compile with hers so that she could contact our server, we found that a missing "int i" and more importantly, a wacky compiler option causing Microsoft Visual Studio to look for precompiled headers (of which there were none) was causing the problems.

 

The saga continued with integration with the Conferencing group. Things slowed as their functions were the last that we debugged. Once operational, though, we had problems with getting the group to properly pass parameters to our server. The results would be conferences either being generated or removed at seemingly random times. We also discovered a miscommunication in that public conferences did not need a password. Fortunately, a simple if statement fixed this. Even so, we still had to tell conferencing to pass in a password for public conferences as null characters crash the code. We also are continuing to have problems with conferencing not being able to properly keep track of their data (this means they remove the owner of a conference from a conference, but leave everyone else in the conference). And we still had to work out the issue of conferencing passing in null passwords with private conferences. This would have the result of the conference then being untouchable in our database and having to be removed by hand. Most of these problems, though, were due to bugs still being worked out by Conferencing on their side where information was not making it from their GUI to their function calls. These problems, though, seem to lead to extremely occasional broken pipes. We can find no reason for this, and our best guess is a premature closing of the tcp socket connection.

Finally, the worst problems were seemingly random segmentation faults of our server. After resolving all of the above, the server would still occasionally crash, with no apparent cause nor rhyme nor reason. We scratched our heads and could find nothing wrong. The reason became apparent when Team 2 approached us with questions as to why our code was not working. The bottom line is that they had not yet worked out their Java code that was running under UNIX. From the Java, they were making direct socket calls to our C++ server, however, they were sending null strings. This would hang or crash the server every time. As of the time of this writing, no progress has been made, even after hours of working with Team 2 to attempt to resolve the problem. Even Kiri has had no luck – none of us simply know enough about Java sockets. And, unfortunately, the language barrier proved to be a great problem in communicating with the Team 2 members. We did propose the solution of them communicating with our UNIX C++ interface which did make the socket calls properly to our server, but the language barrier plus the stubbornness of Team 2 made this solution unfeasible. The hours spent with Conferencing resulted in working out most of their calling convention problems. The time spent with Team 2 has essentially been frustrating and a waste. The only plus to the situation is to know the problem is not on our end. We cannot do anything with null strings, and as we expect everyone to conform to calling conventions we let what will happen happen when people do not. This problem still remains. It would be to our advantage to throw in some exception code so that Team 2 could not crash or hang the server, but the problem of time running out has not permitted this. Coming in version 2 . .

The last problem would be network connections to babbage going down from time to time. Our code is C++ UNIX code, and the only system available is babbage. With the connections constantly freezing up for several minutes at a time, development and testing was slowed considerably. Fortunately, babbage would decide to come back online and we could continue working.

 

 

4. What We Learned

 

Throughout the progression of this project from conception to completion, we discovered many things, both technical and social, that we believe have taught us about programming and about ourselves. As for the technical issues, this assignment left us open range to take our portion of the project essentially wherever we chose. We would like to think that we took advantage of this opportunity to explore many aspects of directory services. To begin with, we elected not to utilize a pre-existing database package (like SQL server). Our reasoning for doing so was a desire to understand the internal workings of a database. This resulted in a good low-level comprehension of a basic database. We discovered how to read and write to and from a database by utilizing input and output streams. In addition, we now see how a database should be structured as far as organization goes. Although we did not implement this, we can clearly see the necessary steps needed to implement a sorting algorithm on the data. We elected to use a simpler method of assigning user-id’s in a sequential manner to ensure some order in our database. In general, we developed a greater respect for those who have designed and written databases because we know how challenging they can be.

Beyond the scope of the database, we learned how design packets to be sent over sockets so as to make the string decoding as simple as possible. We developed methods to place headers in our packets that would simplify the decoding process and a clever manner of delimiting the values for the same effect. Finally, once we realized how many different interfaces we would have to support, it was necessary to explore JAVA native class structures and how to write sockets strictly in C (no C++).

 

Regarding the social issues, we were, for the first time, forced to work in a large group, which can create numerous issues, both good and bad. Due to the busy schedules of the average CS major, getting all of our teammates together proved to be a big problem. Finding one time when twenty people, each with different schedules, could all get together turned out to be nearly impossible. This forced us to rely on good communication skills to ensure that everyone was on the same wavelength. We also learned a lot about cooperation and compromising. The former came in to play mostly towards the end when we had to get all of our various components working together. This involved a lot of close collaboration with the numerous groups that were interfacing with each other. This lead to the latter part, compromise. Many an instance occurred when one group would request a certain functionality that was either beyond the scope of our ability or simply not worth the amount of time required to implement it. We went about these conflicts by each giving a little and taking a little; working out what could be done to make both groups happy, or happier at least. As for the number of hours in the day, well, there aren’t enough of them. Due to strenuous course loads, we both had to give up a lot of sleep or relaxation time in order to complete our tasks. We both feel that we planned our work schedules to the best of our ability but still found ourselves running out of time. We have come to the conclusion that despite our efforts to plan ahead, there are simply times when you gotta do what you gotta do to get the job done.

 

 

5. What We Would Do Different in v. 2.0

 

In general we were quite happy with the outcome of this project. However, there are definitely some changes we would make. In the general sense, we would have liked to have a better game plan. At times, our group seemed a bit disheveled, each team working on their own part of the project and not communicating their needs immediately. This resulted in numerous scrambles in the last couple of weeks to get essential data from other groups. For example, many groups requested certain functionalities of our database system in the past week that were simply too large to implement at that late a point. We wish we had been able to do so, but there were just not enough hours in the day. Late planning also resulted in us having to create and support so many different interfaces. This is something we definitely would have rather not done.

 

Due to our time limitations, there are a few things we would have liked to either re-do or just do for the first time. As far as the actual database goes, we would have like to add some features. For example, we would have liked to implement a sorting algorithm and graphical interface to create a database similar to those found in commercial use today. In addition, we could have implemented some other, smaller storage facilities to hold data. For example, the conferencing group had requested a list of all existing conferences which required simply too much additional coding to implement. In regards to the database control, we would have liked to streamline and simplify some of the coding, as we realize that equivalent functionality could have been encoded more efficiently. We also found that we were passing references to class objects too often. This was unnecessary and excessive, but by the time we discovered this, it was too late to change. Having additional passings of references did not affect the functionality of the database, but probably resulted in less efficient coding.

 

The remaining changes we would have made relate to the sockets. Given enough time, we would have implemented a multiple access protocol allowing multiple users to access the database at the same time, rather than storing database requests in a waiting queue. We would also have implemented more error correction and exception handling, especially in regards to dealing with null pointer exceptions.

 

6. The Interface

 

The Java functions to be called by any team coding in JAVA on Windows NT:

 

// ------- Database Accessing -------- //

// Given one of the above intypes, some data, and an outtype,

// return the desired data

native String DSLookup(int intype, String data, int outtype);

 

// ------- User Profiles ------------- //

// Add a new user profile, returns a string of the form

// "userid.password"

native String AddProfile(String fullname, String email);

 

// Delete a profile, given a userid and pword

native void DeleteProfile(String userid, String pword);

 

// Edit a profile

// Each user is allowed four phone numbers (and four ip addrs) that

// correspond to different times of day (see Team 4 for details).

// IPs must be a string in the form www.xxx.yyy.zzz.

// You must fill in all arguments.

native void EditProfileA(String userid, String pword, String fullname,

String email);

native void EditProfileIPs(String userid, String pword,

String ip1, String ip2, String ip3);

native void EditProfilePhones(String userid, String pword,

String phone1, String phone2, String phone3);

native void EditProfileIP(String userid, String pword, String ip);

native void EditProfilePhone(String userid, String pword, String phone);

 

// ------- Conferencing -------------- //

// Set priority to 1 for a public conf, 0 for a private conf.

// pword is ignored for a public conference.

native void CreateNewConference(String cname, String userid,

int priority, String pword);

native void DeleteConference(String cname, String userid, String pword);

 

// Return the multicast IP address

native String GetMulticastAddr(String cname);

 

// Return 1 for public, 0 for private

native int GetConfPublic(String cname);

 

// Return password for the conference

native String GetConfPword(String cname);

 

// Return all userids in the conference

native String GetMemberList(String cname);

 

// Return password for the conference

native String GetConfPword(String cname);

 

// Return all userids in the conference

native String GetMemberList(String cname);

 

// Return the number of members in the conference

native int GetNumMembers(String cname);

 

native void AddUser(String userid, String cname, String cpword);

native void DeleteUser(String userid, String cname);

 

// Verify that password matches user

// Return 0 for fail, 1 for success

native int Verify(String userid, String pword);

 

ds.h C header file for Windows NT C/C++ coders

 

/* Add profile */

char * addprofile(char *lname, char *fname, char * em);

 

/* Delete profile */

void delprofile(char * uname, char * pw);

 

/* Username lookup based on ip address */

char * unamelookup(char * ip);

 

/* Look up IP by lname, fname */

char * iplflookup(char * lname, char * fname);

 

/* Lookup phone # by uname */

char * phlflookup(char * uname);

 

/* Lookup first name by uname */

char * fnulookup(char * uname);

 

/* Lookup last name by uname */

char * lnulookup(char * uname);

 

/* Lookup email by uname */

char * emulookup(char * uname);

 

/* Lookup email by lname, fname */

char * emlflookup(char * lname, char * fname);

 

/* Lookup email by phone number */

char * emph (char * phone);

 

/* Lookup ip by phone number */

char * ipphlookup (char * phone);

 

/* Verify uname, pw */

int verify(char * uname, char * pw);

 

/* Functions to edit profile */

void editprofilea(char *uname, char *pw, char *fname, char *lname, char *email);

 

void editprofileips(char * uname, char * pw, char * ip1, char * ip2, char * ip3);

 

void editprofilephones(char *uname, char *pw, char *phone1, char *phone2, char * phone3);

 

/* for when a user logs in/out ip */

void editprofileip(char * uname, char * pw, char * ip0);

 

/* for when a user logs in/out phone */

void editprofilephone(char * uname, char * pw, char * phone0);

 

/* looks up uid based on email */

char * uidemlookup(char * email);

 

/* Conference functions */

 

/* Returns uids in a conference */

char * uidsconf(char * confname);

 

/* Returns total # in a group */

char * totalnumingroup(char * confname);

 

/* Create a new conference - associated w. userid of creator */

void createconf(char * uname, char * confname, char * prio, char * confpw);

 

/* Join a conference already created - returns success bool */

int joinconf(char * uname, char * confname, char * confpw);

 

/* Leave a conference */

void leaveconf(char * uname, char * confname);

 

/* Destroy a conference - possible only by creator */

int destroyconf(char * uname, char * confname, char * confpw);

 

/* Get conference ip address */

char * getconfip(char * confname);

 

Socket Interface called by either JAVA or C/C++ programmers

*NOTE: the sprintf statements below the function call represents what is written to the socket. Any functions that return values return char * from the socket which will be converted to the desired form.

 

/* Add profile */

char * addprofile(char *lname, char *fname, char * em)

sprintf(buffer,"A#%s#%s#%s",lname,fname,em);

 

/* Delete profile */

void delprofile(char * uname, char * pw)

sprintf(buffer,"B#%s#%s\0",uname,pw);

 

/* Username lookup based on ip address */

char * unamelookup(char * ip)

sprintf(buffer,"C#%s\0",ip);

 

/* Look up IP by lname, fname */

char * iplflookup(char * lname, char * fname)

sprintf(buffer,"D#%s#%s\0",lname,fname);

 

/* Lookup phone # by uname */

char * phlflookup(char * uname)

sprintf(buffer,"E#%s\0",uname);

 

 

 

 

/* Lookup first name by uname */

char * fnulookup(char * uname)

sprintf(buffer,"F#%s\0",uname);

 

/* Lookup last name by uname */

char * lnulookup(char * uname)

sprintf(buffer,"G#%s\0",uname);

 

/* Lookup email by uname */

char * emulookup(char * uname)

sprintf(buffer,"H#%s\0",uname);

 

/* Lookup email by lname, fname */

char * emlflookup(char * lname, char * fname)

sprintf(buffer,"I#%s#%s\0",lname,fname);

 

/* Lookup email by phone number */

char * emph (char * phone)

sprintf(buffer,"J#%s\0",phone);

 

/* Lookup ip by phone number */

char * ipphlookup (char * phone)

sprintf(buffer,"K#%s\0",phone);

 

/* Verify uname, pw */

int verify(char * uname, char * pw)

sprintf(buffer,"L#%s#%s\0",uname,pw);

 

/* Functions to edit profile */

void editprofilea(char *uname, char *pw, char *fname, char *lname, char *email)

sprintf(buffer,"M#%s#%s#%s#%s#%s\0",uname,pw,fname,lname,email);

 

void editprofileips(char * uname, char * pw, char * ip1, char * ip2, char * ip3)

sprintf(buffer,"N#%s#%s#%s#%s#%s\0",uname,pw,ip1,ip2,ip3);

 

void editprofilephones(char * uname, char * pw, char * phone1, char * phone2, char * phone3)

sprintf(buffer,"O#%s#%s#%s#%s#%s\0",uname,pw,phone1,phone2,phone3);

 

/* for when a user logs in/out ip */

void editprofileip(char * uname, char * pw, char * ip0)

sprintf(buffer,"P#%s#%s#%s\0",uname,pw,ip0);

 

/* for when a user logs in/out phone */

void editprofilephone(char * uname, char * pw, char * phone0)

sprintf(buffer,"Q#%s#%s#%s\0",uname,pw,phone0);

 

/* Lookup userid based on email */

char * uidemlookup(char * email)

sprintf(buffer,"Z#%s\0",email);

 

/*Conference functions*/

/* Returns uids in a conference */

char * uidsconf(char * confname)

sprintf(buffer,"R#%s\0",confname);

 

/* Returns total # in a group */

char * totalnumingroup(char * confname)

sprintf(buffer,"S#%s\0",confname);

 

/* Create a new conference - associated w. userid of creator */

void createconf(char * uname, char * confname, char * prio, char * confpw)

sprintf(buffer,"U#%s#%s#%s#%s\0",uname,confname,prio,confpw);

 

/* Join a conference alrecvy created - returns success bool */

int joinconf(char * uname, char * confname, char * confpw)

sprintf(buffer,"V#%s#%s#%s\0",uname,confname,confpw);

 

/* Leave a conference */

void leaveconf(char * uname, char * confname)

sprintf(buffer,"W#%s#%s\0",uname,confname);

 

/* Destroy a conference - possible only by creator */

int destroyconf(char * uname, char * confname, char * confpw)

sprintf(buffer,"X#%s#%s#%s\0",uname,confname,confpw);

 

/* Get conference ip address */

char * getconfip(char * confname)

sprintf(buffer,"Y#%s\0",confname);

 

 

7. Advice for the Course Staff

 

We felt that the course staff was easily accessible and were very helpful in assisting us. There are only a few suggestions for improvement that we have. To begin with, we need more dialogic cards, plain and simple. There was not enough time to integrate when over 100 people are trying to access one card. Having to compete for time slots seems a bit ridiculous. This bottleneck left us short of our desired level of integration testing that would have been very helpful. One other problem, which may or may not be the course staff’s problem was location. Due to students at different educational levels (undergrad., graduate, and doctoral), accesses to the various labs were limited. This prevented all team members from being able to work in a common place which we believe would have aided in some of the planning and communication. A similar example was having the dialogic card in the systems lab and the team machines in the undergraduate lab. We do not know how much of this is possible, but having all of our resources in the same place would have been very useful!

 

 

8. References

 

http://www.dns.net/dnsrd/

 

http://www.faqs.org/rfcs/rfc2131.html

 

http://www.isc.com/

 

http://www.cs.cornell.edu/cs519/project/nikos.pdf

 

http://www.cs.cornell.edu/cs519/project/description.html#directory

 

Sept. 25, 1998 meeting with Professor Keshav

 

http://www.viconsoft.com/textpages/dhcp/dhcp.info.txt.html

 

http://www.eexpert.com/help/DNSServer.html

 

http://www.ludd.luth.se/~kavli/BIND-FAQ.html

 

http://ftp.cit.cornell.edu/computer/internet/dns

 

http://digitalstarlight.com/dns.html

 

http://www.downlinks.com/internet-server-DNS.htm