This is an old revision of the document!
Corning Community College
CSCS1320 C/C++ Programming
End of Course Experience
Presented within will be various questions evaluating your knowledge and experience gained this semester. In places where you are able, the more you write and explain topics the better the chance you will have of receiving full credit (and alternatively, the more credit you will receive should something be incorrect).
The questions on this experience are open resource with the exception of other individuals. In that respect, it is CLOSED PERSON. This means you are not to communicate with other people (either in the class or otherwise), in real life or electronically. Use your own knowledge, use your own skills, and use your own ability to access the allowed resources to aid you in coming up with your well thought out responses to each question.
You are allowed, and expected, to seek clarification on any question by asking me. But the aim here is to evaluate what you have learned, so do not expect tutoring.
You are to do all items. Submission is to be as follows:
DEADLINE FOR SUBMISSION: You have until 04:29:59pm (that's 16:29:59 in 24-hour time) Thursday, May 14th, 2015 to complete your EoCE(s). This is the ultimate deadline for any and all coursework. There is no “late”, only “too late”. Don't be that person, not with this.
While some classes are allocated a specific meeting time during finals week, I make all such times available should you be free and have questions. Available times (all in B007) are:
Good luck!
In order to perform this end of course experience, you will need to obtain a copy of the eoce project, located on lab46.
These instructions will place the project into your ~/src/cprog/eoce/ directory. If you have been placing your code for this class in a different location, feel free to move it there.
NOTE: It is important that you keep the project directory named eoce; changing its name will break some of the automated functionality making your life easier.
Okay, you're ready to tackle eoce, please log into lab46 and do the following:
lab46:~$ cd /var/public/cprog/spring2015/eoce lab46:/var/public/cprog/spring2015/eoce$ make copy ...
Once copied, you can now change into your project directory, by doing the following:
lab46:/var/public/cprog/spring2015/eoce$ cd ~/src/cprog/eoce lab46:~/src/cprog/eoce$
In the base of the eoce project directory is a Makefile which will automate some tasks for you (specifically, submitting, but it can also be used to help propagate any bugfixes or updates).
To see what options are available, run “make help”
Additionally, there are Makefiles in each of the 0x0/, 0x1/, 0x2/, 0x3/, and 0x4/ subdirectories, which will facilitate the compilation of any code (all you have to do is change into said directory and run make, and watch for any warnings or errors).
In 0x0/ I would like you to create a program in 0x0.c
Following will be the output of a program which I have not provided source code for. Your task is to recreate the necessary programming logic to produce identical output.
Output must be generated by the program (you're not allowed to just have a bunch of fixed printf() statements).
00000000 00000001 00000001 00000002 00000003 00000005 00000008 00000013 00000021 00000034 00000055 00000089 00000144 00000233 00000377 00000610 00000987 00001597 00002584 00004181 00006765 00010946 00017711 00028657 00046368 00075025 00121393 00196418 00317811 00514229 00832040 01346269
You can use the provided Makefile to assist in program compilation; just type 'make'
Please respond to the following:
Although we've largely operated without attention to it, our data and our access to it very much depends upon the permissions set on them.
You cannot view any source code written without the read permission being set; you cannot save changes unless you have write permission enabled; and you cannot run your compiled programs if the execution permission was not applied.
Different operating systems and different filesystems manifest file permissions differently; for this problem we will specifically explore the UNIX file permissions, by writing a program that accepts a value and a file from the command-line and does the pre-processing necessary to convert that value into a form compatible with the mechanism for actually changing the permission.
UNIX file permissions (that we will be exploring) are represented as a 3-digit octal (base 8!) value, and each octal value can have the following values:
^ value ^ description |
4 | apply read permission to that particular mode | |||||
2 | apply write permission to that particular mode | |||||
1 | apply execute permission to that particular mode | |||||
0 | apply no permissions to that particular mode | Being an octal value, we can express results ranging from 0-7, and that is precisely how many variations we need to specify all the possible combinations here.
For example, if we wanted read (4) and write (2) permission, we'd add them together… 4+2 is 6; if we wanted read, write, AND execute: 4+2+1 = 7. There are 3 'tiers' of permissions to consider: | tier | description | ||
---|---|---|---|---|---|---|
user | permissions applied to the assigned owner of the file | |||||
group | permissions applied to the assigned group of the file | |||||
other | permissions applied to anyone else (the world) | More specifically: | user | group | other | |
read | 0400 | 0040 | 0004 | |||
write | 0200 | 0020 | 0002 | |||
execute | 0100 | 0010 | 0001 | |||
none | 0000 | 0000 | 0000 |
lab46:~$ ls -l /etc/motd /etc/shadow /bin/ls -rwxr-xr-x 1 root root 118280 Mar 14 11:47 /bin/ls -rw-r--r-- 1 root root 859 Mar 14 12:16 /etc/motd -rw-r----- 1 root shadow 729 Oct 21 04:55 /etc/shadow lab46:~$
Ignoring the leading '-' (that refers to file type), we see that /bin/ls has rwx (7) applied to the user root, r-x (5) applied to the group root, and r-x applied to everyone else. That means its octal permission is 0755.
/etc/motd has permissions of 0644, while /etc/shadow has permissions of 0640.
When you have a functioning program, you should be able to:
lab46:~/src/cprog/eoce/0x1$ ls -l 0x1.c -rw------- 1 username lab46 729 Apr 13 04:55 0x1.c lab46:~/src/cprog/eoce/0x1$ ./0x0 640 0x1.c lab46:~/src/cprog/eoce/0x1$ ls -l 0x1.c -rw-r----- 1 username lab46 729 Apr 13 04:55 0x1.c lab46:~/src/cprog/eoce/0x1$
As you can see, we were able to modify the permissions from the original 0600 to 0640.
Please respond to the following:
In 0x1 we looked at how to set file permissions, and now we're going to do the opposite: obtaining the permissions of a specified file (indicated on the command-line). This is done through accessing the file's status meta-data, which is done through a function called stat(2).
int stat(const char *pathname, struct stat *buf);
The first parameter is the file name you wish to retrieve information on, the second is where that information will be stored (for the purposes of accessing it in our program).
The stat struct is declared as follows:
struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ mode_t st_mode; /* file permission mode (what you want) */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device ID (if special file) */ off_t st_size; /* total size, in bytes */ blksize_t st_blksize; /* blocksize for filesystem I/O */ blkcnt_t st_blocks; /* number of 512B blocks allocated */ struct timespec st_atim; /* time of last access */ struct timespec st_mtim; /* time of last modification */ struct timespec st_ctim; /* time of last status change */ #define st_atime st_atim.tv_sec #define st_mtime st_mtim.tv_sec #define st_ctime st_ctim.tv_sec };
As you can see, there is a wealth of information we can access.. for those familiar with the output of a long ls file listing, you'd be correct in noticing that so much of its pertinent information points are actually what are stored in the file's meta-data. But we are only interested in the file permission mode for this problem.
You'll notice that the file permission mode is a mode_t type, just as we played with in the 0x1 problem. Treat it as an integer, and treat it as an octal value, and all should be fine.
There happens to be some additional information stored in st_mode; it actually stores up to 6 octal digits. We do not care about the upper 3, merely the lower 3 (so masking them out would be to your benefit).
Once again, logic comes to the rescue… if your solution makes use of it, you'll likely have quite the easy time with this.
Sample output follows:
lab46:~/src/cprog/eoce/0x2$ ./0x2 0x2 755 lab46:~/src/cprog/eoce/0x2$ ./0x2 0x2.c 600 lab46:~/src/cprog/eoce/0x2$ ./0x2 /usr/local/bin/bgrep 750 lab46:~/src/cprog/eoce/0x2$ ./0x2 /etc/motd 644 lab46:~/src/cprog/eoce/0x2$
In combination with a functional 0x1 program, you can now set and check permissions on files (note that you can only set permissions on files you have ownership of).
We've dealt with accessing files, reading and writing information therein.
But there's another common type of file we make use of, but haven't yet considered from a programming perspective: directories.
Directories are files that contain information on other files, to be used as a method of better organizing files.
And now we will explore gaining a deeper insight into what directories are from a programmatic perspective. We're going to explore the implementation of a very simple ls program, which will simply list the files in the indicated directory.
First, to interact with a directory, we need a directory file pointer. We have FILE * for files, we have DIR * for directories, so be sure to declare one.
Next, we need to open the directory. There happens to be a opendir(3) function that accomplishes this task. It has the following prototype:
DIR *opendir(const char *name);
It takes as its only parameter the name of the directory we wish to process (provided via command-line arguments), and returns a DIR pointer. Very similar to fopen(3).
We'll now look to reading directory entries (which can be done with the readdir(3) function).. it deals with struct dirent pointers (so we'll need to declare an instance of one of those as well), which are declared as follows:
struct dirent { ino_t d_ino; /* inode number */ off_t d_off; /* not an offset */ unsigned short d_reclen; /* length of this record */ unsigned char d_type; /* type of file; not supported by all filesystem types */ char d_name[256]; /* filename */ };
For this problem, we're only interested in the d_name element, an array of characters (a string, by any other name), as we're going to print it out.
The readdir(3) function we will be using has the following prototype:
struct dirent *readdir(DIR *dirp);
Its sole parameter is our directory pointer, and it returns a pointer to the (hopefully filled) struct dirent pointer.
What do we want when we wish to access the next directory entry? Simply call readdir(3) again; and again for the next, and again for the next. Until there are no more files in the directory, which is indicated when readdir(3) returns a NULL value (so be sure to check for that).
Finally, as is good practice, when finished with our directory, we need to remember to close it. The closedir(3) function takes care of this (be sure to call it before ending the program).
Look to display the filenames as tab separated values all on one line… we're just aiming for simple operation, not polished output here (that's involves a lot more details, and we're keeping this rather simple).
Sample output could resemble the following:
lab46:~/src/cprog/eoce/0x3$ ./0x3 /home/user/src/cprog/eoce/0x3 Makefile 0x1 0x4 .. 0x2 . .updates 0x0 lab46:~/src/cprog/eoce/0x3$
Also, be sure your output ends with a newline… it is always nice to have our prompt appear on its own line.
Many of these problems are a test of your abstraction skills; while we may not have played with DIR, dirent, and stat pointers, it really doesn't matter- the same basic syntax rules apply. If you understand conceptually what you need to do, the particular details should not get in your way (this is a skill that is crucial to have in programming– the ability to work with things you may not have encountered before).
In 0x4/ is a file called 0x4.c
Here we find an incomplete game in the vein of breakout.
Look over the source code and do the following:
NOTE: in order to test this, you'll need to be in a terminal on one of the pod machines in the LAIR (NOT Lab46), or a machine with the SDL1 libraries and headers installed.
You can use the provided Makefile to assist in program compilation; just type 'make'
After an exciting and intellectually challenging run, we're arriving at the end of this semester's journey. The course as we all experienced it, unfolds in a manner pertaining in part to how you respond to concepts and topics (do we need more time, can I crank it up a couple notches, etc.) so each semester and each class is entirely different from any other- because of each of you, and all of us, working together and learning together.
So, searching deep down within your soul- balancing reason with emotion, and considering attendance and timeliness; answer me the following:
All responses to questions, unless specifically indicated otherwise, should be addressed on this document (or the intended wiki document).
Please edit the appropriate section and provide the necessary information.
If your EoCE involves Makefiles (running make to compile things), you'll likely be able to submit the project with the following command (assuming cprog as the course and location):
lab46:~/src/cprog/eoce$ make submit
And that's it! You're done. If you can make submit, and it works, then there's no further steps needed for project submission.
If applicable, if you'd prefer to submit files to me instead of posting onto your EoCE, please archive everything and submit it using the submit tool. Desired directory structure indicated below.
Assuming ~/src/unix/eoce/, you should have a 0x0/, 0x1/, 0x2/, … 0x7/ set of subdirectories.
Archive them up as follows:
lab46:~/src/unix/eoce$ tar cvf eoce.tar *
Optionally (preferably) compress them (my example will assume you've gzipped them).
Then, submit that file to me using the submit tool:
lab46:~/src/unix/eoce$ submit unix eoce eoce.tar.gz