School 42

Background

42 is a free international programing school (franchise) that operates on a unique project-based and peer-learning model with a large degree of flexibility regarding pace and mode of study. Anyone 18+ can apply and there are no prerequisites, rather acceptance is determined by your performance throughout a 3-4 week intensive programming “piscine”, comprised of multiple projects and exams, with relative performance improvements valued over incoming skill level.

What interested me most about their model was the focus on lower level programming languages (C. C++) as well as system and networking fundamentals (bash/linux/servers/etc.) – this is not something I have seen offered at other coding programs outside of a university context and something I felt was missing from my background as a fledgling programmer.

I was accepted into the 42 Florence program and began attending in March 2024 – I complete projects and exams when I can, in between moving from US to Italy and my work obligations.

Projects

42 is comprised of a range of individual and group projects (some mandatory, some with multiple variants to choose from), many building upon work from previous projects. Many students put their completed projects on Github to show off their hard work, but this is prohibited by the 42 organization as it can tempt students to cheat (projects are the same across countries and campuses). For this reason, I have not shared my progress publicly on Github and try not to look at the raw code of other students (though I do look at READMEs and blogs of past students at times to gain insight into different approaches as well as interpretations of project instructions).

My plan, when I have time, is to go through all my project notes and synthesize a conceptual guide for each project I have completed, while making sure I do not divulge too many details that would ruin the learning process.

Below is a very rough summary of projects I have completed so far (Click project to expand)

Libft – Fundamental C functions (string handling, memory management, operations, linked lists)

The initial curriculum is C-based and you are prohibited from using all but a select few functions from the standard C libraries. Therefore, the first project is to build your own personal library of functions that will serve as the basis of future projects. This library (or any project going forward) should not have memory leaks or unhandled failure modes (ex. segfaults) and every component function must be under 25 lines (but can call other functions).

Using only the following three standard functions:

  • write (write a buffer pointer to a file descriptor)
  • malloc (allocate memory of a given byte size)
  • free (free allocated memory located at a given pointer)

I wrote 43 user-accessible functions (excludes sub-functions) and a makefile and headerfile to compile said functions into a c-library called “Libft” which I can now import and use in my projects going forward. The majority of functions performed string or numerical operations as well as number-to-string conversions, linked-list operations, and memory-safe functions for copying and moving data.

I learned a lot about memory management, creating clean single-purpose functions, and how to stop worrying and love the man pages.

Ft_printf – Writing to stdout

The goal of Ft_printf was to re-implement the well known printf function from the stdout library which takes in a string with placeholder symbols and a variable number of arguments of variable types, placing them in their corresponding location in the string before writing it to stdout

// • %c Prints a single character.
// • %s Prints a string (as defined by the common C convention).
// • %p The void * pointer argument has to be printed in hexadecimal format.
// • %d Prints a decimal (base 10) number.
// • %i Prints an integer in base 10.
// • %u Prints an unsigned decimal (base 10) number.
// • %x Prints a number in hexadecimal (base 16) lowercase format.
// • %X Prints a number in hexadecimal (base 16) uppercase format.
// • %% Prints a percent sign.
ft_printf("ft_printf: %c , %s, %p, %d, %i, %u, %x, %X %% (multi_test)\n\0", c,s,p,d,i,u,x,X);

This project taught me a lot about variadic functions in C, how to reverse engineer from man pages, input validation, and some more advanced Makefile techniques.

Get_Next_Line – Reading from Files

The objective of get next line is to create a function that can return lines read from a given file descriptor, with each subsequent call resulting in a new line until it reaches the end of the file.

char *get_next_line(int fd);

This project seemed fairly easy at first, but it required the introduction of buffer memory allocation and management and the use of static variables to keep a constant memory location (meaning the whatever value is stored in the variable will still be there when the function is re-called).

To qualify for the bonus, I was able to use only one static variable for the whole project which I used to store an array of memory positions from which to resume reading upon next function call. My function also supported the reading of multiple files, allowing the user to pull lines from different files within the same program without losing their place.

Born2BeRoot – Unix System Setup & Config (Virtual Machine, Users, SSH, Server Security, Scripting)

This project was a departure from C and an introduction to Linux System Administration. This project required the creation and configuration of a virtual machine with strict security protocols and a custom monitoring script and SSH server. The use of graphical interfaces was forbidden, all work was done from a terminal interface. (No config process info or scripts shown, just example output)

Major Steps included:

Use of VirtualBox to create a new Debian machine with expert install – partition discs, create LVM configuration, create root user, configure package manager, install grub bootloader on primary drive

Setup SSH Server – install AppArmor, configure SSH ports to reject root access, configure and enable UFW (frontend for iptables), configure sshd config files accordingly, installed openssh-server and setup port forwarding in VirtualBox

