[ This content is protected and may not be shared, uploaded, or distributed. ]

(Please also check out PA2 FAQ.)

Lab 5 has four parts:

Please note that this lab assumes that you have watched the PA2 lecture videos.

Part A (lab5a) - INI file parser (useful for PA2):

Typically, a networking server can be configured to run with various parameters. It can be very cumbersome to specify these parameters using commandline arguments. Instead, a configuration file is typically used to specify these parameters. On Windows, there is file format known as the Windows INI File Format that can be used for such a purpose. We will use configuration files in a restricted form of this format for many labs and programming assignments in this class (starting with this lab and PA2). In this part of the lab exercise, you will write a simple parser to extract information out of such a configuration file.

A INI file (not exactly a Windows INI file) is a text file with multiple sections. The basic structure of such a file looks like the following:

    [SECTION 1 NAME]
    KEY11=VALUE11
    KEY12=VALUE12
    ...
    [SECTION 2 NAME]
    KEY21=VALUE21
    KEY22=VALUE22
    KEY23=VALUE23
    ...
    [SECTION 3 NAME]
    KEY31=VALUE31
    KEY32=VALUE32
    KEY33=VALUE33
    ...
Each line above ends with a '\n' character (not shown).

If the first character of a line is the left-square-bracket (i.e., '[') character, the string inside the square brackets is the section name for that section. After the section name line and before the next section name line, every line specify a KEY/VALUE pair that belongs to the current section if it's in the "KEY=VALUE" format (please note that KEY must not be an empty string while it's perfectly fine if VALUE is an empty string). You must ignore all the blank lines. Also, any line whose first character is the semi-colon (i.e., ';') character is a comment line. You must ignore lines like that as well.

For our class, you can assume that all the configuration files we use will not have any space or tab characters anywhere (except in a comment line). Also, everything is case-sensitive. This should make your code easier to write.

If you don't have a favorite way of splitting a string into parts, please take a look at the code in split.cpp to see how you can use getline() and stringstream to split a string into parts separated by a separater character.

The executable for this part of the lab exercise must be named lab5a. Please create a Makefile so that when the user types "make lab5a", the lab5a executable will be generated. The usage information (i.e., commandline syntax) for "lab5a" is as follows:

    lab5a sections INIFILE
    lab5a keys SECTIONNAME INIFILE
    lab5a value SECTIONNAME KEYNAME INIFILE
where argv[1] is a "command name" and it has the following meaning:
  • sections: print all the section names (one per line) in INIFILE
  • keys: print all the keys (one per line) in section SECTIONNAME in INIFILE
  • value: print the value for the KEYNAME key in section SECTIONNAME in INIFILE
For the sections command, if INIFILE does not contain any sections (or if INIFILE does not exist), please print the following error message:
    No sections in INIFILE.
Otherwise, you can print the section names in any way you'd like.

For the keys command, if SECTIONNAME cannot be found in INIFILE, please print the following error message:

    Cannot find the [SECTIONNAME] section in INIFILE.
Otherwise, you can print the keys in any way you'd like.

For the value command, if SECTIONNAME cannot be found in INIFILE, please print the above error message. If KEYNAME is not a valid key in SECTIONNAME of INIFILE, please print the following error message.

    Cannot find the "KEYNAME" key in the [SECTIONNAME] section in INIFILE.
If the corresponding value is an empty string, please print the following message (which is not an error):
    There is no value for the "KEYNAME" key in the [SECTIONNAME] section in INIFILE.

