The purpose for having programming assignments in this class is to give you experience in socket programming, multithreading, and routing. Programming for networking can be done inside the OS kernel or at the application-level. Since the OS class (CSCI 350) is not a prerequisite for this class, we have to run our networks at the application-level. Although all we will be doing is developing code at the application-level, some of what you will be doing can be considered "systems programming" when your code provides services (such as routing) to other networking applications.

All programming assignments are individual assignments. Although you are encouraged to "work with" your classmates at a "high level". When it's time to write code, make sure you write your code in private. Technically speaking, "sharing" a single line of code or pseudo-code with your classmates is considered cheating. If you don't know how to work with another person and not end up "sharing/copying" code, you are advised not to work together with your classmates at all in programming assignments.

We will not give out "solutions" to any programming assignments even though it may seem that some programming assignments can use a previous programming assignment as a starting point. You should start every programming assignment from scratch and use your experience from previous assignments to write better code! You are also expected to do all the labs becuase the purpose of the labs is to get you started on programming assignments. If your program is not working, you are expected to come to office hours and mentoring hours to seek help, although none of the teaching staff will be permitted to write code for you or debug code for you. Although for this semester, the instructor will provide special debugging help for you and it's explained in course administration (covered in Lecture 1).

You are expected to have the prerequisite background in C++ programming (since the prerequisite of this class is CS 201 and its prerequisite is CS 104). We will not be teaching you how to program in C++ in this class. If you are not proficient at programming and debugging in C++, you need to be prepared to spend a lot of time getting good at programming and debugging!

Access to programming assignments is restricted. These specs are private and you do not permissions to post/display these specs and your work based on these specs in a public place.

It goes without saying that if you change an assignment, you will not get credit for it.

Warmup Assignment:

Networking Assignments:
(Please note that access to these videos is restricted.)

Programming assignment videos from a previous semester are provided here, in case that they can be helpful. You should get the requirements for a programming assignment from its spec and not from these old PA videos since PA specs are more current than these old PA videos. If an old PA video and the corresponding current PA spec disagree with each other, you must follow what's in the current PA spec. These old videos can be helpful at a high level. Therefore, when you watch them, you should pay attention to high level descriptions and look at the examples at a high level (and probably ignore the details since they may be outdated).

Access to these old programming assignment videos are protected by an additional level of security measure. All videos here are on D2L, please enter your D2L user ID and password before accessing these videos. Please also see hints about using the D2L video viewer. You also need to enable 3rd party cookies in your browser.

We will use the following percentages for figuring out your overall grade for your programming assignments:
PA1:   8%  
PA2:   21%  
PA3:   21%  
PA4:   30%  
PA5:   20%  
All programming assignments must compile and run on a standard 32-bit Ubuntu 16.04 Linux system running inside a virtual machine on VirtualBox (please see installation instructions regarding how to setup such a system). One major advantage of using a virtual machine is that you can install as many copies as you want. For example, you can have one 32-bit Ubuntu 16.04 Linux system for development, one standard 32-bit Ubuntu 16.04 Linux system for final testing (and keep this virtual machine as "clean" as possible), one for doing experiments or whatever, etc.

I strongly discourage that you install 32-bit Ubuntu 16.04 directly over your hardware because you may run into hardware compatibility problems! I also strongly discourage that you do development work on Windows (such as using CMake or Microsoft Development Studio) or in a Mac OS X environment (such as using Xcode) because that can make your assignments ungradable and you will end up getting a very very low grade for your programming assignments (since graders are not allowed to grade on these platforms)! You should do all your development work on a standard 32-bit Ubuntu 16.04 system running on VirtualBox (i.e., with only permitted packages). This way, you can minimize the chance of unpleasant surprises.

Please note that a standard 32-bit Ubuntu 16.04 system would, once in a while, offer you to "upgrade" the system to the next release. You must NOT do that (or run the "do-release-upgrade" command). If you do that, you will not be running Ubuntu 16.04 any more and you may have to reinstall a brand-new Ubuntu 16.04 from scratch again (which is not all that difficult once you get used to it).

The New Mac

Apple threw us a curve at the end of 2020 by switching to a non-Intel/AMD CPU for their new Macs. These systems are so new, it's not clear if VirtualBox would work on such a system. Even if VirtualBox works on such a system, it's not clear if you can run a 32-bit Ubuntu 16.04 system inside of it. If you have such a system, please take a look at what options you have.

