├── Assignments ├── Assignment1 │ ├── Assignment1.pdf │ ├── COMP206Fall2018_Assign1_Provided.zip │ ├── README.md │ └── Solution │ │ ├── q2_decrypt.bash │ │ ├── q2_encrypt.bash │ │ └── q3_image_sorter.bash ├── Assignment2 │ ├── Assignment2.pdf │ ├── README.md │ └── daves_q1b_solution.c ├── Assignment3 │ ├── A3.zip │ ├── Assignment3.pdf │ ├── README.md │ └── daves_A3_solution.c ├── Assignment4 │ ├── Assignment4.pdf │ ├── Assignment4.zip │ └── daves_A4_solution.zip └── Assignment5 │ ├── Assignment5.pdf │ └── Assignment5.zip ├── ExampleCode ├── Lecture11-2DArrays │ ├── pointer_review.c │ └── sort_argv.c ├── Lecture12-Memory │ ├── auto_array_alloc.c │ ├── dynamic_array_alloc.c │ ├── stack_pointer_gotcha.c │ └── static_array_alloc.c ├── Lecture13-ImageFiles │ ├── bit_reporting.c │ ├── bmp_2_white.c │ ├── bmp_file_reader.c │ ├── endianness_test.c │ ├── mario_16_bit.bmp │ ├── mario_message.bmp │ ├── pointer_conversion.c │ ├── steg_decoder.c │ ├── steg_encoder.c │ └── utah.bmp ├── Lecture15-LibrariesFnptrsSyscalls │ ├── headache.c │ ├── multi_sort.c │ ├── run_time_check.c │ ├── time_check.c │ ├── time_check.h │ └── time_hack.c ├── Lecture16-structsLinkedList │ └── simple_structs.c ├── Lecture17-networking │ ├── add_ten.bash │ ├── client_inet.c │ └── server_inet.c ├── Lecture18-Internet2 │ ├── echo_client.c │ └── echo_server.c ├── Lecture19-Web │ ├── Makefile │ ├── README │ ├── htdocs │ │ ├── README │ │ ├── check.cgi │ │ ├── color.cgi │ │ ├── index.html │ │ ├── lecture_example.html │ │ └── output.html │ ├── httpd.c │ └── simpleclient.c ├── Lecture20-CGI │ ├── chat.html │ ├── first.c │ ├── mult.html │ └── second.c ├── Lecture21-MultiProcess │ ├── fork_execl.c │ └── schedule_race.c ├── Lecture22-Coordination │ └── synched_counting.c ├── Lecture4-BashIfForWhile │ ├── directory_of_sample_files │ │ ├── a.txt │ │ ├── b.txt │ │ ├── c.txt │ │ └── d.txt │ ├── example_if.bash │ ├── for_over_files.bash │ └── while_calendar.bash ├── Lecture6-CIntro │ ├── args.c │ ├── beyond_array.c │ ├── sorting_exercise_starter.c │ ├── temp.c │ └── temp_for.c ├── Lecture7-TextData │ └── max_int_test.c ├── Lecture8-StringAlgorithms │ ├── array_vs_ptr.c │ ├── merge_sort.c │ ├── my_strlen.c │ └── my_strlen_pointerized.c ├── Lecture9-libraries_debug │ ├── fgetc_example.c │ ├── file_reader.c │ ├── hurricane_data.csv │ ├── myfile.txt │ ├── parse_csv_arrays.c │ ├── parse_csv_ptrs.c │ └── parse_csv_stringH.c ├── SampleMidtermAnswers │ ├── encrypt.c │ ├── first_letters.c │ ├── simple_calc.c │ └── test_letter_file.txt └── Tutorial3_CBootcamp │ ├── MallocQuestion │ └── allocWords.c │ └── README.md ├── Exams ├── COMP206_FALL2018_PRACTICE_FINAL.pdf ├── COMP206_Fall2018_MT_StudyGuide.pdf ├── midterm_answers.pdf ├── practice_final_answers.pdf ├── practice_final_q22_solution1.c ├── practice_final_q22_solution2.c └── practice_final_q22_solution3.c ├── README.md ├── Slides ├── Basic C Tutorial Anirudha Slides.pdf ├── Lecture1-CourseOverview.pdf ├── Lecture10-PointersInC.pdf ├── Lecture11-2DArrays.pdf ├── Lecture11-2DArrays.pptx ├── Lecture12-Memory.pdf ├── Lecture12-Memory.pptx ├── Lecture13 - BMP Images.pdf ├── Lecture14-MultfileAndMake.pdf ├── Lecture15-LibrariesFnptrsSyscalls.pdf ├── Lecture16_structs_linkedLists.pdf ├── Lecture17-Internet.pdf ├── Lecture18-Internet2.pdf ├── Lecture19-Web.pdf ├── Lecture2-OSAndLinuxBasics.pdf ├── Lecture20-CGI.pdf ├── Lecture21-MultiProcess.pdf ├── Lecture22-Coordination.pdf ├── Lecture23-Conclusion.pdf ├── Lecture3-ShellScriptingIntro.pdf ├── Lecture4-AdvancedShells.pdf ├── Lecture5-LastLinuxConcepts.pdf ├── Lecture5-LastLinuxConcepts.pptx ├── Lecture6-CIntro.pdf ├── Lecture6-CIntro.pptx ├── Lecture7-WorkingWithData.pdf ├── Lecture7-WorkingWithData.pptx ├── Lecture8-strings.pdf ├── Lecture9-stinglib-textio-debugging.pdf ├── Tutorial1-Linux-JoesSlides.pdf ├── Tutorial1-Linux-PrabhjotsSlides.pdf └── Tutorial2-C-Programming-PrabhjotSlides.pdf ├── _config.yml └── index.md /Assignments/Assignment1/Assignment1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmeger/COMP206_Fall2018_Lectures_Public/fe5f3136e24658e52b526e8edbf9c6f5afb2cb01/Assignments/Assignment1/Assignment1.pdf -------------------------------------------------------------------------------- /Assignments/Assignment1/COMP206Fall2018_Assign1_Provided.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmeger/COMP206_Fall2018_Lectures_Public/fe5f3136e24658e52b526e8edbf9c6f5afb2cb01/Assignments/Assignment1/COMP206Fall2018_Assign1_Provided.zip -------------------------------------------------------------------------------- /Assignments/Assignment1/README.md: -------------------------------------------------------------------------------- 1 | # Frequently Asked Questions about Assignment 1 2 | 3 | ## Where does my code have to be located to run correctly? 4 | 5 | Your code should be able to run no matter where the .bash file is located, both with respect to the present working directory, and with respect to the paths given as arguments. Just think about the fact that "ls" is located in /bin/ls, but it works equally well no matter where you cd to or which directory you want to inspect. 6 | 7 | How can you achieve this? The trick is to let the shell work for you. $1 and $2 arguments must be "proper" paths given by the user, so you can simply pass them to any command you need without modifying them. Do not hard-code, such as "./$1" or "~/COMP206_A1/$1". Both of those examples will restrict where your code works and would lose you marks. 8 | 9 | For testing, ensure you can cd to a different location entirely and still have your code work. For example, run this test, which assumes you unzipped the provided file in the COMP206_A1 folder within your home directory and also placed your bash script there: 10 | $ cd ~ 11 | $ mkdir temp_junk_test 12 | $ cd temp_junk_test 13 | $ bash ~/COMP206_A1/q2_decrypt.bash ~/COMP206_A1/Q2/codebook.txt ~/~/COMP206_A1/secret_message.txt 14 | 15 | Does it work for you? 16 | -------------------------------------------------------------------------------- /Assignments/Assignment1/Solution/q2_decrypt.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | small_code=$(cat $1 | grep a) 4 | large_code=$(cat $1 | grep A) 5 | 6 | cat $2 | tr $small_code a-z | tr $large_code A-Z 7 | 8 | -------------------------------------------------------------------------------- /Assignments/Assignment1/Solution/q2_encrypt.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | small_code=$(cat $1 | grep a) 4 | large_code=$(cat $1 | grep A) 5 | 6 | cat $2 | tr a-z $small_code | tr A-Z $large_code 7 | 8 | -------------------------------------------------------------------------------- /Assignments/Assignment1/Solution/q3_image_sorter.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | unsorted_list=$(find $1 -name "*.jpg") 4 | 5 | sorted_list=$(ls -tr $unsorted_list) 6 | 7 | output_name=$(echo $1 | tr / _) 8 | 9 | echo convert -append $unsorted_list $output_name 10 | 11 | -------------------------------------------------------------------------------- /Assignments/Assignment2/Assignment2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmeger/COMP206_Fall2018_Lectures_Public/fe5f3136e24658e52b526e8edbf9c6f5afb2cb01/Assignments/Assignment2/Assignment2.pdf -------------------------------------------------------------------------------- /Assignments/Assignment2/README.md: -------------------------------------------------------------------------------- 1 | # Hint video 2 | 3 | Can be found here: 4 | [Dave's tips on Youtube](https://www.youtube.com/watch?v=Ry0MQrmgyq0&feature=youtu.be) 5 | 6 | # Frequently Asked Questions (FAQ) 7 | 8 | - Does the output have to match identically for Q2? 9 | 10 | No, Wikipedia is being constantly updated and it looks like wget pulls just slightly different information at times depending on what type of computer you connect from, where you're located etc. Make sure that the specification is matched: that is everything you output follows the pattern I requested. I do think this means you'll be within 1-2 lines of the provided sample, but just dont worry about tiny differences. 11 | 12 | - Does the PageName after a href have to equal the PageName after title? 13 | 14 | This was a mistake I made. I thought they were always equal on Wiki pages and so didn't fully specify. You can either restrict to only printing links where those names are equal, or print either the first or the second string in case they differ, so long as you only find things that do indeed have both a href and title components as the pattern shows. 15 | 16 | - What's the largest diamond we'll test? 17 | 18 | Make sure you get get to 127 at minimum to ensure full marks. For many solutions, there will not be any real limit, since the code runs fast and takes little memory. It's a nice challenge to see how large you can make it. 19 | -------------------------------------------------------------------------------- /Assignments/Assignment2/daves_q1b_solution.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifdef DEBUG 6 | const char space = '#'; 7 | #else 8 | const char space = ' '; 9 | #endif 10 | 11 | int sierpinski_row( int row, int height, int level ){ 12 | 13 | int width = 2*height - 1; 14 | 15 | if( level == 0 ){ 16 | 17 | int this_width = (row+1) * 2 - 1; 18 | int this_spaces = ( width - this_width ) / 2 ; 19 | 20 | for( int pos=0; pos=0; row-- ){ 65 | sierpinski_row( row, height, level-1 ); 66 | printf( "\n" ); 67 | } 68 | 69 | return 0; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /Assignments/Assignment3/A3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmeger/COMP206_Fall2018_Lectures_Public/fe5f3136e24658e52b526e8edbf9c6f5afb2cb01/Assignments/Assignment3/A3.zip -------------------------------------------------------------------------------- /Assignments/Assignment3/Assignment3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmeger/COMP206_Fall2018_Lectures_Public/fe5f3136e24658e52b526e8edbf9c6f5afb2cb01/Assignments/Assignment3/Assignment3.pdf -------------------------------------------------------------------------------- /Assignments/Assignment3/README.md: -------------------------------------------------------------------------------- 1 | # News 2 | 3 | There was a small error in the documentation (.h) files first posted. They have been corrected on Oct 25th at 7am, so if you downloaded the .zip file prior to that, please re-download. 4 | 5 | # Frequently Asked Questions 6 | 7 | * Why does bmp_close need to take "unsigned char **img_data" instead of a single pointer? 8 | 9 | A: Note the documentation states the pointer must be set to NULL. That means the pointer in the calling function. This is a case of passing a pointer by reference, which extends the idea of passing typical variables by reference, we need to use a pointer to change the value outside the function. 10 | -------------------------------------------------------------------------------- /Assignments/Assignment3/daves_A3_solution.c: -------------------------------------------------------------------------------- 1 | /* FILE: A3_solutions.c is where you will code your answers for Assignment 3. 2 | * 3 | * Each of the functions below can be considered a start for you. 4 | * 5 | * You should leave all of the code as is, except for what's surrounded 6 | * in comments like "REPLACE EVERTHING FROM HERE... TO HERE. 7 | * 8 | * The assignment document and the header A3_solutions.h should help 9 | * to find out how to complete and test the functions. Good luck! 10 | * 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include "A3_provided_functions.h" 17 | 18 | unsigned char* 19 | bmp_open( char* bmp_filename, unsigned int *width, 20 | unsigned int *height, unsigned int *bits_per_pixel, 21 | unsigned int *padding, unsigned int *data_size, 22 | unsigned int *data_offset ){ 23 | 24 | unsigned char *img_data=NULL; 25 | 26 | FILE *fp; 27 | if( ( fp = fopen( bmp_filename, "rb" ) ) == NULL ){ 28 | printf( "Failed to open file %s.\n", bmp_filename ); 29 | return NULL; 30 | } 31 | 32 | char b, m; 33 | fread( &b, 1, 1, fp ); 34 | fread( &m, 1, 1, fp ); 35 | 36 | fread( data_size, 1, sizeof(int), fp ); 37 | 38 | rewind(fp); 39 | 40 | img_data = (unsigned char*)malloc(*data_size); 41 | 42 | if( img_data == NULL ){ 43 | printf( "Error: Failed to malloc space for image of size %d.\n", *data_size ); 44 | return img_data; 45 | } 46 | 47 | fread( img_data, 1, *data_size, fp ); 48 | 49 | *data_offset = *((unsigned int*)(img_data+10)); 50 | *width = *((unsigned int*)(img_data+18)); 51 | *height = *((unsigned int*)(img_data+22)); 52 | *bits_per_pixel = *( (unsigned short int*)(img_data+28)); 53 | 54 | *padding = ( 4 - (*width * (*bits_per_pixel/8)) % 4) % 4; 55 | 56 | return img_data; 57 | } 58 | 59 | // We've implemented bmp_close for you. No need to modify this function 60 | void bmp_close( unsigned char **img_data ){ 61 | 62 | if( *img_data != NULL ){ 63 | free( *img_data ); 64 | *img_data = NULL; 65 | } 66 | } 67 | 68 | unsigned char*** 69 | bmp_scale( unsigned char*** pixel_array, unsigned char* header_data, unsigned int header_size, 70 | unsigned int* width, unsigned int* height, unsigned int num_colors, 71 | float scale ) 72 | { 73 | unsigned int new_width = *width * scale; 74 | unsigned int new_height = *height * scale; 75 | 76 | unsigned char*** new_pixel_array = (unsigned char***)malloc( sizeof(unsigned char**) * (new_height)); 77 | if( new_pixel_array == NULL ){ 78 | printf( "Error: Failed to allocate memory for image of height %d.\n", (new_height) ); 79 | return NULL; 80 | } 81 | 82 | for( int row=0; row 0 ){ 157 | for( unsigned int color=0; color<4; color++ ){ // We are guaranteed only to work with RGBA images 158 | bg_img_pixel_array[row][col][color] = fg_img_pixel_array[fg_row][fg_col][color]; 159 | } 160 | } 161 | fg_col++; 162 | } 163 | fg_row++; 164 | } 165 | 166 | return bmp_from_3D_array( output_collage_image_filename, bg_img_header_data, bg_img_header_size, 167 | bg_img_pixel_array, bg_img_width, bg_img_height, bg_img_num_colors ); 168 | } 169 | 170 | -------------------------------------------------------------------------------- /Assignments/Assignment4/Assignment4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmeger/COMP206_Fall2018_Lectures_Public/fe5f3136e24658e52b526e8edbf9c6f5afb2cb01/Assignments/Assignment4/Assignment4.pdf -------------------------------------------------------------------------------- /Assignments/Assignment4/Assignment4.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmeger/COMP206_Fall2018_Lectures_Public/fe5f3136e24658e52b526e8edbf9c6f5afb2cb01/Assignments/Assignment4/Assignment4.zip -------------------------------------------------------------------------------- /Assignments/Assignment4/daves_A4_solution.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmeger/COMP206_Fall2018_Lectures_Public/fe5f3136e24658e52b526e8edbf9c6f5afb2cb01/Assignments/Assignment4/daves_A4_solution.zip -------------------------------------------------------------------------------- /Assignments/Assignment5/Assignment5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmeger/COMP206_Fall2018_Lectures_Public/fe5f3136e24658e52b526e8edbf9c6f5afb2cb01/Assignments/Assignment5/Assignment5.pdf -------------------------------------------------------------------------------- /Assignments/Assignment5/Assignment5.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmeger/COMP206_Fall2018_Lectures_Public/fe5f3136e24658e52b526e8edbf9c6f5afb2cb01/Assignments/Assignment5/Assignment5.zip -------------------------------------------------------------------------------- /ExampleCode/Lecture11-2DArrays/pointer_review.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main( int argc, char *argv[] ){ 5 | 6 | char letter = 'b'; 7 | char sentence[100] = "2 words."; 8 | char *c_ptr1 = &letter; 9 | char *c_ptr2 = sentence; 10 | sentence[3] = 'i'; 11 | c_ptr2[2] = *c_ptr1; 12 | 13 | printf( "letter holds: %c\n", letter ); 14 | printf( "sentence holds: %s\n", sentence ); 15 | printf( "c_ptr1 holds: %c\n", *c_ptr1 ); 16 | printf( "c_ptr2 holds: %s\n", c_ptr2 ); 17 | 18 | int number = 42; 19 | int lotto_picks[7] = { 8, 18, 28, 38, 48, 58, 68 }; 20 | int *i_ptr1 = &number; 21 | int *i_ptr2 = lotto_picks; 22 | lotto_picks[3] = number; 23 | i_ptr1 = i_ptr2; 24 | i_ptr2[1] = *i_ptr1; 25 | 26 | printf( "number holds: %d\n", number ); 27 | printf( "lotto_picks holds:"); 28 | for( int pos=0; pos<7; pos++ ) 29 | printf( "%d ", lotto_picks[pos] ); 30 | printf( "\n" ); 31 | 32 | printf( "i_ptr1 holds: %d\n", *i_ptr1 ); 33 | printf( "i_ptr2 holds:"); 34 | for( int pos=0; pos<7; pos++ ) 35 | printf( "%d ", i_ptr2[pos] ); 36 | printf( "\n" ); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /ExampleCode/Lecture11-2DArrays/sort_argv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main( int argc, char *argv[] ){ 5 | 6 | // Consider one argument at a time 7 | for( int pos=0; pos 2 | #include 3 | 4 | int main(){ 5 | 6 | long int automatic_array_size = 2; 7 | while(1){ 8 | 9 | char automatic_array[automatic_array_size]; 10 | 11 | printf( "I managed to allocate a string of size %ld.\n", automatic_array_size ); 12 | 13 | automatic_array[automatic_array_size-1] = '2'; 14 | printf( "The last element holds %c.\n", automatic_array[automatic_array_size-1] ); 15 | 16 | automatic_array_size *= 2; 17 | } 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /ExampleCode/Lecture12-Memory/dynamic_array_alloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | 6 | long int dynamic_array_size = 2; 7 | char *dynamic_array; 8 | 9 | while(1){ 10 | 11 | dynamic_array = (char*)malloc( dynamic_array_size*sizeof(char) ); 12 | 13 | if( dynamic_array == NULL ){ 14 | printf( "I failed to allocate string of size %ld.\n", dynamic_array_size ); 15 | break; 16 | } 17 | 18 | printf( "I managed to allocate a string of size %ld.\n", dynamic_array_size ); 19 | 20 | dynamic_array[dynamic_array_size-1] = '2'; 21 | printf( "The last element holds %c.\n", dynamic_array[dynamic_array_size-1] ); 22 | 23 | free(dynamic_array); 24 | dynamic_array_size *= 2; 25 | } 26 | 27 | dynamic_array_size /= 2; // The last one that worked 28 | dynamic_array = (char*)malloc( dynamic_array_size*sizeof(char) ); 29 | 30 | if( dynamic_array != NULL ){ 31 | printf( "OK, populating an array of size %ld... how long will this take?\n", dynamic_array_size ); 32 | for( long int pos=0; pos 9 | #include 10 | 11 | char* f( int size ){ 12 | 13 | char stack_array[size]; 14 | strcpy( stack_array, "hello world" ); 15 | return stack_array; 16 | } 17 | 18 | int main() 19 | { 20 | char *ptr = f(20); 21 | ptr[0] = 'j'; 22 | printf( "%s\n", ptr ); 23 | 24 | char *ptr2 = f(20); 25 | ptr2[0] = 'j'; 26 | printf( "%s\n", ptr2 ); 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /ExampleCode/Lecture12-Memory/static_array_alloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static char static_array[STATIC_ARRAY_SIZE]; 6 | 7 | int main(){ 8 | 9 | printf( "I managed to statically allocate a string of size %ld.\n", (long int)STATIC_ARRAY_SIZE ); 10 | 11 | for( long int pos=0; pos<(long int)(STATIC_ARRAY_SIZE); pos++ ) 12 | static_array[pos] = '2'; 13 | 14 | printf( "The last element holds %c.\n", static_array[(long int)(STATIC_ARRAY_SIZE-1)] ); 15 | int input; 16 | 17 | // This loop "pauses" execution so we can see the impact on our computer 18 | while( (input=getchar()) != 'q' ){ 19 | usleep(10); 20 | } 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /ExampleCode/Lecture13-ImageFiles/bit_reporting.c: -------------------------------------------------------------------------------- 1 | /* File bit_reporting.c 2 | 3 | Uses the bit-wise operations left-shift and 4 | bitwise logical AND to sequentially check the 5 | bits within a single byte (character). 6 | Prints the results to screen and ensures 7 | the sum of the bitwise values adds up to the 8 | original number. 9 | 10 | Author: David Meger 11 | */ 12 | 13 | #include 14 | #include 15 | 16 | int main() 17 | { 18 | unsigned char c = 42; 19 | int bit_number; 20 | int bit_contribution; 21 | int total_value = 0; 22 | 23 | printf( "Considering the one-byte integer %d.\n", c ); 24 | 25 | for( bit_number=0; bit_number<8; bit_number++ ) 26 | { 27 | bit_contribution = c & (1< 0 ) 30 | printf( "Bit number %d was 1.\n", bit_number ); 31 | else 32 | printf( "Bit number %d was 0.\n", bit_number ); 33 | 34 | printf( "bit %d of c contributes %d.\n", bit_number, bit_contribution ); 35 | 36 | total_value += bit_contribution; 37 | } 38 | 39 | printf( "The total value of c was %d\n.", total_value ); 40 | 41 | return EXIT_SUCCESS; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /ExampleCode/Lecture13-ImageFiles/bmp_2_white.c: -------------------------------------------------------------------------------- 1 | /* FILE: bmp_2_white.c 2 | * 3 | * Our first example of changing image data. 4 | * Just sets it all to white. 5 | * 6 | */ 7 | #include 8 | 9 | int main(){ 10 | 11 | // Open a binary bmp file 12 | FILE *bmpfile = fopen( "utah.bmp", "rb" ); 13 | 14 | if( bmpfile == NULL ){ 15 | printf( "I was unable to open the file utah.bmp.\n" ); 16 | return -1; 17 | } 18 | 19 | char b, m; 20 | fread( &b, 1, 1, bmpfile ); 21 | fread( &m, 1, 1, bmpfile ); 22 | 23 | 24 | // Read the overall file size 25 | unsigned int overallFileSize; 26 | fread( &overallFileSize, 1, sizeof(unsigned int), bmpfile ); 27 | printf( "The size was: %d.\n", overallFileSize ); 28 | 29 | // Rewind file pointer to the beginning and read the entire contents. 30 | rewind(bmpfile); 31 | 32 | char imageData[overallFileSize]; 33 | if( fread( imageData, 1, overallFileSize, bmpfile ) != overallFileSize ){ 34 | printf( "I was unable to read the requested %d bytes.\n", overallFileSize ); 35 | return -1; 36 | } 37 | 38 | // To modify the pixel data, we need to make sure we dont 39 | // mess up the image header. Otherwise, image viewers will 40 | // no longer understand the file. Let's read the offset 41 | // and move a pointer forward. 42 | unsigned int* offsetp = (unsigned int*)(imageData+10); 43 | unsigned int offset = *offsetp; 44 | char *pixel_data = imageData + offset; 45 | 46 | // Now, indexing to pixel_data will only change the "visible" 47 | // data in the image. White is all of R, G and B = 255. 48 | // Warning! This changes the "padding" parts of the image also. 49 | // For A3, you will need a more sophisticated way of managing 50 | // the image data. 51 | for( int pixel=0; pixel< overallFileSize-offset; pixel++ ) 52 | pixel_data[pixel] = pixel; 53 | 54 | // Time to output, just dump the binary data, inverse of reading. 55 | FILE* out_file = fopen( "utah_white.bmp", "wb" ); 56 | if( out_file == NULL ){ 57 | printf( "Unable to open utah_white.bmp for writing.\n" ); 58 | return -1; 59 | } 60 | fwrite( imageData, 1, overallFileSize, out_file ); 61 | 62 | return 0; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /ExampleCode/Lecture13-ImageFiles/bmp_file_reader.c: -------------------------------------------------------------------------------- 1 | /* FILE: bmp_file_reader.c 2 | * 3 | * Uses the binary file reading toolkit such as fopen with "rb" 4 | * and fread rather than the string-based operations like fgets. 5 | * This is so that we dont have to worry about special characters 6 | * in the file and ensure we get all the header bytes. 7 | * 8 | * It should be a helpful start for Assignment 3 Question 1. 9 | */ 10 | 11 | #include 12 | 13 | int main(){ 14 | 15 | // Open a binary bmp file 16 | FILE *bmpfile = fopen( "utah.bmp", "rb" ); 17 | 18 | if( bmpfile == NULL ){ 19 | printf( "I was unable to open the file utah.bmp.\n" ); 20 | return -1; 21 | } 22 | 23 | // Read the B and M characters into chars 24 | char b, m; 25 | fread (&b,1,1,bmpfile); 26 | fread (&m,1,1,bmpfile); 27 | 28 | // Print the B and M to terminal 29 | printf( "The first byte was: %c.\n", b ); 30 | printf( "The second byte was: %c.\n", m ); 31 | 32 | // Read the overall file size 33 | unsigned int overallFileSize; 34 | fread( &overallFileSize, 1, sizeof(unsigned int), bmpfile ); 35 | printf( "The size was: %d.\n", overallFileSize ); 36 | 37 | // Rewind file pointer to the beginning and read the entire contents. 38 | rewind(bmpfile); 39 | 40 | char imageData[overallFileSize]; 41 | if( fread( imageData, 1, overallFileSize, bmpfile ) != overallFileSize ){ 42 | printf( "I was unable to read the requested %d bytes.\n", overallFileSize ); 43 | return -1; 44 | } 45 | 46 | // Read the width size into unsigned int (hope = 500 since this is the width of utah.bmp) 47 | unsigned int* wp = (unsigned int*)(imageData+18); 48 | unsigned int width = *wp; 49 | 50 | // Print the width size to terminal 51 | printf( "The width is: %d.\n", width ); 52 | 53 | return 0; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /ExampleCode/Lecture13-ImageFiles/endianness_test.c: -------------------------------------------------------------------------------- 1 | /* File endianness_test.c 2 | 3 | Explores the byte-ordering of integers 4 | on the system it's run on. By using a shorter 5 | pointer than the target data-type, we can access 6 | the int it one byte at a time. Most personal computer 7 | systems are "Little Endian". 8 | 9 | Author: David Meger 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | int main() 16 | { 17 | int a = 257; 18 | char *p = &a; 19 | 20 | printf( "The value at p is %d.\n", *p ); 21 | printf( "The value at p+1 is %d.\n", *(p+1) ); 22 | printf( "The value at p+2 is %d.\n", *(p+2) ); 23 | printf( "The value at p+3 is %d.\n", *(p+3) ); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ExampleCode/Lecture13-ImageFiles/mario_16_bit.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmeger/COMP206_Fall2018_Lectures_Public/fe5f3136e24658e52b526e8edbf9c6f5afb2cb01/ExampleCode/Lecture13-ImageFiles/mario_16_bit.bmp -------------------------------------------------------------------------------- /ExampleCode/Lecture13-ImageFiles/mario_message.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmeger/COMP206_Fall2018_Lectures_Public/fe5f3136e24658e52b526e8edbf9c6f5afb2cb01/ExampleCode/Lecture13-ImageFiles/mario_message.bmp -------------------------------------------------------------------------------- /ExampleCode/Lecture13-ImageFiles/pointer_conversion.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | 8 | char a[4]; 9 | memset( a, '\0', 4 ); 10 | a[0] = 'a'; 11 | int *p = (int*)a; 12 | 13 | printf( "The value of *p is %d.\n", *p ); 14 | 15 | int i = 257; 16 | char *cp = (char*)&i; 17 | 18 | printf( "The value of *cp is %d.\n", *cp ); 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /ExampleCode/Lecture13-ImageFiles/steg_decoder.c: -------------------------------------------------------------------------------- 1 | /* The file steg_decoder.c 2 | is a larger systems example to demonstrate 3 | input, output and memory manipulation in C. 4 | 5 | Build this file with: 6 | gcc -o decoder steg_decoder.c 7 | 8 | When both this, and the paired encoder are compiled, 9 | then you can pass a message using a bmp file with these commands: 10 | 11 | $ ./encoder mario_16_bit.bmp mario_message.bmp Your Message Here. 12 | $ ./decoder mario_message.bmp 13 | 14 | Make sure to view the original mario bitmap and the 15 | mario_message file to verify that you cannot visually detect the change. 16 | 17 | Author: David Meger 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | int main(int argc, char *argv[] ) 24 | { 25 | const int bmp_header_size = 54; 26 | const int max_msg_size = 1000; 27 | 28 | int i; 29 | int c; 30 | int img_idx = 0; 31 | int msg_idx = 0; 32 | int bit_idx = 0; 33 | 34 | if( argc < 2 ){ 35 | printf( "Usage: %s message_bmp.\n", argv[0] ); 36 | return 1; 37 | } 38 | 39 | char msg[max_msg_size]; 40 | FILE *img_in = NULL; 41 | 42 | img_in = fopen( argv[1], "rb" ); 43 | 44 | if( img_in == NULL ){ 45 | printf( "Could not open the input image file.\n" ); 46 | return 1; 47 | } 48 | 49 | // This for loop sets the character string initially to all 0's 50 | // This is to save us some trouble in having to explicitly zero-out 51 | // bits when we're decoding. Since all bits are set to 0 at first, we 52 | // now will only need to flip some of them to 1's as needed 53 | for( i=0; i < max_msg_size; i++ ) 54 | msg[i] = 0; 55 | 56 | // This while loop is the main decoding action. We loop through the image 57 | // and extract the lowest-order bits from each byte into msg 58 | while( ( c = fgetc( img_in )) != EOF ){ 59 | 60 | // The encoder did not touch the BMP header, so we also have to skip 61 | // those bytes here 62 | if( img_idx >= bmp_header_size ){ 63 | 64 | // This is how to check the lowest-order bit (from class-notes) 65 | if( ( c & 1 ) > 0 ) 66 | // If it was 1, use OR to set msg where we next need to write 67 | // into msg to be 1 (OR does not change any of its other bits) 68 | msg[msg_idx] |= 1 << bit_idx; 69 | // Note that no else was needed because msg starts as 0's 70 | 71 | // Move on to the next bit 72 | bit_idx++; 73 | 74 | // When we're done all 8 bits in a byte, move on to the next byte 75 | if( bit_idx >= 8 ){ 76 | // However, we know we're done reading the message when we see the 77 | // null character '\0' 78 | if( msg[msg_idx] == '\0' ) 79 | break; 80 | bit_idx = 0; 81 | msg_idx++; 82 | } 83 | } 84 | 85 | img_idx++; 86 | } 87 | 88 | printf( "Processed %d bytes.\n", img_idx ); 89 | printf( "The secret message is: %s\n", msg ); 90 | 91 | fclose(img_in); 92 | 93 | return 0; 94 | } 95 | 96 | -------------------------------------------------------------------------------- /ExampleCode/Lecture13-ImageFiles/steg_encoder.c: -------------------------------------------------------------------------------- 1 | /* The file steg_encoder.c 2 | is a larger systems example to demonstrate 3 | input, output and memory manipulation in C. 4 | 5 | Build this file with: 6 | gcc -o encoder steg_encoder.c 7 | 8 | When both this, and the paired decoder are compiled, 9 | then you can pass a message using a bmp file with these commands: 10 | 11 | $ ./encoder mario_16_bit.bmp mario_message.bmp Your Message Here. 12 | $ ./decoder mario_message.bmp 13 | 14 | Make sure to view the original mario bitmap and the 15 | mario_message file to verify that you cannot visually detect the change. 16 | 17 | Author: David Meger 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | int main(int argc, char *argv[] ) 24 | { 25 | const int bmp_header_size = 54; 26 | const int max_msg_size = 1000; 27 | int i; 28 | int curr_message_position=0; 29 | int read_code; 30 | int msg_idx = 0; 31 | int img_idx = 0; 32 | int bit_idx = 0; 33 | char c; 34 | char msg[max_msg_size]; 35 | FILE *img_in = NULL; 36 | FILE *img_out = NULL; 37 | 38 | if( argc < 4 ){ 39 | printf( "Usage: %s source_bmp output_bmp message.\n", argv[0] ); 40 | return 1; 41 | } 42 | 43 | img_in = fopen( argv[1], "rb" ); 44 | if( img_in == NULL ){ 45 | printf( "Could not open the input image file.\n" ); 46 | return 1; 47 | } 48 | 49 | img_out = fopen( argv[2], "wb" ); 50 | if( img_out == NULL ){ 51 | printf( "Could not open the output file.\n" ); 52 | return 1; 53 | } 54 | 55 | // This for loop is specific to the way the encoder puts the entire sentence 56 | // typed on the command-line into the image as a single string. 57 | // We loop over the arguments, which each hold one word of the sentence 58 | // and build up msg, placing spaces as appropriate. At its end, msg 59 | // holds the correct string we want to encode. 60 | for( i=3; i= bmp_header_size && msg_idx <= strlen( msg ) ){ 79 | 80 | // bit_mask will have exactly one "1" bit and seven "0" bits 81 | // See the lecture slides on bit-wise operations for details 82 | char bit_mask = 1 << bit_idx; 83 | 84 | // Use bit_mask to probe the appropriate bit in the message. 85 | // If it is 1, then use the OR operation to set the lowest-order 86 | // bit of c to 1. If it is 0, then use the AND operation to set the 87 | // lowest-order bit of c to 0. Again, details in the class slides. 88 | if( ( msg[msg_idx] & bit_mask) > 0 ) 89 | c |= 1; 90 | else 91 | c &= 254; 92 | 93 | // Move the bit index forward 94 | bit_idx++; 95 | 96 | // When we complete all 8 bits in a byte, move to the next byte 97 | if( bit_idx >= 8 ){ 98 | bit_idx = 0; 99 | msg_idx++; 100 | } 101 | } 102 | 103 | // Always write the resulting c value to the output file. Note that this will 104 | // sometimes be an exact copy from img_in (like for the header, or when we're 105 | // past the end of our string), and sometimes we'll have modified c with 106 | // bits from the message. 107 | fputc( c, img_out ); 108 | img_idx++; 109 | } 110 | 111 | printf( "I have hidden the secret within an image of %d bytes.\n", img_idx ); 112 | 113 | fclose(img_in); 114 | fclose(img_out); 115 | 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /ExampleCode/Lecture13-ImageFiles/utah.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmeger/COMP206_Fall2018_Lectures_Public/fe5f3136e24658e52b526e8edbf9c6f5afb2cb01/ExampleCode/Lecture13-ImageFiles/utah.bmp -------------------------------------------------------------------------------- /ExampleCode/Lecture15-LibrariesFnptrsSyscalls/headache.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int return5(){ 4 | return 5; 5 | } 6 | 7 | void mult( int a, int b){ 8 | 9 | printf( "%d\n", (a * b) ); 10 | } 11 | 12 | void add( int a, int b ){ 13 | 14 | printf( "%d\n", (a + b) ); 15 | } 16 | 17 | void call( void(*fn)() ){ 18 | 19 | fn( 5, 5 ); 20 | } 21 | 22 | int main(){ 23 | 24 | call( &add ); 25 | call( &mult ); 26 | 27 | int i; 28 | int *pi = &i; 29 | 30 | int (*fn)() = return5; 31 | 32 | *pi = return5(); 33 | 34 | printf( "fn returned %d.\n", fn() ); 35 | 36 | void (*p)(int, int); 37 | 38 | p = &add; 39 | p(5,5); 40 | 41 | p = mult; 42 | p(5,5); 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /ExampleCode/Lecture15-LibrariesFnptrsSyscalls/multi_sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int lt( char a, char b ){ 4 | return a < b; 5 | } 6 | 7 | int gt( char a, char b){ 8 | return a > b; 9 | } 10 | 11 | void sort( char* toSort, int (*comparison)(char,char), char max_val ){ 12 | 13 | while( *toSort ){ 14 | char *pos = toSort; 15 | char min = max_val; 16 | char *min_spot = NULL; 17 | while( *pos ){ 18 | 19 | if( comparison( *pos, min ) ){ 20 | min = *pos; 21 | min_spot = pos; 22 | } 23 | pos++; 24 | } 25 | if( min_spot ){ 26 | char temp = *min_spot; 27 | *min_spot = *toSort; 28 | *toSort = temp; 29 | } 30 | toSort++; 31 | } 32 | } 33 | 34 | int main(){ 35 | 36 | char toSort[100] = "tuiowerpjngklcadhgaioprejhalcx"; 37 | //sort( toSort, lt, 'z' ); 38 | sort( toSort, gt, 'a' ); 39 | printf( "Sorted version: %s.\n", toSort ); 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /ExampleCode/Lecture15-LibrariesFnptrsSyscalls/run_time_check.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "time_check.h" 3 | 4 | 5 | void main( ) 6 | { 7 | check_time(); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /ExampleCode/Lecture15-LibrariesFnptrsSyscalls/time_check.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | int check_time( ) 6 | { 7 | time_t t = time(NULL); 8 | 9 | struct tm tm = *localtime(&t); 10 | 11 | printf("Now: %d-%d-%d %d:%d:%d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); 12 | 13 | // Set up a tm struct to may 1st 2018 14 | tm.tm_year = 119; 15 | tm.tm_mon = 01; 16 | tm.tm_mday = 01; 17 | tm.tm_hour = 0; 18 | tm.tm_min = 0; 19 | tm.tm_sec = 0; 20 | 21 | time_t due_date = mktime( &tm ); 22 | printf( "The time_t value on the due date is: %ld.\n", due_date ); 23 | 24 | if( t < due_date ) 25 | { 26 | printf( "I will not tell you the answer until after the due date:\n" ); 27 | printf( "%d-%d-%d %d:%d:%d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec ); 28 | return 0; 29 | } 30 | 31 | printf( "The answer is 42.\n" ); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /ExampleCode/Lecture15-LibrariesFnptrsSyscalls/time_check.h: -------------------------------------------------------------------------------- 1 | int check_time( ); 2 | -------------------------------------------------------------------------------- /ExampleCode/Lecture15-LibrariesFnptrsSyscalls/time_hack.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | time_t time( time_t *seconds ) 4 | { 5 | return 1543699800; // This is the time value for some time on Dec 1st 2018 6 | 7 | } 8 | 9 | 10 | -------------------------------------------------------------------------------- /ExampleCode/Lecture16-structsLinkedList/simple_structs.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct student{ 4 | 5 | char name[100]; 6 | char grade; 7 | long int student_id; 8 | }; 9 | 10 | int main(){ 11 | 12 | struct student dave = { "Dave", '?', 2600000000 }; 13 | 14 | printf( "The struct entries are:\n name: %s\n grade: %c\n student_id: %ld\n", dave.name, dave.grade, dave.student_id ); 15 | 16 | printf( "The size of the struct is %ld.\n", sizeof(struct student) ); 17 | 18 | printf( "The addresses fields relative to the struct are:\n full struct: %ld\n name: %ld\n grade: %ld\n student_id: %ld\n", 19 | (long int)&dave - (long int)&dave, (long int)&(dave.name) - (long int)&dave, (long int)&(dave.grade) - (long int)&dave, (long int)&(dave.student_id) - (long int)&dave ); 20 | 21 | return 0; 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /ExampleCode/Lecture17-networking/add_ten.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for i in 0 1 2 3 4 5 6 7 8 9 4 | do 5 | x=`cat file` 6 | echo $x 7 | echo $(($x+1)) > file 8 | done 9 | 10 | -------------------------------------------------------------------------------- /ExampleCode/Lecture17-networking/client_inet.c: -------------------------------------------------------------------------------- 1 | /* 2 | * socket demonstrations: 3 | * This is the client side of an "internet domain" socket connection, for 4 | * communicating over the network. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int main() 15 | { 16 | int fd; 17 | struct sockaddr_in r; 18 | 19 | /* "AF_INET" specifies internet instead of some other type of connection */ 20 | if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 21 | perror("socket"); 22 | return(1); 23 | } 24 | 25 | /* Specify IP address and port number. */ 26 | memset(&r, '\0', sizeof r); 27 | r.sin_family = AF_INET; 28 | r.sin_addr.s_addr = htonl((127 << 24) | 1); 29 | r.sin_port = htons(1234); 30 | /* 31 | * That address is 127.0.0.1 -- take the 127 and shift it to the left 24 32 | * bits so as to put it in the upper octet. More commonly we would look 33 | * up a hostname with gethostbyname(). 34 | */ 35 | 36 | /* Now connect, go to look for the server! */ 37 | if (connect(fd, (struct sockaddr *)&r, sizeof r) < 0) { 38 | perror("connect"); 39 | return(1); 40 | } 41 | /* 42 | * Once we make it here, someone is listening. Let's say hello! 43 | */ 44 | if (write(fd, "Hello", 5) != 5) { 45 | perror("write"); 46 | return(1); 47 | } 48 | 49 | return(0); 50 | } 51 | 52 | -------------------------------------------------------------------------------- /ExampleCode/Lecture17-networking/server_inet.c: -------------------------------------------------------------------------------- 1 | /* 2 | * socket demonstrations: 3 | * This is the server side of an "internet domain" socket connection, for 4 | * communicating over the network. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int main() 15 | { 16 | int fd, clientfd; 17 | int len; 18 | socklen_t size; 19 | struct sockaddr_in r, q; 20 | char buf[80]; 21 | 22 | /* "AF_INET" says we'll use the internet */ 23 | if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 24 | perror("socket"); 25 | return(1); 26 | } 27 | 28 | /* Specify port number. Note, we do not give our address here because 29 | the server's job is to listen. The whole computer has an address, so 30 | this is the only one we can listen on. */ 31 | memset(&r, '\0', sizeof r); 32 | r.sin_family = AF_INET; 33 | r.sin_addr.s_addr = INADDR_ANY; 34 | r.sin_port = htons(1234); 35 | 36 | /* Bind connects the socket, tells the OS we're ready to use it. */ 37 | if (bind(fd, (struct sockaddr *)&r, sizeof r) < 0) { 38 | perror("bind"); 39 | return(1); 40 | } 41 | 42 | /* Listen blocks until a client tries to connect */ 43 | if (listen(fd, 5)) { 44 | perror("listen"); 45 | return(1); 46 | } 47 | 48 | /* Accept says, OK, let's talk! */ 49 | size = sizeof q; 50 | if ((clientfd = accept(fd, (struct sockaddr *)&q, &size)) < 0) { 51 | perror("accept"); 52 | return(1); 53 | } 54 | 55 | /* Read is now much like a file, we can keep grabbing data that's sent. */ 56 | if ((len = read(clientfd, buf, sizeof buf - 1)) < 0) { 57 | perror("read"); 58 | return(1); 59 | } 60 | buf[len] = '\0'; 61 | /* 62 | * Here we should be converting from the network newline convention to the 63 | * unix newline convention, if the string can contain newlines. Ignoring for 64 | * now to keep it simple. 65 | */ 66 | 67 | printf("The other side said: %s\n", buf); 68 | 69 | /* We're done listening to this client. */ 70 | close(clientfd); 71 | 72 | /* 73 | * We didn't really have to do that since we're exiting. 74 | * But usually you'd be looping around and accepting more connections. 75 | */ 76 | 77 | return(0); 78 | } 79 | 80 | -------------------------------------------------------------------------------- /ExampleCode/Lecture18-Internet2/echo_client.c: -------------------------------------------------------------------------------- 1 | #include //printf 2 | #include //strlen 3 | #include //socket 4 | #include //inet_addr 5 | #include 6 | #include 7 | #include 8 | 9 | int main(int argc , char *argv[]) 10 | { 11 | int sock; 12 | struct sockaddr_in server; 13 | char message[2000] , server_reply[2000]; 14 | char addr[20] = "127.0.0.1"; 15 | unsigned short int port = 8888; 16 | 17 | if( argc>1 ){ 18 | strcpy( addr, argv[1] ); 19 | } 20 | 21 | if( argc>2 ){ 22 | port = (unsigned short int)atoi( argv[2] ); 23 | } 24 | 25 | //Create socket 26 | sock = socket(AF_INET , SOCK_STREAM , 0); 27 | if (sock == -1) 28 | { 29 | printf("Could not create socket"); 30 | } 31 | puts("Socket created"); 32 | 33 | server.sin_addr.s_addr = inet_addr( argv[1] ); 34 | server.sin_family = AF_INET; 35 | server.sin_port = htons( port ); 36 | 37 | //Connect to remote server 38 | if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) 39 | { 40 | perror("connect failed. Error"); 41 | return 1; 42 | } 43 | 44 | puts("Connected\n"); 45 | 46 | //keep communicating with server 47 | while(1) 48 | { 49 | printf("Enter message : "); 50 | char* ret = fgets (message , 2000 , stdin); 51 | if( ret == NULL ){ 52 | break; 53 | } 54 | 55 | //Send some data 56 | if( send(sock , message , 2000, 0) < 0) 57 | { 58 | puts("Send failed"); 59 | return 1; 60 | } 61 | 62 | //Receive a reply from the server 63 | size_t read_size = recv(sock , server_reply , 2000 , 0); 64 | if( read_size < 0) 65 | { 66 | puts("recv failed"); 67 | break; 68 | } 69 | server_reply[read_size] = '\0'; 70 | 71 | printf("Server reply : %s\n", server_reply); 72 | } 73 | 74 | close(sock); 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /ExampleCode/Lecture18-Internet2/echo_server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include //strlen 3 | #include 4 | #include //inet_addr 5 | #include //write 6 | #include 7 | 8 | int main(int argc , char *argv[]) 9 | { 10 | int socket_desc , client_sock , c , read_size; 11 | struct sockaddr_in server , client; 12 | char client_message[2000]; 13 | 14 | unsigned short int port = 8888; 15 | 16 | if( argc > 1 ) 17 | port = (unsigned short int)atoi(argv[1]); 18 | 19 | //Create socket 20 | socket_desc = socket(AF_INET , SOCK_STREAM , 0); 21 | if (socket_desc == -1) 22 | { 23 | printf("Could not create socket"); 24 | } 25 | puts("Socket created"); 26 | 27 | //Prepare the sockaddr_in structure 28 | server.sin_family = AF_INET; 29 | server.sin_addr.s_addr = INADDR_ANY; 30 | server.sin_port = htons( port ); 31 | 32 | //Bind 33 | if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) 34 | { 35 | //print the error message 36 | perror("bind failed. Error"); 37 | return 1; 38 | } 39 | puts("bind done"); 40 | 41 | //Listen 42 | listen(socket_desc , 3); 43 | 44 | //Accept and incoming connection 45 | puts("Waiting for incoming connections..."); 46 | c = sizeof(struct sockaddr_in); 47 | 48 | //accept connection from an incoming client 49 | client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c); 50 | if (client_sock < 0) 51 | { 52 | perror("accept failed"); 53 | return 1; 54 | } 55 | puts("Connection accepted"); 56 | 57 | //Receive a message from client 58 | while( 1 ){ 59 | char temp[2000]; 60 | memset(client_message, '\0', 2000); 61 | int bytes_read = 0; 62 | while( bytes_read < 2000 ){ 63 | read_size = recv(client_sock , temp , 2000 , 0); 64 | if(read_size <= 0){ 65 | puts("Client disconnected"); 66 | fflush(stdout); 67 | close(client_sock); 68 | close(socket_desc); 69 | return 0; 70 | } 71 | memcpy( client_message+bytes_read, temp, read_size ); 72 | bytes_read += read_size; 73 | } 74 | 75 | //Send the message back to client 76 | write(client_sock , client_message , strlen(client_message)); 77 | } 78 | 79 | close(client_sock); 80 | close(socket_desc); 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /ExampleCode/Lecture19-Web/Makefile: -------------------------------------------------------------------------------- 1 | all: httpd http_client 2 | 3 | http_client: simpleclient.c 4 | gcc simpleclient.c -o http_client 5 | 6 | httpd: httpd.c 7 | gcc -W -Wall -lpthread -o httpd httpd.c 8 | 9 | clean: 10 | rm httpd http_client 11 | 12 | -------------------------------------------------------------------------------- /ExampleCode/Lecture19-Web/README: -------------------------------------------------------------------------------- 1 | Parts of this example were started from open source code, here: 2 | https://sourceforge.net/projects/tinyhttpd/ 3 | It has been modified by David Meger to make it fit COMP 206 4 | well. However, almost all of the credit goes to the original 5 | author, and here is his open-source license information: 6 | 7 | This software is copyright 1999 by J. David Blackstone. Permission 8 | is granted to redistribute and modify this software under the terms of 9 | the GNU General Public License, available at http://www.gnu.org/ . 10 | 11 | -------------------------------------------------------------------------------- /ExampleCode/Lecture19-Web/htdocs/README: -------------------------------------------------------------------------------- 1 | These are sample CGI scripts and webpages for tinyhttpd. They can 2 | be redistributed under the terms of the GPL. 3 | 4 | The most impressive demonstration I gave of tinyhttpd to my 5 | professor and my classmates was to load color.cgi with a value of 6 | "chartreuse." :) It's actually a very simple script, guys. 7 | 8 | jdb 9 | -------------------------------------------------------------------------------- /ExampleCode/Lecture19-Web/htdocs/check.cgi: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl -Tw 2 | 3 | use strict; 4 | use CGI; 5 | 6 | my($cgi) = new CGI; 7 | 8 | print $cgi->header('text/html'); 9 | print $cgi->start_html(-title => "Example CGI script", 10 | -BGCOLOR => 'red'); 11 | print $cgi->h1("CGI Example"); 12 | print $cgi->p, "This is an example of CGI\n"; 13 | print $cgi->p, "Parameters given to this script:\n"; 14 | print "
    \n"; 15 | foreach my $param ($cgi->param) 16 | { 17 | print "
  • ", "$param ", $cgi->param($param), "\n"; 18 | } 19 | print "