We will test your code with lab5data.tar.gz. Please do the following

  • Create an empty directory (call it "lab5") and change directory into it.
  • Download lab5data.tar.gz into that directory and type:
        tar xvf lab5data.tar.gz
    This should create a subdirectory called "lab5data" with a bunch of INI files in it (plus other files you will need for the rest of this lab).
  • Type "script lab5a.script" to start a transcript. Then type:
        uname -a
        cat /etc/os-release
        make clean
        make lab5a
        ./lab5a sections lab5data/test3.ini
    Your printout should look like:
        startup
        startup2
        startup3
    If your printout is wrong, please fix your code until it works correctly.

  • Type:
        ./lab5a keys startup2 lab5data/test3.ini
    Your printout should look like:
        host
        port
        pidfile
        rootdir_xyz
        logfile
    Type:
        ./lab5a keys startup2x lab5data/test3.ini
    Your printout should look like:
        Cannot find the [startup2x] section in lab5data/test3.ini
    If your printout is wrong, please fix your code until it works correctly.

  • Type:
        ./lab5a value startup3 logfile_abc lab5data/test3.ini
    Your printout should look like:
        lab5.log4
    Type:
        ./lab5a value startup3 host lab5data/test3.ini
    Your printout should look like:
        There is no value for the "host" key in the [startup3] section in lab5data/test3.ini.
    Type:
        ./lab5a value startup3 logfile_abcx lab5data/test3.ini
    Your printout should look like:
        Cannot find the "logfile_abcx" key in the [startup3] section in lab5data/test3.ini
    If your printout is wrong, please fix your code until it works correctly.

  • Type:
        ./lab5a keys startup3 lab5data/test1.ini
        ./lab5a value startup port lab5data/test1.ini
        ./lab5a value startup2 port lab5data/test3.ini
        ./lab5a value startup pidfile lab5data/test2.ini
        ./lab5a value startup3 rootdir lab5data/test3.ini
        ./lab5a value startup3 rootdir lab5data/test2.ini
        ./lab5a value endup rootdir lab5data/test1.ini
        exit

Part B (lab5b) - logging (useful for PA2):

In PA2, you will need to log information into either a log file or cout. You should use the same code to write log information into either a lot file or cout. This part of the lab shows you a way to do that.