Setup user and sudo groups of various permissions (ex. path access), controls, and corresponding log files.

Created a more comprehensive password policy with libpam-pwquality and config files (includes checks against common passwords, reuse, length and complexity rules, and automatic expiration)

Used chronjobs to run a custom monitoring script every 10 minutes for all users – broadcast to all users and saved to monitor file. This monitoring script described system state aggregated from a number of different bash operations.

Bonus Work

Install and config of additional service failtoban to lock out users for a set time after multiple failed access attempts

Installation of lighttpd (web server), MariaDB (SQL database tool), and PHP in order to host a website.

  • Created a mySQL database with secure install, granted user access, configured PHP settings and started a FastCGI server
  • Installed latest version of wordpress now accessible via a newly opened port on the VM.

This project taught me a *lot*. I learned about granular access controls based on users, groups, and services – as well as how services are run and can have their own corresponding permissions (ex. certain services are permitted to communicate only over specific ports). This project was really eye-opening – and revealing of how when you visit a site, you are communicating with a server not dissimilar to how this host computer communicates with this virtual machine. This definitely helped demystify some aspects of the internet and web hosting for me.

Pipex – Bash Pipe Simulator

The objective of this project was to create a program that replicates the behavior of the pipe “|” operator in bash — which is used to pass the output from one operation to the input of another in the terminal:
ex:

./pipex file1 cmd1 cmd2 cmd3 .... file2 
 
//should behave exactly like
 
< file1 cmd1 | cmd2 | cmd3 ... > file2

For this project we were allowed to use a number of new functions relating to piping, forking, and executing programs, as well as more elaborate error handling.

I learned about creating and redirecting pipes, child and parent processes and PID state handling for the first time. I also learned how a C program can check user access permissions, read environment variables, and execute programs outside of itself. Error handling and memory cleanup became more complicated than in previous projects, particularly when errors could be thrown from multiple child processes and programs — I learned to use the memory checker tool Valgrind much more effectively.

Push Swap – Efficient stack sorting (algorithms for limited memory space)

Push swap is a sorting challenge designed to test your ability to efficiently sort a randomized list of numbers given an artificial constraint of two number stacks – you can rotate the stacks, swap the first two values of a given stack, or swap the first two values between the stacks. Your program should accept a randomized list of unique numbers and output a sequence of operations to sort them. The fewer the operations, the higher your score.

There are a lot of sorting algorithms out there, but most of them do not operate within these constraints, so it is not as easy as simply pulling an algo off the shelf and implementing it. This project has been done enough however that there are known algorithms available online specifically for this project. In the end, I decided not to look at them and instead used a custom sorting method that involved chunking and sub-sorting based on size of initial list. I was not able to achieve the max score but got a decent grade without consulting other solutions, which I’m happy with.

This project required a large amount of setup before getting to the actual algorithmic implementation – including input validation and normalization, linked-lists and structs, lookup functions (to identify shortest paths to desired elements) and and sub-operations for sorting algorithms and batching.

All in all, excluding the Libft functions, my pushswap used a total of 60 functions – I realized that this project took me much less time than Libft, despite me writing much more code — a reassurance that I am getting more fluent in C.

Fdf – X11 window graphics (rendering projected wireframe views of map files)
(color artifacts and flashing are present only in screen capture process – couldn’t get a good recording)

This was my favorite project to date – for this project, we were required to use a low-level graphics library that interfaces with the X11 windows manager in order to render isometric projections of depth map files to the screen. For bonus points, I added additional features including zoom, variable perspective and z-axis scaling to emphasize map features.

A high-level overview of how my project developed:

  • Created a map parser (convert text to 2D array)
  • Rendered 2D map (to check correct orientation, image building sequence)
  • Tested Basic rendering expansion (create space between map vertices)
  • Create Alpha gradient to visualize depth (switched to more interesting maps once I confirmed orientation of rendering was correct)
  • Expanded and projected Map Isometrically to image buffer array

( I created my projection equations by modifying some standard forms found in this blog post )

My projection equations look *similar* but not identical to those below:

  • Created a line-draw function (interpolated between points after projection and drew connecting lines)
  • Implemented X11 window hooks for key inputs and clean exit operations (needed to make sure that no memory was lost after program shutdown)

From this project, I learned how to integrate an external library with various dependencies into my project Makefile and build it alongside my program. I learned about the differences between image buffer, canvas, window, and display in graphics management. I was introduced to C hook functions for the first time (which allowed my program to respond to user input by listening for keyboard and mouse message events), as well as memory representation of pixel maps and common rendering procedures (writing to buffer array before updating window makes for a more performant program). I also enjoyed the geometry aspects of this project and am excited to create future graphical interfaces using pure C.

….will update periodically