"; 20 | print $cgi->end_html, "\n"; 21 | -------------------------------------------------------------------------------- /ExampleCode/Lecture19-Web/htdocs/color.cgi: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl -Tw 2 | 3 | use strict; 4 | use CGI; 5 | 6 | my($cgi) = new CGI; 7 | 8 | print $cgi->header; 9 | my($color) = "blue"; 10 | $color = $cgi->param('color') if defined $cgi->param('color'); 11 | 12 | print $cgi->start_html(-title => uc($color), 13 | -BGCOLOR => $color); 14 | print $cgi->h1("This is $color"); 15 | print $cgi->end_html; 16 | -------------------------------------------------------------------------------- /ExampleCode/Lecture19-Web/htdocs/index.html: -------------------------------------------------------------------------------- 1 | 2 | Index 3 | 4 |

Welcome to the COMP 206 Web Server 5 |

CGI demo 6 |
7 | Enter a color: 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /ExampleCode/Lecture19-Web/htdocs/lecture_example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hello world! 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ExampleCode/Lecture19-Web/htdocs/output.html: -------------------------------------------------------------------------------- 1 | Content-Type: text/html; charset=ISO-8859-1 2 | 3 | 6 | 7 | 8 | BLUE 9 | 10 | 11 | 12 |

This is blue

