Assignment 4 FAQ, Tutorials, Errata, and Addenda

Due Monday, April 6, 2009 6:00 pm on-line

Last update: Saturday, April 4, 2009 23:51 EDT

Important
Be sure that you change the program number of hist.x to one of your own choosing (abiding by the restrictions; see the tutorial). Otherwise you may be connecting to someone else's server and will have a hard time figuring out why it's not working.
My string isn't getting passed across. I seem to get only the first character.

You probably defined the event as char * in your hist.x file. The RPC compiler won't know that this represents a string when it has to generate code to marshal parameters; it's just a pointer. To pass strings, you need to define them as such:

string event<256>;

instead of

char *event;

The <256> tells RPC to send at most 256 characters.If you look at the generated .c and .h files, you'll see that rpcgen has declared event as char * since that's what C knows about. In your code, you can use event as a char * because that's what it is. The string directive is just for rpcgen to know what to do.

I get the error:
cc: not found
in step 2 of the RPC tutorial.

The rpcgen program on Sun systems generates a makefile that assumes you have a C compiler that is invoked in classic Unix style: via the cc command. Most Rutgers machines have the GNU C compiler installed, which is invoked via the gcc command. Until you write your own makefile, you can change occurrances of cc in the automatically generated makefile to gcc. Alternatively, you can use the commands in step 3 to compile your stuff (under the "you'll see output similar to": section; change cc to gcc if needed). You'll also need to remember to add -DRPC_SVC_FG on the command line that compiles the server so that the server is compiled to not run in the background as a dæmon.

BTW, the -Sm option doesn't work on OS X.

No matter what you do, you will ultimately write your own makefile, which will be a trivial variation of the one in step 6. You will not get credit for submitting any makefile generaged with rpcgen -Sm.

Can I use Java for this assignment?
No.
I'm having problems running rpcgen on remus.
The RPC installation on remus looks like it's messed up. Use romulus, the cereal machines, any Linux system, or any OS X system.
The make command doesn't seem to be installed on romulus (but the man page exists). I have checked remus and it exists there, gives me usage, but I think you said that Sun RPC won't work on remus. What do we do?
The make command does exist on romulus. It's in /usr/ccs/bin/make. Either type the full pathname or add /usr/ccs/bin to your search path. On sh, bash, ksh, you can do this with:
PATH=$PATH:/usr/ccs/bin
I want to know if there is a way to create a main function in hserver.c to initialize the values of the global array that will hold the events. I attempted to define one, but when I compiled it, gcc told me that a main function was already defined.

Yes, there's a way to do this. rpcgen accepts a -m flag that does not generate a main() routine. The reason you couldn't just go and write a main() function was because the server stub is the main function. This may be more trouble than it's worth. You can define an initialization function (for example, init_events) and call it from each of the remote procedure definitions. For example, define

#define MONTHS 12 #define DAYS 31 int initialized = 0; /* these are global */ struct *list[MONTHS][DAYS] = 0; void init_list(void) { /* whatever you need to do to initialize */ } int* add_1_svc(Event *e, struct svc_req *rqstp){ static int result; /* before we do anything else, initialize the global data */ /* do this in EVERY rpc server function */ if (!initialized) { init_list(); initialized = 1; }
On all makefiles you add -lnsl to the end of your gcc lines, my computer tells me cannot find file for: -lnsl. It seems to work when I delete these parts of the line. Is there anything this is actually needed for?
The -nsl directive tells the linker to look in the library libnsl.a when resolving symbols. On Sun systems, this contains RPC support functions that the stubs need. You do not need this on Linux or OS X systems: those functions are part of libc. You can safely remove -lnsl on those platforms.
Some things that you will lose points on.
  • Submitting a makefile created by rpcgen.
  • Not checking the failure of every remote procedure call. This means exiting or returning upon encountering one.
  • Ridiculously careless formatting: tons of blanks lines, for example.
  • Sloppy coding - using cryptic variables like result_3. Just because rpcgen generated variable names in a template program doesn't mean you have to use them - use something short and descriptive.
  • Sloppy coding - leaving in comments such as "This is sample code generated by rpcgen."
  • Functionality: nonsensical date (e.g., month=22 or date=81) should be handled gracefully.
  • Submission: handing in files such as hist_svc.c, hist_clnt.c, any .o files or any executable files.
When performing adds - do we append the data to the file or should the data file be in order, as in the example on the site?
You don't need to keep a permanent file. If it's easier for you, you can read the file into memory and keep modifications in memory. If you do keep a file, you don't need to keep all the dates sorted. Appending is fine.
Does the hserver have to store the events in a file (or in any other way store/retrieve the events on server shutdown/startup respectively)?
No, you don't need to store the events in a file. It's OK if everything you added dies when the server exits.
I'm currently storing the events in memory. In order to achieve that, the hserver::query is dynamically allocating memory for the event string itself. Is there a way to subscribe to the server-shutdown event, in order to deallocate the memory (to keep the server memory-leak free)?
There should be no need to allocate memory in the query function. You can have a static definition of the return structure that contains a char *event. Just set event to whatever's in the list you're maintaining. Make sure, however, that you dynamically allocate storage to the string in the list of events (see strdup). If you really need to allocate memory for returned functions dynamically (you don't for this assignment), then you should store the results of the allocation into a static variable, and free it next time the function is called.
Should there be a check for duplicate events
No, there is no need to check for duplicate events.
What is the desired maximum length of the event string and, when it is reached, what would you like the error code to be for query?
You can limit the event length to 255 chars. Don't worry about the max length on the server. You can check on the client and limit it in the RPC definition if you'd like (e.g., string event<255>;)
What would you like the hserver::query response to be when a non-existent event is queried

The server can just return an empty event

static char *empty = ""; ... result.event = empty; result.index = 0; return &result;
Do we need to check for the proper input on the command line. For example, that the month and date are integers or that there are enough arguments or can we assume that the arguments will always be correct?

You can never assume anything the user does will always be correct!

You should check that there the month is in the range 1..12 and the date is in the range 1..31. You should also check that there are just the right number of arguments. You do not need to check for Feb having 28/29 days or that April, June, September, and November have 30 days (unless you'd like to for completeness).

I get the error "Unable to create (ADD_PROG, ADD_VERS) for netpath.".

If you're on a Linux or OS X system, change your client to specify a transport provider instead of using netpath. For example, change:

clnt = clnt_create(host, HIST_PROG, HIST_VERS, "netpath");

to

clnt = clnt_create(host, HIST_PROG, HIST_VERS, "tcp");

SunOS supports a "netpath" parameter, which allows you to specify a list of transport providers as a shell environment variable and picks the first in the list that it can use. This has not been brought into Linux or OS X (yet). For example, on SonOS, you can set an environment variable:

export NETPATH="tcp:udp"

I get a weird message when I run make:

make: *** Warning: File `makefile' has modification time in the future make: warning: Clock skew detected. Your build may be incomplete.

You've stumbled upon a common problem with NFS. It assumes clocks on all the machines are synchronized, which isn't always the case. If you want to be sure that everything is compiling, you can remove all your executables, auto-generated files, and object files and touch all the remaining files. Run:

rm *.o rm add_xdr.c add_clnt.c add_svc.c add_server add_client touch * make
If there are no events on a certain date that a client requests, should something like "no events on this day" return or is just a simple return enough?
Up to you. A simple return is fine if there are no events. That's what a good Unix applicaiton would do because you might want to pipe the output to, for example, wc -l to count the number of events on a given day.