If you just want to use your Mac and not use a Windows system, there are two choices.

  1. You can set up a standard (although "headless") 32-bit Ubuntu 16.04 system in AWS Free Tier. This is a better option than option (2) below because you can run wireshark on it (although a little slow because the AWS servers are very far away) and there are no issues with "wget" on this system and you can run valgrind on it.

  2. It's not a perfect substitute for a Ubuntu 16.04 system, but it's usable. The name of the system is viterbi-scf1.usc.edu and it's a Linux server system running CentOS 7. It has no graphical user interface (and therefore, no IDE). It also does not have debugging tools such as valgrind and wireshark. But, as far as all our labs and programming assignments go, it's pretty much identical to a 32-bit standard Ubuntu 16.04 system (as long as you stick to the "standard" stuff on viterbi-scf1.usc.edu). The only real issue with this system is that the "wget" program there seems to be broken when you want it to retry a download automatically and indefinitely. This only impact PA3 grading (therefore, the grading procedure is slightly modified if you ask the grader to grade your PA3 on viterbi-scf1.usc.edu). If you have never used this system before, please start a "terminal" program and type the following command to ssh into it:
        ssh -X -Y YOURNETID@viterbi-scf1.usc.edu
    where YOURNETID is local-part of your USC email address (and use your USC email password when you are prompted for a password). If you were able to login, you can type the following to logout:
        exit
    If this doesn't work, please let me know as soon as possible.
To transfer files between your Mac and viterbi-scf1.usc.edu, you can use the scp program mentioned in Lab 1. I have also been told that you can use FileZilla, free for download from the ITS Software Website.

The bottom line is that graders can only grade in one of the two following systems:

When you submit your programming assignments, you must include the README file specified in the programming spec and you were supposed to modify the README file according to the instructions in the spec. At the beginning of each of these README files is a question, asking you which system the grader should grade the corresponding assignment. Please make sure you modify the README file and tell the grader which system to use for grading.

Grade Normalization (for all PAs)

Some programming assignments maybe more time-consuming to grade than others. In order to return the grades to you in a timely manner, we may have to have more than one grader grading a programming assignment. Then we have an issue that practially, it's pretty much impossible to have all the graders grade identically. Therefore, if a programming assignment is graded by multiple graders, I will normalize your score (i.e., move everyone's scores "on the same curve" and make necessary adjustments) and use the normalized score when I calculate your final class grade at the end of the semester. Please note that normalization will only be done on the PAs and not on labs since lab grading is pretty straight-forward.