13 | 14 | -------------------------------------------------------------------------------- /ExampleCode/Lecture19-Web/httpd.c: -------------------------------------------------------------------------------- 1 | /* FILE: httpd.c is a simple web server to give you a flavor of web programming. 2 | * 3 | * It serves html pages from the htdocs directory, and can run simple CGIs. 4 | * 5 | * It was adapted from J. David's webserver that is available free on sourceforge 6 | * Created November 1999 by J. David Blackstone. 7 | * CSE 4344 (Network concepts), Prof. Zeigler 8 | * University of Texas at Arlington 9 | */ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define ISspace(x) isspace((int)(x)) 24 | 25 | #define SERVER_STRING "Server: jdbhttpd/0.1.0\r\n" 26 | 27 | void accept_request(int); 28 | void bad_request(int); 29 | void cat(int, FILE *); 30 | void cannot_execute(int); 31 | void error_die(const char *); 32 | void execute_cgi(int, const char *, const char *, const char *); 33 | int get_line(int, char *, int); 34 | void headers(int, const char *); 35 | void not_found(int); 36 | void serve_file(int, const char *); 37 | int startup(u_short *); 38 | void unimplemented(int); 39 | 40 | /**********************************************************************/ 41 | /* A request has caused a call to accept() on the server port to 42 | * return. Process the request appropriately. 43 | * Parameters: the socket connected to the client */ 44 | /**********************************************************************/ 45 | void accept_request(int client) 46 | { 47 | char buf[1024]; 48 | int numchars; 49 | char method[255]; 50 | char url[255]; 51 | char path[512]; 52 | size_t i, j; 53 | struct stat st; 54 | int cgi = 0; /* becomes true if server decides this is a CGI 55 | * program */ 56 | char *query_string = NULL; 57 | 58 | numchars = get_line(client, buf, sizeof(buf)); 59 | 60 | i = 0; j = 0; 61 | while (!ISspace(buf[j]) && (i < sizeof(method) - 1)) 62 | { 63 | method[i] = buf[j]; 64 | i++; j++; 65 | } 66 | method[i] = '\0'; 67 | 68 | if (strcasecmp(method, "GET") && strcasecmp(method, "POST")) 69 | { 70 | unimplemented(client); 71 | return; 72 | } 73 | 74 | if (strcasecmp(method, "POST") == 0) 75 | cgi = 1; 76 | 77 | i = 0; 78 | while (ISspace(buf[j]) && (j < sizeof(buf))) 79 | j++; 80 | while (!ISspace(buf[j]) && (i < sizeof(url) - 1) && (j < sizeof(buf))) 81 | { 82 | url[i] = buf[j]; 83 | i++; j++; 84 | } 85 | url[i] = '\0'; 86 | 87 | if (strcasecmp(method, "GET") == 0) 88 | { 89 | query_string = url; 90 | while ((*query_string != '?') && (*query_string != '\0')) 91 | query_string++; 92 | if (*query_string == '?') 93 | { 94 | cgi = 1; 95 | *query_string = '\0'; 96 | query_string++; 97 | } 98 | } 99 | 100 | sprintf(path, "htdocs%s", url); 101 | if (path[strlen(path) - 1] == '/') 102 | strcat(path, "index.html"); 103 | if (stat(path, &st) == -1) { 104 | while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ 105 | numchars = get_line(client, buf, sizeof(buf)); 106 | not_found(client); 107 | } 108 | else 109 | { 110 | if ((st.st_mode & S_IFMT) == S_IFDIR) 111 | strcat(path, "/index.html"); 112 | if ((st.st_mode & S_IXUSR) || 113 | (st.st_mode & S_IXGRP) || 114 | (st.st_mode & S_IXOTH) ) 115 | cgi = 1; 116 | if (!cgi) 117 | serve_file(client, path); 118 | else 119 | execute_cgi(client, path, method, query_string); 120 | } 121 | 122 | close(client); 123 | } 124 | 125 | /**********************************************************************/ 126 | /* Inform the client that a request it has made has a problem. 127 | * Parameters: client socket */ 128 | /**********************************************************************/ 129 | void bad_request(int client) 130 | { 131 | char buf[1024]; 132 | 133 | sprintf(buf, "HTTP/1.0 400 BAD REQUEST\r\n"); 134 | send(client, buf, sizeof(buf), 0); 135 | sprintf(buf, "Content-type: text/html\r\n"); 136 | send(client, buf, sizeof(buf), 0); 137 | sprintf(buf, "\r\n"); 138 | send(client, buf, sizeof(buf), 0); 139 | sprintf(buf, "

