User Tools

Site Tools


Sidebar

projects

  • cci0 (due 20150128)
  • mms0 (due 20150204)
  • mbe0 (due 20150211)
  • mbe1 (due 20150311)
  • afn0 (due 20150318)
  • cbf0 (due 20150408)
  • EoCE - bottom of your Opus (due 20150514 by 4:30pm)
haas:spring2015:cprog:projects:eoce

This is an old revision of the document!


Corning Community College

CSCS1320 C/C++ Programming

End of Course Experience

EoCE

Rules

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:

  • an organized and easy to read presentation of information on your EoCE wiki page.
  • if applicable, files submitted via a project Makefile (make submit), or a submitted archive using the submit tool.

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:

  • Tuesday, May 12th from 08:00am - 4:30pm
  • Wednesday, May 13th from 08:00am - 5:30pm
  • Thursday, May 14th from 11:00am - 4:30pm

Good luck!

CPROG

Obtain the EOCE project

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.

Obtain eoce

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
...

Change into your eoce project directory

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$ 

Using the Makefile

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).

0x0: Fun with numbers

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).

Output

    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'

Questions

Please respond to the following:

  • Additionally, What would be the next row (next 4 values) that would occur should this output be allowed to continue?
  • In words, describe the pattern taking place with these numbers.

0x1: Setting permissions

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.

Questions

Please respond to the following:

  • What do you suppose would happen if you specified a permission of 000 to this file?
    • Apply it and try to open it.
    • How would you change it back?
  • What if you removed the execute permission on the 0x1 binary?
    • How would you remove the execute permission?
    • Can you still run the compiled 0x1 program without execution bit?
    • What does it say when you run it?
    • How can you restore previous functionality?

0x2: Get file permissions

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).

0x3: Directories

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).

0x4: Fun with games

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:

  • comment it: identify major sections of code, and dissect the logic so that you can better understand what is going on
  • restore paddle movement with the cursor keys
  • enable an autopilot mode with the press (and holding) of the TAB key, centering the ball in the middle of the paddle (except when at extreme edges of the screen)
  • do something extra to the game; such as:
    • change the default brick layout
    • change the default color patterns
    • require 2 hits of each brick before it goes away
    • add a second player for cooperative play
    • simplify main() by moving code into separate functions, all called from main()

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'

0x5: Your Perspective

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:

  • What grade do you feel you deserve for this course?
  • Why do you feel you deserve this mark? (Justify your answer based on your own perceived performance, not on need.)
  • How did you feel about the course?
  • Was it useful/interesting to you?
  • What was your least favorite aspect, and why?
  • What was something meaningful to you with respect to the course? Why does this stick out in your mind?
  • Any other comments or suggestions?

Submission

Opus

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.

Makefile Submission

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.

File 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
haas/spring2015/cprog/projects/eoce.1428964435.txt.gz · Last modified: 2015/04/13 22:33 by wedge