Week 09 Tutorial Questions

  1. Explain the output of print_bytes below:
     echo hello Andrew >hi.txt
     echo Good bye Andrew >bye.txt
     1521 chicken -c a.egg hi.txt bye.txt
    Adding: hi.txt
    Adding: bye.txt
     print_bytes a.egg
    byte    0:  99 0x63 'c'
    byte    1:  56 0x38 '8'
    byte    2:  45 0x2d '-'
    byte    3: 114 0x72 'r'
    byte    4: 119 0x77 'w'
    byte    5:  45 0x2d '-'
    byte    6: 114 0x72 'r'
    byte    7:  45 0x2d '-'
    byte    8:  45 0x2d '-'
    byte    9: 114 0x72 'r'
    byte   10:  45 0x2d '-'
    byte   11:  45 0x2d '-'
    byte   12:   6 0x06
    byte   13:   0 0x00
    byte   14: 104 0x68 'h'
    byte   15: 105 0x69 'i'
    byte   16:  46 0x2e '.'
    byte   17: 116 0x74 't'
    byte   18: 120 0x78 'x'
    byte   19: 116 0x74 't'
    byte   20:  13 0x0d
    byte   21:   0 0x00
    byte   22:   0 0x00
    byte   23:   0 0x00
    byte   24:   0 0x00
    byte   25:   0 0x00
    byte   26: 104 0x68 'h'
    byte   27: 101 0x65 'e'
    byte   28: 108 0x6c 'l'
    byte   29: 108 0x6c 'l'
    byte   30: 111 0x6f 'o'
    byte   31:  32 0x20 ' '
    byte   32:  65 0x41 'A'
    byte   33: 110 0x6e 'n'
    byte   34: 100 0x64 'd'
    byte   35: 114 0x72 'r'
    byte   36: 101 0x65 'e'
    byte   37: 119 0x77 'w'
    byte   38:  10 0x0a
    byte   39: 161 0xa1
    byte   40:  99 0x63 'c'
    byte   41:  56 0x38 '8'
    byte   42:  45 0x2d '-'
    byte   43: 114 0x72 'r'
    byte   44: 119 0x77 'w'
    byte   45:  45 0x2d '-'
    byte   46: 114 0x72 'r'
    byte   47:  45 0x2d '-'
    byte   48:  45 0x2d '-'
    byte   49: 114 0x72 'r'
    byte   50:  45 0x2d '-'
    byte   51:  45 0x2d '-'
    byte   52:   7 0x07
    byte   53:   0 0x00
    byte   54:  98 0x62 'b'
    byte   55: 121 0x79 'y'
    byte   56: 101 0x65 'e'
    byte   57:  46 0x2e '.'
    byte   58: 116 0x74 't'
    byte   59: 120 0x78 'x'
    byte   60: 116 0x74 't'
    byte   61:  16 0x10
    byte   62:   0 0x00
    byte   63:   0 0x00
    byte   64:   0 0x00
    byte   65:   0 0x00
    byte   66:   0 0x00
    byte   67:  71 0x47 'G'
    byte   68: 111 0x6f 'o'
    byte   69: 111 0x6f 'o'
    byte   70: 100 0x64 'd'
    byte   71:  32 0x20 ' '
    byte   72:  98 0x62 'b'
    byte   73: 121 0x79 'y'
    byte   74: 101 0x65 'e'
    byte   75:  32 0x20 ' '
    byte   76:  65 0x41 'A'
    byte   77: 110 0x6e 'n'
    byte   78: 100 0x64 'd'
    byte   79: 114 0x72 'r'
    byte   80: 101 0x65 'e'
    byte   81: 119 0x77 'w'
    byte   82:  10 0x0a
    byte   83: 221 0xdd
    
  2. This is the initial code for the assignment. Discuss how you compile this code, how these function are called and what values the function arguments might take?
    ////////////////////////////////////////////////////////////////////////
    // COMP1521 21T3 --- Assignment 2: `chicken', a simple file archiver
    // <https://www.cse.unsw.edu.au/~cs1521/21T3/assignments/ass2/index.html>
    //
    // Written by YOUR-NAME-HERE (z5555555) on INSERT-DATE-HERE.
    //
    // 2021-11-08   v1.1    Team COMP1521 <cs1521 at cse.unsw.edu.au>
    
    #include <stdio.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    #include "chicken.h"
    
    
    // ADD ANY extra #defines HERE
    
    
    // ADD YOUR FUNCTION PROTOTYPES HERE
    
    
    // print the files & directories stored in egg_pathname (subset 0)
    //
    // if long_listing is non-zero then file/directory permissions, formats & sizes are also printed (subset 0)
    
    void list_egg(char *egg_pathname, int long_listing) {
    
        // REPLACE THIS CODE WITH YOUR CODE
    
        printf("list_egg called to list egg: '%s'\n", egg_pathname);
    
        if (long_listing) {
            printf("long listing with permissions & sizes specified\n");
        }
    }
    
    
    // check the files & directories stored in egg_pathname (subset 1)
    //
    // prints the files & directories stored in egg_pathname with a message
    // either, indicating the hash byte is correct, or
    // indicating the hash byte is incorrect, what the incorrect value is and the correct value would be
    
    void check_egg(char *egg_pathname) {
    
        // REPLACE THIS PRINTF WITH YOUR CODE
    
        printf("check_egg called to check egg: '%s'\n", egg_pathname);
    }
    
    
    // extract the files/directories stored in egg_pathname (subset 2 & 3)
    
    void extract_egg(char *egg_pathname) {
    
        // REPLACE THIS PRINTF WITH YOUR CODE
    
        printf("extract_egg called to extract egg: '%s'\n", egg_pathname);
    }
    
    
    // create egg_pathname containing the files or directories specified in pathnames (subset 3)
    //
    // if append is zero egg_pathname should be over-written if it exists
    // if append is non-zero egglets should be instead appended to egg_pathname if it exists
    //
    // format specifies the egglet format to use, it must be one EGGLET_FMT_6,EGGLET_FMT_7 or EGGLET_FMT_8
    
    void create_egg(char *egg_pathname, int append, int format,
                    int n_pathnames, char *pathnames[n_pathnames]) {
    
        // REPLACE THIS CODE PRINTFS WITH YOUR CODE
    
        printf("create_egg called to create egg: '%s'\n", egg_pathname);
        printf("format = %x\n", format);
        printf("append = %d\n", append);
        printf("These %d pathnames specified:\n", n_pathnames);
        for (int p = 0; p < n_pathnames; p++) {
            printf("%s\n", pathnames[p]);
        }
    }
    
    
    // ADD YOUR EXTRA FUNCTIONS HERE
    
  3. How is the assignment going?

    Does anyone have questions?

    Does anyone have hints or advice for other students on how to start?

  4. The stat() and lstat() functions both take an argument which is a pointer to a struct stat object, and fill it with the meta-data for a named file.

    On Linux, a struct stat contains the following fields (among others, which have omitted for simplicity):

    struct stat {
        ino_t st_ino;         /* inode number */
        mode_t st_mode;       /* protection */
        uid_t st_uid;         /* user ID of owner */
        gid_t st_gid;         /* group ID of owner */
        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 */
        time_t st_atime;      /* time of last access */
        time_t st_mtime;      /* time of last modification */
        time_t st_ctime;      /* time of last status change */
    };
    

    Explain what each of the fields represents (in more detail than given in the comment!) and give a typical value for a regular file which appears as follows:

    ls -ls stat.c
    8 -rw-r--r--  1 jas  cs1521  1855  Sep  9 14:24 stat.c
    

    Assume that jas has user id 516, and the cs1521 group has group id 36820.

  5. Consider the following (edited) output from the command ls -l ~cs1521:

    drwxr-x--- 11 cs1521 cs1521 4096 Aug 27 11:59 17s2.work
    drwxr-xr-x  2 cs1521 cs1521 4096 Aug 20 13:20 bin
    -rw-r-----  1 cs1521 cs1521   38 Jul 20 14:28 give.spec
    drwxr-xr-x  3 cs1521 cs1521 4096 Aug 20 13:20 lib
    drwxr-x--x  3 cs1521 cs1521 4096 Jul 20 10:58 public_html
    drwxr-xr-x 12 cs1521 cs1521 4096 Aug 13 17:31 spim
    drwxr-x---  2 cs1521 cs1521 4096 Sep  4 15:18 tmp
    lrwxrwxrwx  1 cs1521 cs1521   11 Jul 16 18:33 web -> public_html
    
    1. Who can access the 17s2.work directory?

    2. What operations can a typical user perform on the public_html directory?

    3. What is the file web?

    4. What is the difference between stat("web", &info) and lstat("web", &info)?
      (where info is an object of type (struct stat))

  6. Write a C program, chmod_if_public_write.c, which is given 1+ command-line arguments which are the pathnames of files or directories

    If the file or directory is publically-writeable, it should change it to be not publically-writeable, leaving other permissions unchanged.

    It also should print a line to stdout as in the example below

    dcc chmod_if_public_write.c -o chmod_if_public_write
    ls -ld file_modes.c file_modes file_sizes.c file_sizes
    -rwxr-xrwx 1 z5555555 z5555555 116744 Nov  2 13:00 file_sizes
    -rw-r--r-- 1 z5555555 z5555555    604 Nov  2 12:58 file_sizes.c
    -rwxr-xr-x 1 z5555555 z5555555 222672 Nov  2 13:00 file_modes
    -rw-r--rw- 1 z5555555 z5555555   2934 Nov  2 12:59 file_modes.c
    ./file_modes file_modes file_modes.c file_sizes file_sizes.c
    removing public write from file_sizes
    file_sizes.c is not publically writable
    file_modes is not publically writable
    removing public write from file_modes.c
    ls -ld file_modes.c file_modes file_sizes.c file_sizes
    -rwxr-xr-x 1 z5555555 z5555555 116744 Nov  2 13:00 file_sizes
    -rw-r--r-- 1 z5555555 z5555555    604 Nov  2 12:58 file_sizes.c
    -rwxr-xr-x 1 z5555555 z5555555 222672 Nov  2 13:00 file_modes
    -rw-r--r-- 1 z5555555 z5555555   2934 Nov  2 12:59 file_modes.c
    
    Make sure you handle errors.
  7. Write a C program, fgrep.c, which is given 1+ command-line arguments which is a string to search for.

    If there is only 1 command-line argument it should read lines from stdin and print them to stdout iff they contain the string specified as the first command line argumenbt.

    If there are 2 or more command line arguments, it should treat arguments after the first as fiilenames and print any lines they contain which contain the string specified as the first command line arguments.

    When printing lines your program should prefix them with a line number.

    It should print suitable error messages if given an incorrect number of arguments or if there is an error opening a file.

  8. Write a C program, print_file_bits.c, which given as a command line arguments the name of a file contain 32-bit hexadecimal numbers, one per line, prints the low (least significant) bytes of each number as a signed decimal number (-128..127).
  9. Write a C program, compile.c, which is given 1+ command-line arguments which are the pathname of single file C programs.

    It should compile each program with dcc.

    It also should print the compile command to stdout.

    dcc compile.c -o compile
    ./compile file_sizes.c file_modes.c
    /usr/local/bin/dcc file_modes.c -o file_modes
    /usr/local/bin/dcc file_sizes.c -o file_sizes
    
    Make sure you handle errors, for example, you should stop if any compile fails.

Revision questions

The following questions are primarily intended for revision, either this week or later in session.
Your tutor may still choose to cover some of these questions, time permitting.