Your browser sent a bad request, "); 140 | send(client, buf, sizeof(buf), 0); 141 | sprintf(buf, "such as a POST without a Content-Length.\r\n"); 142 | send(client, buf, sizeof(buf), 0); 143 | } 144 | 145 | /**********************************************************************/ 146 | /* Put the entire contents of a file out on a socket. This function 147 | * is named after the UNIX "cat" command, because it might have been 148 | * easier just to do something like pipe, fork, and exec("cat"). 149 | * Parameters: the client socket descriptor 150 | * FILE pointer for the file to cat */ 151 | /**********************************************************************/ 152 | void cat(int client, FILE *resource) 153 | { 154 | char buf[1024]; 155 | 156 | fgets(buf, sizeof(buf), resource); 157 | while (!feof(resource)) 158 | { 159 | send(client, buf, strlen(buf), 0); 160 | fgets(buf, sizeof(buf), resource); 161 | } 162 | } 163 | 164 | /**********************************************************************/ 165 | /* Inform the client that a CGI script could not be executed. 166 | * Parameter: the client socket descriptor. */ 167 | /**********************************************************************/ 168 | void cannot_execute(int client) 169 | { 170 | char buf[1024]; 171 | 172 | sprintf(buf, "HTTP/1.0 500 Internal Server Error\r\n"); 173 | send(client, buf, strlen(buf), 0); 174 | sprintf(buf, "Content-type: text/html\r\n"); 175 | send(client, buf, strlen(buf), 0); 176 | sprintf(buf, "\r\n"); 177 | send(client, buf, strlen(buf), 0); 178 | sprintf(buf, "