This part has no coding (although you have to modify the "Makefile" you created for Part A of this lab. Please do the following:

  • Change directory into the "lab5" directory mentioned above.
  • Download "logging.cpp" into that directory. Modify the "Makefile" you created for Part A of this lab and add a section to it so that when you type "make lab5b" in the commandline, "logging.cpp" would get compiled into an executable called "lab5b". Study the code in "logging.cpp" to see what it does. If commandline arguments are given, It opens "argv[1]" as a file output stream and it uses that as the output stream. Otherwise, it simply uses cout as the output stream. Once this is setup, you would use the same object and call the same function to log messages.
  • In a Terminal window, type "script lab5b.script" to start a transcript. Then type the following:
        make lab5b
        rm -f xyzzy xyzzy.log
        ./lab5b > xyzzy
        ./lab5b xyzzy.log
        diff xyzzy xyzzy.log
        cat xyzzy
        cat xyzzy.log
        xxd -g 1 xyzzy.log
    In the above, the 1st time you run lab5b, it will log messages to cout and the command there redirect cout to a file named "xyzzy". The 2nd time you run lab5b, it will log messages into a file named "xyzzy.log" directly. A message will be printed to cout and you should see that message. Then the "diff" command is used to show you the difference between "xyzzy" and "xyzzy.log" and you should read the code of logging.cpp to make sense of the difference. Then the "cat" commands are used to print the content of "xyzzy" and "xyzzy.log". Finally, the "xxd" command is used to do a hexdump of the content of "xyzzy.log". The "xxd" program may be very useful for debugging bugs caused by missing data bytes or extra data bytes.
  • Type "exit" to close the transcript.
Please review the code in "logging.cpp" and make sure you understand what every line of code there is doing.

Part C (lab5c) - hash file content with MD5 (useful for PA2):

Some students are not used to read from a binary file or writing binary data. The purpose of this lab exercise is to get comfortable with read/writing binary data. We will also learn how to create a "MD5 hash/checksum" of a "stream" of binary data. A sender can append a "MD5 hash" of a stream of data after the data is sent. The receive can compute the "MD5 hash" of the received data and compare it against the "MD5 hash" at the end of the data stream to see if some bits/bytes in the data have been accidentically modified/dropped. This is quite often done in the Internet as part of the process of "message authentication" (although a secret "key" is usually added to the mix).

"MD5 hash" can be calculated for an arbitrarily long stream of binary data. The way it's typically calculated is to use an interative method. You first call MD5_Init() to iniitalize a "MD5 context data structure" to set the "MD5 calculator" to a known initial state. Then you can chop the long stream of binary data to any size you want and send the chunks in sequence to the "MD5 calculator" one chunk at a time by calling MD5_Update() (the chunk size can even change on every call). When you are done with sending all the bytes to the "MD5 calculator", you would call MD5_Final() to ask the "MD5 calculator" to return the final "MD5 hash/checksum" (always 16 bytes) of all the stream of bytes you have sent to the "MD5 calculator".

This part has no coding (although you have to modify the "Makefile" you used in Part B of this lab). Please do the following:

  • Change directory into the "lab5" directory mentioned above.
  • Download md5-calc.cpp into that directory and download Makefile and append it to the Makefile you have created for Part A of this lab. Study the code in "md5-calc.cpp" to see what it does. It opens "argv[1]" as a file using the open() system call. It figures out the size of the file using the stat() system call. Then it reads from the input file at most 4 KB of binary data at a time and sends whatever that was read into the MD5_Update() function to update the MD5 calculator. When all the binary data has been processed by MD5_Update() (i.e., when read() failed), it calls MD5_Final() to finalize the MD5 calculation. Then it calls HexDump() to print the MD5 hash/checksum to cout.
  • In a Terminal window, type "script lab5c.script" to start a transcript. Then type the following:
        make lab5c
        gdb lab5c
        (gdb) b 47
        (gdb) b 58
        (gdb) run lab5c
        (gdb) display bytes_remaining
        (gdb) display/x buf
    Line 47 of "md5-calc.cpp"" is right after it has successfully read (at most) 4 KB of binary data from "lab5c" (the executable file itself, which is a binary file). The "display bytes_remaining" and "display/x buf" gdb commands put "spy points" on bytes_remaining in decimal and the content of buf in hex. From this point on, after every gdb command, it will print the content of buf in hex. Now press <Ctrl+z> to suspend gdb and get to the command shell. In the command shell, type:
        xxd -g 1 lab5c | head
    The "head" program prints the first 10 lines of its input and discards the rest. The vertical bar character is the Unix/Linux pipe character. To the left of it is one program and to the right of it is another program. The pipe takes the printout from the program running on the left and feeds it as the input to the program running on the right. Altogether, the above command line performs a hexdump on the "lab5c" binary file and displays the first 10 lines of the printout. You should check what you see against the last gdb command. Every byte should match.
  • Type the following into your Terminal:
        fg
    This will bring the program you have suspended to the "foreground" and you will be in gdb again. Please continue to type:
        (gdb) cont
        (gdb) cont
        (gdb) cont
        (gdb) cont
        (gdb) clear
        (gdb) cont
        (gdb) p/x md5_buf
        (gdb) cont
        (gdb) quit
        openssl md5 lab5c
    The "clear" gdb command clears the breakpoint and the "cont" continues running the program being debugged until it hits another breakpoint or the program terminates or crashes. In this case, the program should hit the second breakpoint on line 58, right after the MD5 hash value has been printed out in a hexstring. After you have quit gdb, the "openssl md5 FILE" command prints out the MD5 hash of FILE. The printout of the "openssl md5 lab5c" command should match the hexstring printed by the lab5c program.
  • Type "exit" to close the transcript.
Please review the code in "md5-calc.cpp" and make sure you understand what every line of code there is doing.

Part D (lab5d) - text-based animation (useful for PA2):

This part has no coding (although you have to modify the "Makefile" you used in Part C of this lab). Please do the following:
  • Change directory into the "lab5" directory mentioned above.
  • Type the following:
        cp lab5data/progress.cpp ./progress.cpp
        make lab5d
        ./lab5d
    Then study the code in "progress.cpp" to see how "text-based animation" is done for a commandline program and how to wait for 0.1 second to pass (both needed in PA2).

    Please note that the code in "progress.cpp" works because every line it prints in the progress bar is either just as long or longer than the previous line. When you adapt the code to be used in PA2, you need to modify the code a bit to take care of the cases where the current line is shorter than the previous line.

The above specificiation has quite a lot of details! So, pseudo-code for the code you need to write is not provided.

Below is the grading breakdown:
  • (1 pt) submitted a valid lab5.tar.gz file with all the required files using the submission procedure below
  • (1 pt) contents in "lab5a.script" is correct.
  • (1 pt) contents in "lab5b.script" and "lab5c.script" are correct.
  • (1 pt) Makefiles works for "make lab5a"
  • (1 pt) source code of your INI parsing program looks right
Minimum deduction is 0.5 pt for anything that's incorrect. Please note that for the "Makefile" item, you can only get credit for it if your "source code" is relevant to this lab; therefore, you can only get as many points as the "source code" item in the best case.

Please keep in mind that even though lab grading is "light", it doesn't mean that you can just put anything into your submission! It's still your responsibility to make sure that the files in your submission contains information that's relevant to the tests you were supposed to run. Use the "more" command to view your script/log files to make sure that they contain the right information. If a file has the wrong stuff in it, you should delete it and create the file again and verify. If most of the stuff in your script/log files are wrong and you did not notice it, we will most likely have to take points off.

To submit your work, you must first tar all the files you want to submit into a tarball and gzip it to create a gzipped tarfile named "lab5.tar.gz". Then you upload "lab5.tar.gz" to our Bistro submission server.

Change into the "lab5" directory you have created above and enter the following command to create your submission file "lab5.tar.gz" (if you don't have any ".h" files, don't include "*.h*" at the end):

    tar cvzf lab5.tar.gz lab5*.script Makefile *.c* *.h*
    ls -l lab5.tar.gz
The last command shows you how big the created "lab5.tar.gz" file is. If "lab5.tar.gz" is larger than 1MB in size, the submission server will not accept it.

If you use an IDE, the IDE may put your source code in subdirectories. In that case, you need to modify the commands above so that you include ALL the necessary source files and subdirectories (and don't include any binary files) ane make sure that your code can be compiled without the IDE since the grader is not allowed to use an IDE to compile your code.

You should read the output of the above commands carefully to make sure that "lab5.tar.gz" is created properly. If you don't understand the output of the above commands, you need to learn how to read it! It's your responsibility to ensure that "lab5.tar.gz" is created properly.

To check the content of "lab5.tar.gz", you can use the following command:

    tar tvf lab5.tar.gz
Please read the output of the above command carefully to see what files were included in "lab5.tar.gz" and what are their file sizes and make sure that they make sense.

Please enter your USC e-mail address and your submission PIN below. Then click on the Browse button and locate and select your submission file (i.e., "lab5.tar.gz"). Then click on the Upload button to submit your "lab5.tar.gz". (Be careful what you click! Do NOT submit the wrong file!) If you see an error message, please read the dialogbox carefully and fix what needs to be fixed and repeat the procedure. If you don't know your submission PIN, please visit this web site to have your PIN e-mailed to your USC e-mail address.

When this web page was last loaded, the time at the submission server at merlot.usc.edu was 27Nov2025-18:59:34. Reload this web page to see the current time on merlot.usc.edu.

USC E-mail:    @usc.edu
Submission PIN:  
Event ID (read-only):  
Submission File Full Path:  
   
 
If the command is executed successfully and if everything checks out, a ticket will be issued to you to let you know "what" and "when" your submission made it to the Bistro server. The next web page you see would display such a ticket and the ticket should look like the sample shown in the submission web page (of course, the actual text would be different, but the format should be similar). Make sure you follow the Verify Your Ticket instructions to verify the SHA1 hash of your submission to make sure what you did not accidentally submit the wrong file. Also, an e-mail (showing the ticket) will be sent to your USC e-mail address. Please read the ticket carefully to know exactly "what" and "when" your submission made it to the Bistro server. If there are problems, please contact the instructor.

It is extreme important that you also verify your submission after you have submitted "lab5.tar.gz" electronically to make sure that every you have submitted is everything you wanted us to grade. If you don't verify your submission and you ended up submit the wrong files, please understand that due to our fairness policy, there's absolutely nothing we can do.

Finally, please be familiar with the Electronic Submission Guidelines and information on the bsubmit web page.