The way normalization will be performed is as follows. I will normalize each PA grade according to the average for each grader for that PA and adjust your grade according to the overall class average. This "normalization" only applies to the grader-dependent part of your grade (i.e., without early/late submission extra credit and penalty. If the overall score you get for an assignment is X, your early/late submission extra credit and penalty is Y percent, your grader-dependent part of the score is Z = X / ((100+Y)/100). After normalization of the grader-dependent part of your score, if your score is Z', the score we will use to calculate your class grade would be X' = Z' × ((100+Y)/100). In the next two paragraphs, we will show you the basic idea of how to get Z' from Z by using an example.

Let's say that the average of a PA graded by your grader is 85 and the overall class average is 86, this means that your grader's average is slightly lower than the class average (maybe because you were graded by a "harsher grader") and everyone graded by your grader will get their grade increased by 1 point (so that your grader's average will be 86). On the other hand, if the average score of your grader is 86.5, this means that your grader's average is slightly above the class average (maybe because you were graded by an "easier grader"), then everyone graded by your grader will get their grade lowered by 0.5 point (so that your grader's average will be 86).

Since the purpose of grade normalization is to normalize the difference in grading among the graders. For a programming assignment, the highest possible normalized grade anyone can get must still be the original maximum score assigned to that assignment, independent of the grader. Similarly, the lowest score one can get is 1 point if you have submitted something for grading. Also, if the grader-dependent part of your grade is 100, your score will not be lowered even if your grader's average is higher than the overall class average since a perfect score is a perfect score and should be grader-independent!

Please note that this is not a perfect system for normalization (because a perfect system doesn't exist). But I think it's a big improvement over not normalizing your scores at all.

With the flipped classroom model, I was able to give a lot of individual help to students with labs and PAs during lecture time and that's a major advantage of the flipped classroom model. Now that we are not doing the flipped model any more, I (not TA nor CPs) would offer the following special debugging help.

Here is the basic idea. If you have a difficult bug that you are having trouble with because your program crashed and C++ and gdb is not giving you much to go on (i.e., gdb doesn't mention your code at all when you type "where" and it looks like your crash has nothing to do with your code), email your code to me (not to the TA or CPs) and within 24 hours, I will try my best to find the bug. If your code doesn't crash, or when it crashes under gdb, you can easily find out where the crash happened, then it's not considered a "difficult" bug (even though it may not be easy to find the bug because debugging multithreaded code may not be easy, but that's something you need to get good at).

Please understand that I do not guarantee that I can find your bug because there are bugs that are extremely difficult to find, even for professional programmers (and I have worked as a professional programmer for many years). Some students are super creative with their bugs! If you have some bad memory corruption bugs, there is a good chance that I won't be able to find it! As I have mentioned in Lecture 1, it's best to write code very carefully to avoid memory corruption bugs than to debug!

If I find a bug, I will tell you where it is and suggest how to fix it. I will not fix it for you since writing code is definitely your job.

Given that you have a "difficult bug" (as defined above), here are some requirements for this "special debugging help" from the instructor.

  • Given that there is a crash, you have to include a transcript showing gdb printout (i.e., when you crash, type "where" or "bt" and record that in the transcript to show that your code is not mentioned in the stack trace).
  • Please note that if your code crashed with the following error message:
        terminate called after throwing an instance of 'std::invalid_argument'
          what():  stoi
        Abort (core dumped)
    This is not considered a "difficult bug" because all you have to do is to find all instances of your code where you are calling stoi() and print its argument and you would easily find the bug. What you should do is of course to call stoi() in a try-catch block or to validate the argument of stoi() before you call stoi().

    Similarly, if your code crashed with the following error message:

        terminate called after throwing an instance of 'std::out_of_range'
          what():  vector::_M_range_check: __n (which is 1) >= this->size() (which is 1)
        Thread ... received signal SIGABRT, Aborted.
    This is not considered a "difficult bug" because it's basically an array out-of-bounds error. What you should do is of course to access an array element in a try-catch block or to validate the array index before you use the list's at() method.
  • You need to send me a full "submission file" (according to the corresponding lab or PA spec) and tell me what "make" command to type to create your program and what command to type to lead to the crash (I would only investigate one serious bug at a time).
  • In your code, you must make sure that every time you call functions like read_a_line(), better_write_header(), or better_write(), you check the return code of these functions immediately. If the return code is -1, it means that the socket is no good and you must break out of all the infinite loops and make sure you shutdown() the socket and set the socket_fd inside the corresponding Connection object to a negative value so that you won't accidentally use that socket ever again. One common bugs I have seen is that students are not checking the return code and end up executing code that they are not supposed to execute.
  • I'm sorry, but I have to ask you to clean up your code and organize your code a little better before you send me your code! I have seen student's code with functions that are over 500 lines long! Break your code down to small and well-defined functions. Sometimes when you do just that, your bug will simply disappear! If you don't know how to do that, you should go to office and mentoring hours of the instructor, TAs, and CPs.
If you are given a pseudo-code and your were supposed to implement the pseudo-code and you cannot get it to work right. Well, that's not considered to be a "difficult" bug. You need to be patient and single-step through your code to figure out where your code has gone wrong. Please also remember that psueod-code given in spec is incomplete and sometimes, they are used to give high-level concepts and you are expected to convert them into working code. Error checking is often not part of any pseudo-code and you are supposed to perform all the error checking at all the right places and you need to know where they are.

For now, if you have bugs that you think are "difficult", even though it doesn't satisfy the definition mentioned above, feel free to send your code to me (but make sure you have followed the requirements and send me what I have requested in the right format). The worst I can say is that it doesn't qualify as a "difficult" bug and in that case, I would typically make some suggestion regarding what you can do in gdb to help you to find the bug.

By the way, if you are using C++ classes that I am not familiar with and something weird is happening with those objects, I will not be able to help you. I would suggest that you stick to the basics and not get too fancy with C++ (since this is a networking class and not an advanced C++ programming class)!

Below are some very important information and requirement about our programming assignments. Please read them carefully so you understand all the rules we will stick to. If you are not sure about something, please send an email to the instructor for clarification.
  1. The class programming assignments will be C/C++ code to be developed on a UNIX/Linux environment. No other programming language will be accepted and your program must compile and run with a Makefile as is. You must be familiar with the UNIX development environment (vi/pico/emacs, g++/gcc, make, etc.) Please read the general programming FAQ if you need a refresher on C file I/O and bit/byte manipulications.

  2. You are not permitted to use any 3rd-party multithreading and/or networking/socket libraries (e.g., boost, google, Qt, etc.) in this class (even if you explicitly ask the grader to install them before grading).

    On a standard 32-bit Ubuntu 16.04, if a package you want to use is not on the list of approved packages, you must send an email to the instructor to ask the instructor to ADD that package to the list of approved packages and wait for approval. Also, only packages from the standard repository will be permitted (i.e., asking to use something like the "add-apt-repository" command to install packages from a non-standard repository will not be permitted).

    Here is the list of approved packages for this course:

    • dos2unix
    • git
    • gitk
    • git-core
    • libssl-dev
    • tcsh
    • tmux
    • traceroute
    • valgrind
    • vim
    • wireshark

    If you have followed the installation instructions for a standard 32-bit Ubuntu 16.04 system, the above packages should have all been installed. If you would like to use a package that's not in the above list, please ask the instructor for approval. If the instructor approves, the list above will be updated! If the package is not approved, you must not use it in your assignments.

  3. We can ONLY grade your programming assignments on the grader's standard 32-bit Ubuntu 16.04 system running inside VirtualBox. with a standard setup (i.e., setup using the method described in our Ubuntu Linux installation procedure). Our grader's system will be such a system and you need to make sure that your programs run on the same platform (and you won't have access to the grader's machine).

  4. For any programming assignment, please do not hardcode any directory path in your code! If you hardcode something like "/home/YOURACCOUNTNAME/..." (where YOURACCOUNTNAME is the name of your account on your standard 32-bit Ubuntu 16.04 system) in your code to access something in your home directory, since the grader cannot change your code during grading, you may end up getting a very very low score. So, please make sure you are not doing this. Please understand that this is your responsibility.

    The only path that you can hardcode is probably "/tmp", and even that is not a great idea. What you can do is to define such a path as a compile time variable and pass it to your program. For example, you can use the following to define TMPDIR to be equal to "/tmp":

        g++ ... -DTMPDIR=\"/tmp\" ...
    Then in your code, you can do:
        char tmpfile[256];
    
        snprintf(tmpfile, sizeof(tmpfile), "%s/XXXXXX", TMPDIR);
        ... mkstemp(tmpfile) ...
    Basically, using a compile time variable is the same as doing the following in your code:
        #define TMPDIR "/tmp"
    The difference is that you doing it outside of your code is much cleaner.

    By the way, Linux/Unix file system path can be as long as 256 bytes. So, if you have a char-array variable that will hold a file system path, make sure it's at least 256 bytes in size.

  5. We will make grading guidelines available at least one week before an assignment is due. We will grade based on the posted grading guidelines. To make sure that students cannot hard-code solution values mentioned in the grading guidelines into their code, the grading guidelines that the grader will be used for grading will use have different numeric values, commandline arguments, and test data files. Therefore, you should expect that we will change the testing data for grading. To the best of our effort, we will not change the grading script/procedure (although we may make minor changes if we discover bugs in the grading script or important things that we forgot to test).

    The general rule is that you will not get credit for simply coding. The general rule about grading is that you do not get credit for effort. You only get credit for getting your code to work correctly according to the spec and grading guidelines and produce the correct output. You need to learn how to use the debugger (and ask for help if you don't know how) to find bugs in your code even though some bugs can be extremely difficult to find. Please do not ask the grader to read your code so you can get more points because you have done a lot of coding and your code looks like it should work. If your code is close to working correctly, it's your responsiblity to get your code to work correctly and produce the correct output (and seek help EARLY if you cannot get your code to work). Please do not expect partial credit just because you have put in effort to write code!

    Please understand that all the requirements mentioned in the spec and grading guidelines are serious requirements for all programming assignments. If you have a minor bug that causes a lot of tests to fail, you may end up losing a lot of points. (Therefore, for starters, don't name your executable to be anything other than the one mentioned in the spec and grading guidelines.) For the same mistake in your code, you may get points deducted over and over again (i.e., do expect "double jeopardy", "triple jeopardy", etc.).

  6. Early submissions may get you extra credit, if you submit more than 48 hours before the submission deadline. Please see the extra credit policy.

  7. Late submissions will receive severe penalties. Please see the late policy.

  8. All submissions will be timestamped by the submission server (i.e., a Bistro server) and receipts (known as upload tickets) will be issued. Whether your submission arrived to the server by the deadline is determined by the timestamp. Please do not delete any email that contains a submission ticket.

  9. If you sign up late for this class, you are still required to turn in all the programming assignments on time or you will receive a score of zero for the applicable assignments. No exceptions! This requirement also applys to students on the wait list.

  10. You must follow the Electronic Submission Guidelines when you submit programming assignments. Please note that this is a fairly new procedure and very different from other classes. When you make a submission, you will get an email containing a ticket and you should read the ticket carefully. It should look similar to the sample output given on the Bistro page. The timestamped upload ticket issued by the Bistro server is a proof that the server has received your submission (and you do not need additional proof). You should also verify what you have submitted is what you intended to submit by following the Verify Your Submission procedure. Please note that it is your responsibility to ensure that you have submitted valid submissions and that you have received timestampted upload tickets for them. Please understand that a file system timestamp can be easily forged. The only kind of timestamp that we can accept is a timestamp in a ticket issued by a Bistro server under my control.
You must not look at, copy, or share any code fragments from your classmates or previous semesters to implement any programming assignment. Doing so would be considered cheating. You have committed plagiarism if you submit work done by others and claim that it's your own work.

It should be clear that you cannot use code written by other students in the current or a previous semester no matter what. As clearly in spelled out in the academic integrity policy of this class, if you have a copy of any of our programming assignments written by someone else, looking at the code or running the code is considered cheating, let alone copying code from it.

What about code you find online? First of all, it has to be publically available code (suh as stuff you find in stackoverflow.com). If it's a paid site or password protected, then it's not public. Also, you must not compile the code you got online into a library and have your code link to them. If you want to use any code online, you should extract what you need (make sure you understand them perfectly) and add it to your source code and cite where you got the source properly (see below). This way, you are making it clear that you did not write that piece of code and you are giving credit to others who have written the code.

What if you end up with the same code fragment as another student because you copy the code fragment from the same place online? This will make it look like you copied/shared code with another student. Well, this is why it's important to cite the source of each piece of code in your code properly. The proper way to cite your source is to do it inline in your C/C++ file. Please understand that it's improper to simply give citation in your README file. Here's what your code should look like when you use a piece of code you found on the Internet:

    /* Begin code (derived) from [URL] */
    /* If the code you got requires you to include its copyright information, put copyright here as well. */
    [ code you copied or derived from above URL ]
    /* End code from [URL] */
If you don't cite the code you got online properly and our plagiarism-catching software complains about identical code were found becuase you and somone else copied code from the same place online, you will lose 10 points for each such code fragment.

You have my permission to use code given to you as part of this class (i.e., from textbook or lecture slides). You do not need to cite such code.

You are allowed to submit modifications via email to the instructor, up to 24 hours after the submission deadline (and preferably after the submission deadline). The first 3 lines of modifications are free of charge within this time frame. Additional modifications cost 3 points per line (each submission is worth 100 points).

One line (128 characters max) of change is defined as one of the following:

  • Add 1 line before (or after) line x of file y
  • Delete line x of file y
  • Replace line x of file y by 1 line
  • Move line x of file z to before (or after) line y
where x and z are line numbers and y is a specified file. Please also mention what line z looks like so I can verify that I have made the modification at the right place.

Afterwards, additional modifications cost 6 points per line until 7 days past the submission deadline. After 7 days past the submission deadline, an additional modification costs 15 points per line.

Please note that this applies to source code, Makefile, and README files. Please understand that the grader is NOT allowed to modify your source code or Makefile during grading.

Just want to be very clear about this... The free 3 lines of changes are only applicable if you submit them within 24 hours of the submission deadline. Also, a "modification" is NOT considered a "new submission". So, sending a "modification request" will not change the timestamp of the submission we grade.

I often get questions regarding segmentation faults and bus errors. Sometimes, these occue when one calls library functions such as malloc() or free(). Some students think this is some kind of a system bug. Well, it's often not. I will try to answer this type of questions here once and for all.

Chances are that you have corrupted memory (or have corrupted the memory allocation chain). Memory corruption means that a memory location got modified in a bad way and you have no idea when it happened or how it happened. It's as if it has gone bad all by itself. But since it really cannot go bad all by itself, it just be your code that somehow corrupted memory! When you notice that memory corruption has occurred, this usually implies that you have corrupted memory a while back. It just happened that when you call malloc() or free(), the corrupted memory caused a bus error or the execution of an illegal instruction. By the way, bus errors and illegal instructions are basically the same thing as segmentation faults. If you see something like "stack smash", it's another form of memory corruption bug (unless you really try to "smash the stack" on purpose).

How does one corrupt memory (or corrupt the memory allocation chain)? You can write beyond an allocated memory block. You can free the same object twice. You can free an object that was not allocated. You can write to an object that's already freed. You can write to a portion of a stack space that is no longer valid. These bugs are hard to find because most of the them you only see that there is problem long time after you have "corrupted memory". We will talk about all this when we go over "dynamic storage allocation" in Ch 3 of the textbook.

If you have access to a professional/expensive debugging tool, it may be helpful. Otherwise, you just need to do binary search and see where the bug(s) might be. There's no magical cures in debugging memory corruption bugs, not even for professionals! I, unfortunately, do not have any magic tricks that can help anyone find memory corruption bugs. My advise is to write your code very carefully and understand what every line of your code is doing and make sure that your code won't corrupt memory! It's much better to avoid creating nasty bugs than to debug and this good habit can save a lot of your time that you would have spent in debugging!

One thing you might try on Ubuntu is to include the following commandline argument when you run g++ to compile your code:

    -fsanitize=address
The above enables AddressSanitizer to catch certain memory corruption bugs. It's not a cure-all, so please do not exactly that it will find all your memory corruption bugs.

Another thing you might try is to temporarily turn off memory deallocation (if you suspect that you have freed the same object twice or freed an object that was not allocated). You can do the following to define free() as a no-op in a common header file when you are debugging:

    #ifdef DEBUGGING_MEMORY_CORRUPTION
    #ifdef free
    #undef free
    #endif /* free */
    #define free
    #endif /* DEBUGGING_MEMORY_CORRUPTION */
Then use -DDEBUGGING_MEMORY_CORRUPTION as a commandline argument when you run g++ to use this trick.

As your code gets more and more complicated, you may get more of these bugs. This is one reason why you want to keep your code nice and clean.

On Ubuntu Linux, one very useful tool for finding memory corruption bugs is valgrind. If you have installed Ubuntu 16.04 on your laptop/desktop, you should give it a try. Just prefix your commandline by "valgrind" (or "valgrind --tool=exp-sgcheck" if simply running "valgrind" doesn't print any error messages, although this feature is experimental and may not work right) and read the output carefully. Figure out why valgrind is complaining and fix only the first bug it complains about. Although valgrind cannot catch every memory corruption bug, it does a pretty good job for relatively straight-forward memory corruption bugs. For more details, please see the PA1 FAQ item about valgrind. By the way, from what I can tell, it seems to catch the same memory corruption bugs as using the address sanitization options in g++.

If your program is memory-corruption free and you just want to look for memory leaks, you can run your program by prefixing it with "valgrind --leak-check=full" and see what valgrind has found for you. Please understand that, for our programming assignments, there is absolutely no requirement that you don't have memory leaks. My recommendation is that you should ignore memory leak information from valgrind and only run valgrind when you suspect that you have memory corruption bugs and hope that valgrind can help.

Recently, I have heard about two more memory debuggers.

  • cppcheck - Static analysis of C/C++ code. Checks for: memory leaks, mismatching allocation-deallocation, buffer overrun, and many more. To install on Ubuntu, do
        sudo apt-get install cppcheck
  • libefence - Helps you detect two common programming bugs: software that overruns the boundaries of a malloc() memory allocation and software that touches a memory allocation that has been released by free().
        sudo apt-get install electric-fence
I haven't tried them. I'm hoping that they may be useful.

It's imperative that you backup your code when you are doing a major programming assignment (or even labs). Sometimes, your virtual machine may refuse to start (maybe because of changes in your system) and there is no way to recover files inside the virtual machine. That makes it even more important to backup your code.

Must NOT Use GitHub.Com

You must NOT use GitHub.com because if you don't pay them within a certain time frame, your private repository will automatically become public (no matter what the GitHub.com website says)! Once your code becomes public, future students will be able to copy your code and you will end up helping them to cheat! USC Student Conduct Code (which you have agreed to when you became a student at USC) says that you must not cheat off other students AND you must not knowingly allow other students to cheat off of you. By allowing your code to apper in public, which will perit future students to have access to your code, you are violating the USC Student Conduct Code!

For the above reason, please do not use GitHub.com as your "online resume" to host your code. If you do that, you will be knowingly violating USC Student Conduct Code.

Use BitBucket.Com

BitBucket is like GitHub.com in that it combines version control and backup. The main difference is that private projects on bitbucket.com stays private.
  1. Create an academic account on BitBucket. You must use your USC email address.

  2. You must make sure to make your git repository private. When you create a new repository, by default, the repository would be private. So, don't change that! If for some reason it's showing "public", select "private" before you create the repository). Failing to do so would be considered cheating (since you are allowing other students to cheat from you) and can lead to very serious consequences. If you cannot make your git repository private, you should NOT use BitBucket!

  3. For a repository, you can change its settings and you can make the repository public. Please don't do that! If a prospective employer asks you to do that, you must tell them that you are not allowed to do that because you have agreed to the USC student conduct code when you were a student at USC and the USC student conduct code says that you must not cheat off other students and you must not knowingly allow other students to cheat off of you. You can email them a private copy of your code and you must not include anything you do not have rights to distribute.
A student had made the following comment about some advantages of using bitbucket.org:
I'm not sure if it is clearly stated on the website, but Bitbucket also comes with Jira that allows you to track the progress of features/bugs in your repo. You can basically create an entry stating issues associated with a certain commit and track them. You can also breakdown features of what you're implementing and assign them easily to different collaborators (easy to track and write a detailed breakdown contribution for grading too!). If you're an experienced swdev and are familiar with agile/scrum then this is a big plus over Github. If you decide to work in a group then this will allow you to collaborate/communicate more efficiently.
Once you have created a repository, say, "pa1", you can do the following on your laptop in a terminal:
  1. Change directory (using the "cd" command) to your "pa1" directory then do the following only once:
        git init
        git remote add origin https://YOURACCOUNTNAME@bitbucket.org/billcheng/pa1.git

  2. Add files to the repository. For example:
        git add *.c *.h Makefile *README.txt
        git commit -m 'Initial commit'
        git push -u origin master --tags

  3. After you have made changes to some of the files, you can do the following to update the repository:
        git commit -a
        git push origin master --tags
    You should do the above at least once a day so that what's on your laptop do not get too much out of sync with the repository.
The above are just some examples to get you started quickly. To learn more about "git", please please read the free online book, Pro Git, mentioned in the textbooks section of our course description web page.

Use Shared Folder

A quick and easy to to backup is to copy all your files into the shared folder, i.e., the folder you are sharing with the host system. You should make this as easy as possible. Let's say that you put all your code in the folder called cs353 in the home directory of your Ubuntu 16.04 system. Assuming that your shared folder is in /Shared-ubuntu (suggested in the Ubuntu 16.04 installation instruction and additional instructions and you should change it if the location of your shared folder is different). Then you just need to do the following to make a backup. If your command shell is bash, do:
    cd
    now=`date +%d%b%Y-%H%M%S`
    tar cvzf cs353-backup-$now.tar.gz cs353
    cp cs353-backup-$now.tar.gz ~/Shared-ubuntu
    ls -l ~/cs353-backup-$now.tar.gz
If your command shell is tcsh, do:
    cd
    set now=`date +%d%b%Y-%H%M%S`
    tar cvzf cs353-backup-$now.tar.gz cs353
    cp cs353-backup-$now.tar.gz ~/Shared-ubuntu
    ls -l ~/cs353-backup-$now.tar.gz
If you don't know what command shell you are running, do:
    echo $BASH
If it says that BASH is an undefined variable, then most likely, your command shell is tcsh. Otherwise, your command shell is bash.

Please copy and paste the above command and not try to copy it visually (watch out for the "backquote" characters). The above command create a file called cs353-backup-DDMMMYY-HHMMSS.tar.gz where DDMMMYY is the current day, month, and year and HHMMSS is the current hour, minute, and second. Please read the printout of the above commands carefully. If you see any errors, maybe you did not setup your shared folder completely according to the standard procedure.