Error prohibited CGI execution.\r\n"); 179 | send(client, buf, strlen(buf), 0); 180 | } 181 | 182 | /**********************************************************************/ 183 | /* Print out an error message with perror() (for system errors; based 184 | * on value of errno, which indicates system call errors) and exit the 185 | * program indicating an error. */ 186 | /**********************************************************************/ 187 | void error_die(const char *sc) 188 | { 189 | perror(sc); 190 | exit(1); 191 | } 192 | 193 | /**********************************************************************/ 194 | /* Execute a CGI script. Will need to set environment variables as 195 | * appropriate. 196 | * Parameters: client socket descriptor 197 | * path to the CGI script */ 198 | /**********************************************************************/ 199 | void execute_cgi(int client, const char *path, 200 | const char *method, const char *query_string) 201 | { 202 | char buf[1024]; 203 | int cgi_output[2]; 204 | int cgi_input[2]; 205 | pid_t pid; 206 | int status; 207 | int i; 208 | char c; 209 | int numchars = 1; 210 | int content_length = -1; 211 | 212 | printf( "In execute cgi with path %s, method %s, and query_string %s.\n", path, method, query_string ); 213 | 214 | buf[0] = 'A'; buf[1] = '\0'; 215 | if (strcasecmp(method, "GET") == 0) 216 | while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ 217 | numchars = get_line(client, buf, sizeof(buf)); 218 | else /* POST */ 219 | { 220 | numchars = get_line(client, buf, sizeof(buf)); 221 | while ((numchars > 0) && strcmp("\n", buf)) 222 | { 223 | buf[15] = '\0'; 224 | if (strcasecmp(buf, "Content-Length:") == 0) 225 | content_length = atoi(&(buf[16])); 226 | numchars = get_line(client, buf, sizeof(buf)); 227 | } 228 | if (content_length == -1) { 229 | bad_request(client); 230 | return; 231 | } 232 | } 233 | 234 | sprintf(buf, "HTTP/1.0 200 OK\r\n"); 235 | send(client, buf, strlen(buf), 0); 236 | 237 | if (pipe(cgi_output) < 0) { 238 | cannot_execute(client); 239 | return; 240 | } 241 | if (pipe(cgi_input) < 0) { 242 | cannot_execute(client); 243 | return; 244 | } 245 | 246 | if ( (pid = fork()) < 0 ) { 247 | cannot_execute(client); 248 | return; 249 | } 250 | if (pid == 0) /* child: CGI script */ 251 | { 252 | char meth_env[255]; 253 | char query_env[255]; 254 | char length_env[255]; 255 | 256 | dup2(cgi_output[1], 1); 257 | dup2(cgi_input[0], 0); 258 | close(cgi_output[0]); 259 | close(cgi_input[1]); 260 | sprintf(meth_env, "REQUEST_METHOD=%s", method); 261 | putenv(meth_env); 262 | if (strcasecmp(method, "GET") == 0) { 263 | sprintf(query_env, "QUERY_STRING=%s", query_string); 264 | putenv(query_env); 265 | } 266 | else { /* POST */ 267 | sprintf(length_env, "CONTENT_LENGTH=%d", content_length); 268 | putenv(length_env); 269 | printf( "httpd got a post request and will execute %s.\n", path ); 270 | } 271 | execl(path, path, NULL); 272 | exit(0); 273 | } else { /* parent */ 274 | close(cgi_output[1]); 275 | close(cgi_input[0]); 276 | if (strcasecmp(method, "POST") == 0) 277 | for (i = 0; i < content_length; i++) { 278 | recv(client, &c, 1, 0); 279 | write(cgi_input[1], &c, 1); 280 | } 281 | while (read(cgi_output[0], &c, 1) > 0) 282 | send(client, &c, 1, 0); 283 | 284 | close(cgi_output[0]); 285 | close(cgi_input[1]); 286 | waitpid(pid, &status, 0); 287 | } 288 | } 289 | 290 | /**********************************************************************/ 291 | /* Get a line from a socket, whether the line ends in a newline, 292 | * carriage return, or a CRLF combination. Terminates the string read 293 | * with a null character. If no newline indicator is found before the 294 | * end of the buffer, the string is terminated with a null. If any of 295 | * the above three line terminators is read, the last character of the 296 | * string will be a linefeed and the string will be terminated with a 297 | * null character. 298 | * Parameters: the socket descriptor 299 | * the buffer to save the data in 300 | * the size of the buffer 301 | * Returns: the number of bytes stored (excluding null) */ 302 | /**********************************************************************/ 303 | int get_line(int sock, char *buf, int size) 304 | { 305 | int i = 0; 306 | char c = '\0'; 307 | int n; 308 | 309 | while ((i < size - 1) && (c != '\n')) 310 | { 311 | n = recv(sock, &c, 1, 0); 312 | /* DEBUG printf("%02X\n", c); */ 313 | if (n > 0) 314 | { 315 | if (c == '\r') 316 | { 317 | n = recv(sock, &c, 1, MSG_PEEK); 318 | /* DEBUG printf("%02X\n", c); */ 319 | if ((n > 0) && (c == '\n')) 320 | recv(sock, &c, 1, 0); 321 | else 322 | c = '\n'; 323 | } 324 | buf[i] = c; 325 | i++; 326 | } 327 | else 328 | c = '\n'; 329 | } 330 | buf[i] = '\0'; 331 | 332 | return(i); 333 | } 334 | 335 | /**********************************************************************/ 336 | /* Return the informational HTTP headers about a file. */ 337 | /* Parameters: the socket to print the headers on 338 | * the name of the file */ 339 | /**********************************************************************/ 340 | void headers(int client, const char *filename) 341 | { 342 | char buf[1024]; 343 | (void)filename; /* could use filename to determine file type */ 344 | 345 | strcpy(buf, "HTTP/1.0 200 OK\r\n"); 346 | send(client, buf, strlen(buf), 0); 347 | strcpy(buf, SERVER_STRING); 348 | send(client, buf, strlen(buf), 0); 349 | sprintf(buf, "Content-Type: text/html\r\n"); 350 | send(client, buf, strlen(buf), 0); 351 | strcpy(buf, "\r\n"); 352 | send(client, buf, strlen(buf), 0); 353 | } 354 | 355 | /**********************************************************************/ 356 | /* Give a client a 404 not found status message. */ 357 | /**********************************************************************/ 358 | void not_found(int client) 359 | { 360 | char buf[1024]; 361 | 362 | sprintf(buf, "HTTP/1.0 404 NOT FOUND\r\n"); 363 | send(client, buf, strlen(buf), 0); 364 | sprintf(buf, SERVER_STRING); 365 | send(client, buf, strlen(buf), 0); 366 | sprintf(buf, "Content-Type: text/html\r\n"); 367 | send(client, buf, strlen(buf), 0); 368 | sprintf(buf, "\r\n"); 369 | send(client, buf, strlen(buf), 0); 370 | sprintf(buf, "Not Found\r\n"); 371 | send(client, buf, strlen(buf), 0); 372 | sprintf(buf, "

The server could not fulfill\r\n"); 373 | send(client, buf, strlen(buf), 0); 374 | sprintf(buf, "your request because the resource specified\r\n"); 375 | send(client, buf, strlen(buf), 0); 376 | sprintf(buf, "is unavailable or nonexistent.\r\n"); 377 | send(client, buf, strlen(buf), 0); 378 | sprintf(buf, "\r\n"); 379 | send(client, buf, strlen(buf), 0); 380 | } 381 | 382 | /**********************************************************************/ 383 | /* Send a regular file to the client. Use headers, and report 384 | * errors to client if they occur. 385 | * Parameters: a pointer to a file structure produced from the socket 386 | * file descriptor 387 | * the name of the file to serve */ 388 | /**********************************************************************/ 389 | void serve_file(int client, const char *filename) 390 | { 391 | FILE *resource = NULL; 392 | int numchars = 1; 393 | char buf[1024]; 394 | 395 | buf[0] = 'A'; buf[1] = '\0'; 396 | while ((numchars > 0) && strcmp("\n", buf)) /* read & discard headers */ 397 | numchars = get_line(client, buf, sizeof(buf)); 398 | 399 | resource = fopen(filename, "r"); 400 | if (resource == NULL) 401 | not_found(client); 402 | else 403 | { 404 | headers(client, filename); 405 | cat(client, resource); 406 | } 407 | fclose(resource); 408 | } 409 | 410 | /**********************************************************************/ 411 | /* This function starts the process of listening for web connections 412 | * on a specified port. If the port is 0, then dynamically allocate a 413 | * port and modify the original port variable to reflect the actual 414 | * port. 415 | * Parameters: pointer to variable containing the port to connect on 416 | * Returns: the socket */ 417 | /**********************************************************************/ 418 | int startup(u_short *port) 419 | { 420 | int httpd = 0; 421 | struct sockaddr_in name; 422 | 423 | httpd = socket(PF_INET, SOCK_STREAM, 0); 424 | if (httpd == -1) 425 | error_die("socket"); 426 | memset(&name, 0, sizeof(name)); 427 | name.sin_family = AF_INET; 428 | name.sin_port = htons(*port); 429 | name.sin_addr.s_addr = htonl(INADDR_ANY); 430 | if (bind(httpd, (struct sockaddr *)&name, sizeof(name)) < 0) 431 | error_die("bind"); 432 | if (*port == 0) /* if dynamically allocating a port */ 433 | { 434 | socklen_t namelen = sizeof(name); 435 | if (getsockname(httpd, (struct sockaddr *)&name, &namelen) == -1) 436 | error_die("getsockname"); 437 | *port = ntohs(name.sin_port); 438 | } 439 | if (listen(httpd, 5) < 0) 440 | error_die("listen"); 441 | return(httpd); 442 | } 443 | 444 | /**********************************************************************/ 445 | /* Inform the client that the requested web method has not been 446 | * implemented. 447 | * Parameter: the client socket */ 448 | /**********************************************************************/ 449 | void unimplemented(int client) 450 | { 451 | char buf[1024]; 452 | 453 | sprintf(buf, "HTTP/1.0 501 Method Not Implemented\r\n"); 454 | send(client, buf, strlen(buf), 0); 455 | sprintf(buf, SERVER_STRING); 456 | send(client, buf, strlen(buf), 0); 457 | sprintf(buf, "Content-Type: text/html\r\n"); 458 | send(client, buf, strlen(buf), 0); 459 | sprintf(buf, "\r\n"); 460 | send(client, buf, strlen(buf), 0); 461 | sprintf(buf, "Method Not Implemented\r\n"); 462 | send(client, buf, strlen(buf), 0); 463 | sprintf(buf, "\r\n"); 464 | send(client, buf, strlen(buf), 0); 465 | sprintf(buf, "

HTTP request method not supported.\r\n"); 466 | send(client, buf, strlen(buf), 0); 467 | sprintf(buf, "\r\n"); 468 | send(client, buf, strlen(buf), 0); 469 | } 470 | 471 | /**********************************************************************/ 472 | 473 | int main(void) 474 | { 475 | int server_sock = -1; 476 | u_short port = 0; 477 | int client_sock = -1; 478 | struct sockaddr_in client_name; 479 | socklen_t client_name_len = sizeof(client_name); 480 | // pthread_t newthread; 481 | 482 | server_sock = startup(&port); 483 | printf("httpd running on port %d\n", port); 484 | 485 | while (1) 486 | { 487 | client_sock = accept(server_sock, 488 | (struct sockaddr *)&client_name, 489 | &client_name_len); 490 | if (client_sock == -1) 491 | error_die("accept"); 492 | accept_request(client_sock); 493 | } 494 | 495 | close(server_sock); 496 | 497 | return(0); 498 | } 499 | 500 | 501 | -------------------------------------------------------------------------------- /ExampleCode/Lecture19-Web/simpleclient.c: -------------------------------------------------------------------------------- 1 | /* FILE: simple_web_client.c implements the HTTP interface 2 | * in order to download information from the web. 3 | * Compile and run it with a web address like example.com 4 | * in order to see the pages returned. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | int main(int argc, char** argv) { 18 | 19 | struct addrinfo hints; 20 | memset(&hints, 0, sizeof hints); 21 | hints.ai_family = AF_INET ; 22 | hints.ai_socktype = SOCK_STREAM; 23 | struct addrinfo *servinfo; 24 | int status = getaddrinfo(argv[1], "80", 25 | &hints, &servinfo); 26 | int sockfd = socket(servinfo->ai_family, 27 | servinfo->ai_socktype, 28 | servinfo->ai_protocol); 29 | connect(sockfd, 30 | servinfo->ai_addr, 31 | servinfo->ai_addrlen); 32 | 33 | char header[1000]; 34 | sprintf(header, "GET /index.html HTTP/1.1\r\nHost:%s\r\n\r\n", argv[1] ); 35 | int n = write(sockfd, header, strlen(header)); 36 | 37 | char buffer[2048]; 38 | n = read(sockfd, buffer, 2048); 39 | printf("%s", buffer); 40 | 41 | return (EXIT_SUCCESS); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /ExampleCode/Lecture20-CGI/chat.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 15 | 16 |
No messages yet.
10 |
11 |
12 |
13 |
14 |
17 | -------------------------------------------------------------------------------- /ExampleCode/Lecture20-CGI/first.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main(void) { 3 | printf("Content-Type: text/plain;charset=us-ascii\n\n"); 4 | printf("Hello world\n\n"); 5 | return 0; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ExampleCode/Lecture20-CGI/mult.html: -------------------------------------------------------------------------------- 1 |

2 |
3 |
4 |
5 |
6 | 7 | -------------------------------------------------------------------------------- /ExampleCode/Lecture20-CGI/second.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main(void) 4 | { 5 | char *data; 6 | long m,n; 7 | printf("%s%c%c\n", "Content-Type:text/html;charset=iso-8859-1",13,10); 8 | printf("Multiplication results\n"); 9 | printf("

Multiplication results

\n"); 10 | data = getenv("QUERY_STRING"); 11 | if(data == NULL) 12 | printf("

Error! Error in passing data from form to script."); 13 | else if(sscanf(data,"m=%ld&n=%ld",&m,&n)!=2) 14 | printf("

Error! Invalid data. Data must be numeric."); 15 | else 16 | printf("

The product of %ld and %ld is %ld.",m,n,m*n); 17 | return 0; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ExampleCode/Lecture21-MultiProcess/fork_execl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | 9 | int x = fork(); 10 | 11 | if( x == -1 ){ 12 | perror( "fork failed" ); 13 | return 1; 14 | } else if( x == 0 ){ 15 | // Child 16 | char *argument = "directory_that_doesnt_exist"; 17 | execl( "/bin/ls", "ls", argument, (char*)NULL); 18 | perror( "/bin/ls" ); 19 | return(1); 20 | } else{ 21 | // Parent 22 | int status, pid; 23 | printf( "I am about to wait for ls to run.\n" ); 24 | pid = wait( &status ); 25 | printf( "pid %d exit status %d\n", pid, WEXITSTATUS(status)); 26 | return 0; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ExampleCode/Lecture21-MultiProcess/schedule_race.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define MAX_COUNT 200 7 | #define BUF_SIZE 100 8 | 9 | int main(){ 10 | 11 | pid_t pid; 12 | int i; 13 | char buf[BUF_SIZE]; 14 | 15 | fork(); 16 | pid = getpid(); 17 | 18 | for( i=1; i<=MAX_COUNT; i++ ){ 19 | 20 | sprintf( buf, "This line is from pid %d, value=%d\n", pid, i ); 21 | write(1,buf,strlen(buf)); 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /ExampleCode/Lecture22-Coordination/synched_counting.c: -------------------------------------------------------------------------------- 1 | // An example of using semaphores 2 | // to control the order of counting. 3 | // 4 | // Compile with -lpthread 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #define MAX_COUNT 200 14 | #define BUF_SIZE 100 15 | 16 | sem_t *s1; 17 | sem_t *s2; 18 | 19 | int main(){ 20 | 21 | pid_t pid; 22 | int i; 23 | char buf[BUF_SIZE]; 24 | 25 | sem_unlink("first"); 26 | sem_unlink("second"); 27 | s1 = sem_open( "first", O_CREAT, 0066, 1 ); 28 | s2 = sem_open( "second", O_CREAT, 0066, 0 ); 29 | 30 | int x = fork(); 31 | pid = getpid(); 32 | 33 | for( i=1; i<= MAX_COUNT; i++ ){ 34 | 35 | if( x == 0 ){ 36 | sem_wait( s1 ); 37 | } 38 | else{ 39 | sem_wait( s2 ); 40 | } 41 | 42 | sprintf( buf, "This line is from pid %d, value = %d\n", pid, i ); 43 | write( 1, buf, strlen(buf)); 44 | 45 | if( x==0 ){ 46 | sem_post(s2); 47 | } 48 | else{ 49 | sem_post(s1); 50 | } 51 | } 52 | 53 | sem_close(s1); 54 | sem_close(s2); 55 | } 56 | 57 | -------------------------------------------------------------------------------- /ExampleCode/Lecture4-BashIfForWhile/directory_of_sample_files/a.txt: -------------------------------------------------------------------------------- 1 | Content of file a 2 | -------------------------------------------------------------------------------- /ExampleCode/Lecture4-BashIfForWhile/directory_of_sample_files/b.txt: -------------------------------------------------------------------------------- 1 | Content of file b 2 | -------------------------------------------------------------------------------- /ExampleCode/Lecture4-BashIfForWhile/directory_of_sample_files/c.txt: -------------------------------------------------------------------------------- 1 | Content of file c 2 | -------------------------------------------------------------------------------- /ExampleCode/Lecture4-BashIfForWhile/directory_of_sample_files/d.txt: -------------------------------------------------------------------------------- 1 | Content of file d 2 | -------------------------------------------------------------------------------- /ExampleCode/Lecture4-BashIfForWhile/example_if.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # A first simple example with if 4 | # You can try modifying the condition 5 | # such as using the [[ ]] syntax to do 6 | # the same thing 7 | # 8 | 9 | x=$((3*5)) 10 | 11 | if `test $x -lt 14` 12 | then 13 | echo Math is borken. 14 | else 15 | echo Bash can multiply! 16 | fi 17 | 18 | echo By the way x=$x. 19 | -------------------------------------------------------------------------------- /ExampleCode/Lecture4-BashIfForWhile/for_over_files.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # A first example for loop 4 | # Very often we want to loop over the files in a 5 | # directory and do the same thing to all of them. 6 | # 7 | # This script changes the extension of all files 8 | # in a sub-directory to ".dat". 9 | # 10 | 11 | for f in `ls directory_of_sample_files` 12 | do 13 | 14 | echo The file was named $f 15 | 16 | without_ext=$(echo $f | cut -d. -f1) 17 | new_name=${without_ext}.dat 18 | 19 | echo I will move it to $new_name 20 | 21 | mv directory_of_sample_files/${f} directory_of_sample_files/${new_name} 22 | 23 | done 24 | 25 | -------------------------------------------------------------------------------- /ExampleCode/Lecture4-BashIfForWhile/while_calendar.bash: -------------------------------------------------------------------------------- 1 | days_of_week=" Su M Tu W Th F Sa" 2 | echo $days_of_week 3 | 4 | day_of_month=1 5 | curr_position=3 6 | echo -n " " 7 | 8 | while [[ $day_of_month -le 30 ]] 9 | do 10 | printf " %02d" ${day_of_month} 11 | 12 | day_of_month=$((day_of_month+1)) 13 | 14 | curr_position=$(($curr_position+1)) 15 | 16 | if [[ $curr_position == 7 ]] 17 | then 18 | curr_position=1 19 | echo "" 20 | fi 21 | done 22 | 23 | -------------------------------------------------------------------------------- /ExampleCode/Lecture6-CIntro/args.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main( int argc, char *argv[] ){ 4 | 5 | printf( "I have %d args.\n", argc ); 6 | printf( "First was %s.\n", argv[0] ); 7 | printf( "Second was %s.\n", argv[1] ); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /ExampleCode/Lecture6-CIntro/beyond_array.c: -------------------------------------------------------------------------------- 1 | // 2 | // This file is an example of what not to do 3 | // The programmer has not matched up the array bounds 4 | // with the loop limit, and so this program will read 5 | // beyond the end of the valid array. 6 | // 7 | // Run it with different array limits (including really big ones 8 | // in millions or billions to see what happens. 9 | // 10 | 11 | #include 12 | 13 | int main(){ 14 | 15 | int array[10]; 16 | for( int i=0; i<100; i++ ) 17 | printf( "Value of array at %d is %d.\n", i, array[i] ); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /ExampleCode/Lecture6-CIntro/sorting_exercise_starter.c: -------------------------------------------------------------------------------- 1 | /* FILE: sorting_excersize_starter.c 2 | * 3 | * Please fill this in with some code to sort. You can use the 4 | * linear sort algorithm suggested on the Lecture 6 slides 5 | * or something you learned in a previous course. 6 | * Good luck! 7 | * 8 | * Author: David Meger 9 | * Date: Sept 19, 2018 10 | */ 11 | 12 | #include 13 | 14 | int main(){ 15 | 16 | int array[4]; 17 | 18 | array[0] = 4; 19 | array[1] = 2; 20 | array[2] = 1; 21 | array[3] = 3; 22 | 23 | // Write your code here, try to sort the array 24 | 25 | printf( "The array holds: " ); 26 | for( int i=0; i<4; i++ ) 27 | printf( "%d ", array[i] ); 28 | 29 | printf("\n"); 30 | 31 | printf( "If you coded it correctly, you should see 1 2 3 4\n"); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /ExampleCode/Lecture6-CIntro/temp.c: -------------------------------------------------------------------------------- 1 | /* FILE: temp.c 2 | * 3 | * A first overview at using variables in C and while loops 4 | * 5 | * Author: David Meger 6 | * Date: Sept 19, 2018 7 | */ 8 | 9 | #include 10 | int main(){ 11 | int fahr, celcius; 12 | int lower, upper, step; 13 | 14 | lower=0; 15 | upper=300; 16 | step=20; 17 | fahr = lower; 18 | 19 | while( fahr <= upper ){ 20 | celcius = 5 * (fahr-32)/9; 21 | printf( "%d\t%d\n", fahr, celcius); 22 | fahr = fahr + step; 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /ExampleCode/Lecture6-CIntro/temp_for.c: -------------------------------------------------------------------------------- 1 | /* FILE: temp_for.c 2 | * 3 | * A second version of the same functionality as temp.c to show 4 | * the for loop syntax in a C program 5 | * 6 | */ 7 | 8 | #include 9 | int main(){ 10 | int fahr; 11 | for( fahr=0; fahr<=300; fahr = fahr + 20 ) 12 | printf( "%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32)); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /ExampleCode/Lecture7-TextData/max_int_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(){ 4 | 5 | int val=0; 6 | 7 | while( 1 ) 8 | printf( "Val holds: %d.\n", val++ ); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /ExampleCode/Lecture8-StringAlgorithms/array_vs_ptr.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(){ 4 | 5 | char array[1000]; 6 | 7 | for( int pos=0; pos<1000; pos++ ){ 8 | array[pos] = 'a'+(pos%26); 9 | } 10 | array[999] = '\0'; 11 | printf( "Array holds: %s\n", array ); 12 | 13 | char *ptr = "hello"; 14 | ptr[0] = 'a'; 15 | //for( int pos=0; pos<1000; pos++ ){ 16 | // ptr[pos] = 'a'+(pos%26); 17 | //} 18 | //ptr[999] = '\0'; 19 | 20 | printf( "Ptr holds: %s\n", ptr ); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ExampleCode/Lecture8-StringAlgorithms/merge_sort.c: -------------------------------------------------------------------------------- 1 | /* File: merge_sort.c is a simple example of one of the easiest 2 | O(nlgn) sorting algorithms. We break the input in half 3 | repeatedly until we hit pieces of size 1. Then, we begin 4 | to merge neighboring pieces, where merge sorts the result 5 | if and only if both pieces were already sorted. Since 6 | a piece of size 1 is automatically sorted, merge_sort 7 | succeeeds to sort the entire input. 8 | 9 | This is an example of a recursive C program that you 10 | should consider as en example to help with A2. 11 | 12 | Autho: David Meger 13 | */ 14 | 15 | #include 16 | #define type int 17 | 18 | // Merge is a simple algorithm that tries to shuffle pieces like a deck of cards. 19 | int merge( type left[], type right[], type result[], int left_size, int right_size, int result_size ){ 20 | 21 | int pos_left=0; 22 | int pos_right=0; 23 | 24 | for( int pos=0; pos 2 | 3 | int main(){ 4 | 5 | char str_var[100] = "world"; 6 | 7 | int length = 0; 8 | for( int pos=0; pos<100; pos++ ){ 9 | 10 | if( str_var[pos] == '\0' ) break; 11 | length++; 12 | } 13 | 14 | printf( "The string %s has length %d.\n", str_var, length ); 15 | 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /ExampleCode/Lecture8-StringAlgorithms/my_strlen_pointerized.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(){ 4 | 5 | char str_var[100] = "world"; 6 | 7 | int length = 0; 8 | char *ptr = str_var; 9 | 10 | while( *ptr ){ 11 | ptr++; 12 | length++; 13 | } 14 | 15 | printf( "The string %s has length %d.\n", str_var, length ); 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /ExampleCode/Lecture9-libraries_debug/fgetc_example.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(){ 4 | 5 | 6 | int input_char; 7 | 8 | FILE *fp = fopen( "myfile.txt", "r" ); 9 | 10 | while( (input_char = fgetc( fp )) != EOF ){ 11 | 12 | printf( "I read the character %c.\n", input_char ); 13 | 14 | } 15 | 16 | printf( "The value of EOF is %d.\n", EOF ); 17 | 18 | return 0; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /ExampleCode/Lecture9-libraries_debug/file_reader.c: -------------------------------------------------------------------------------- 1 | // This program reads in a whole file using fseek and ftell to get the size 2 | // Then prints the AASCI code for each character in the resulting string. 3 | 4 | #include 5 | 6 | int main(){ 7 | 8 | FILE* fp; 9 | fp = fopen( "myfile.txt", "r" ); 10 | fseek( fp, 0L, SEEK_END ); 11 | int sz = ftell(fp); 12 | rewind(fp); 13 | 14 | char file_data_array[sz+1]; 15 | fread( file_data_array, 1, sz+1, fp ); 16 | printf( "File contents:\n%s\n", file_data_array ); 17 | 18 | for( int pos=0; pos 2 | 3 | int main(){ 4 | 5 | FILE *fp = fopen( "hurricane_data.csv", "r" ); 6 | 7 | if( !fp ) return -1; 8 | 9 | fseek( fp, 0, SEEK_END ); 10 | int size = ftell( fp ); 11 | rewind(fp); 12 | 13 | char array[size+1]; 14 | fread( array, 1, size+1, fp ); 15 | 16 | int this_word_start=0; 17 | 18 | for( int pos=0; pos 2 | 3 | int main(){ 4 | 5 | FILE *fp = fopen( "hurricane_data.csv", "r" ); 6 | 7 | if( !fp ) return -1; 8 | 9 | fseek( fp, 0, SEEK_END ); 10 | int size = ftell( fp ); 11 | rewind(fp); 12 | 13 | char array[size+1]; 14 | fread( array, 1, size+1, fp ); 15 | 16 | char *this_word = array; 17 | char *pos = array; 18 | 19 | while( *pos ){ 20 | if( pos[0] == ',' || pos[0] == '\n' ){ 21 | pos[0] = '\0'; 22 | printf( "Word was: %s\n", this_word ); 23 | this_word = pos+1; 24 | } 25 | pos++; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ExampleCode/Lecture9-libraries_debug/parse_csv_stringH.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(){ 5 | 6 | FILE *fp = fopen( "hurricane_data.csv", "r" ); 7 | 8 | if( !fp ) return -1; 9 | 10 | fseek( fp, 0, SEEK_END ); 11 | int size = ftell( fp ); 12 | rewind(fp); 13 | 14 | char array[size+1]; 15 | fread( array, 1, size+1, fp ); 16 | 17 | char *this_word = array; 18 | char *word_end = strtok(array,",\n"); 19 | 20 | while( this_word != NULL ){ 21 | printf( "Word was: %s\n", this_word ); 22 | this_word = strtok( NULL, ",\n"); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ExampleCode/SampleMidtermAnswers/encrypt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void encrypt( char source[], char destination[], int key ){ 5 | 6 | // Your code starts here 7 | int length = 0; 8 | while( source[length] != '\0'){ 9 | length++; 10 | } 11 | 12 | char *ptr2 = destination + length; 13 | *ptr2 = '\0'; 14 | ptr2--; 15 | char* ptr = source; 16 | 17 | while( *ptr ){ 18 | *ptr2 = *ptr; 19 | 20 | for( int shift=0; shift 2 | 3 | int main( int argc, char *argv[] ){ 4 | 5 | 6 | if( argc<2 ){ 7 | printf( "Argument required: filename.\n" ); 8 | return -1; 9 | } 10 | 11 | FILE* fp = fopen( argv[1], "r" ); 12 | 13 | if( !fp ){ 14 | printf( "Unable to open file %s.\n", argv[1] ); 15 | return -1; 16 | } 17 | 18 | 19 | fseek( fp, 0, SEEK_END ); 20 | size_t size = ftell( fp ); 21 | rewind( fp ); 22 | 23 | char file_data[ size ]; 24 | 25 | fread( file_data, 1, size, fp ); 26 | 27 | char *pos = file_data; 28 | 29 | 30 | while( *pos ){ 31 | printf( "%c\n", *pos ); 32 | pos++; 33 | 34 | while( *pos != '\r' && *pos != '\n' && *pos != ' ' ){ 35 | if( *pos == '\0' ) 36 | break; 37 | pos++; 38 | } 39 | 40 | while( *pos == '\n' || *pos == '\r' || *pos == ' ' ) 41 | pos++; 42 | 43 | } 44 | 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /ExampleCode/SampleMidtermAnswers/simple_calc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main( int argc, char *argv[] ){ 6 | 7 | 8 | int result = atoi(argv[1]); 9 | argv += 2; 10 | 11 | while( *argv ){ 12 | 13 | if( strcmp( *argv, "x" ) == 0 ) 14 | result *= atoi(argv[1]); 15 | else if( strcmp( *argv, "/" ) == 0 ) 16 | result /= atoi(argv[1]); 17 | else if( strcmp( *argv, "+" ) == 0 ) 18 | result += atoi(argv[1]); 19 | else if( strcmp( *argv, "-" ) == 0 ) 20 | result -= atoi(argv[1]); 21 | else{ 22 | printf( "There was an error. Operator %s not OK.\n", *argv ); 23 | return -1; 24 | } 25 | 26 | argv += 2; 27 | } 28 | 29 | printf( "%d\n", result ); 30 | 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /ExampleCode/SampleMidtermAnswers/test_letter_file.txt: -------------------------------------------------------------------------------- 1 | one two three four 2 | five six seven 3 | eight 4 | n 5 | i 6 | n 7 | e 8 | ten 9 | 10 | -------------------------------------------------------------------------------- /ExampleCode/Tutorial3_CBootcamp/MallocQuestion/allocWords.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char** allocWords( int numWords, int wordLengths[] ){ 6 | 7 | // FILL IN FROM HERE 8 | // 9 | // TO HERE... so that the rest of hte program works! 10 | } 11 | 12 | int main( int argc, char *argv[] ){ 13 | 14 | int wordLengths[argc-1]; 15 | for( int word=1; word 2 | #define MAX_ARGS 1000 3 | 4 | void parseArgs( char* raw_command_line, int *argc, char *argv[MAX_ARGS] ){ 5 | // You fill in this code during the exam 6 | 7 | *argc=0; 8 | argv[(*argc)++] = raw_command_line; 9 | 10 | while( *raw_command_line ){ 11 | if( *raw_command_line == ' ' ){ 12 | *raw_command_line = '\0'; 13 | argv[(*argc)++] = raw_command_line + 1; 14 | } 15 | raw_command_line++; 16 | } 17 | 18 | // End of your solution 19 | } 20 | 21 | void main_like( char *raw_command_line ){ 22 | 23 | int argc; 24 | char *argv[MAX_ARGS]; 25 | parseArgs(raw_command_line, &argc, argv ); 26 | 27 | printf( "raw_command_line was %s\n", raw_command_line ); 28 | for( int i=0; i 2 | #include 3 | #define MAX_ARGS 1000 4 | 5 | void parseArgs( char* raw_command_line, int *argc, char *argv[MAX_ARGS] ){ 6 | // You fill in this code during the exam 7 | 8 | int argNumber = 0; 9 | argv[argNumber] = (char*)malloc(MAX_ARGS*sizeof(char)); 10 | 11 | int argPos = 0; 12 | 13 | while( *raw_command_line ){ 14 | 15 | 16 | if( *raw_command_line != ' ' ){ 17 | argv[argNumber][argPos] = *raw_command_line; 18 | argPos++; 19 | } 20 | else{ 21 | argv[argNumber][argPos] = '\0'; 22 | argNumber++; 23 | argv[argNumber] = (char*)malloc(MAX_ARGS*sizeof(char)); 24 | argPos = 0; 25 | } 26 | 27 | raw_command_line++; 28 | } 29 | 30 | argv[argNumber][argPos] = '\0'; 31 | *argc = argNumber + 1; 32 | 33 | // End of your solution 34 | } 35 | 36 | void main_like( char *raw_command_line ){ 37 | 38 | int argc; 39 | char *argv[MAX_ARGS]; 40 | parseArgs(raw_command_line, &argc, argv ); 41 | 42 | printf( "raw_command_line was %s\n", raw_command_line ); 43 | for( int i=0; i 2 | #include 3 | #define MAX_ARGS 1000 4 | 5 | void parseArgs( char* raw_command_line, int *argc, char *argv[MAX_ARGS] ){ 6 | // You fill in this code during the exam 7 | 8 | int rawPos = 0; 9 | char argArray[MAX_ARGS][MAX_ARGS]; 10 | int lenArray[MAX_ARGS]; 11 | 12 | for( int arg=0; arg