A network monitoring service with pthreads in pure C.
/-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\
| |
| ::^~^::: :: |
| :^~~JPGPJ5GB#&&&&&#GYJ?!: : : |
| ::!YB#&&@@@@@@@@@@@@@@@@@@@@@#GPY7~^: : |
| ^!?YP#&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&B5!: |
| :!Y#&@&&@@@@@@@@@@@@@&&&##BBBBGBBB&&&&@@@@@@@@@&5?~: |
| :!JYB&@@@@@@@@@@@@@@@&&#??77^~^ : :::^~!JP5G&@@@&#B?^ |
| ^?P#&@@@@@@@@@@@@@@@&&BYPGJPY?PP?!?Y~!^^^::::: :!?P#@@&BY^ |
| Y#&@@@@@@@@@@@@@@@&#BGBPBG##P&##&##5B&GB5?YY?5!7~~:^::: ~5B&&P~: |
| !&@@@@@@@@@@@@@@&&#&B&&#&@@@&@&@&@&@@@&&&&#&&#B#GYY5??~~~^~ : ~?#&P^ |
| Y@@@@@@@@@@@&&G&B#&&@&GPYJ7!!!7!!7?Y5PGB#&&&&&&&&#&B#BP557!~^!!: ?&#? |
| :^?B##&&#BB5GBB#@@YY~^: :~J: :~ :!~::~7JPB&@&@&&&&GBPPPY?J!!^: :YB~ |
| :~~!?JJJY555P#&@@&BGGY5J?^^~?5&@&B#&&PPB&&J^7?: :^^~JG#&&&###P#PG5J???^: ~7 |
| ^^!J7555BBG&&&@@@#5PBBY?75B&@@@@@@@@@@@@@@@&&@#5GP~ :~?G#@#&GGPGP5G57~:: |
| ^~7GJPP#B&B&&@&&BPGP5J!P&@@&#@@@&@@@@@@@@@@@@@&@@&BJ!~!~ :!5#BGP5GPPP~~: |
| !??PGBG&G#5&@@#&##B5!P@@&#P!P@@@@@@@@@@@@&&&@@BGB#&@@@&Y!~!^ :!55?YJ7~: |
| !??PBG5GG#&&@#7!5G55J#@&B?!^ ?@@@@#G@@@@@&&&@@@!::~!5P#&@@&PPY~ |
| :~?J5G#G#&&5! :JPB#@&57: :B@@@B5@@@@&&&&@@5: :75BBPY! |
| :!7YPBG#G: ?@&J^:P5~ :P&@@@@@&@@@@@#? ^~!J~ :~!^!:: |
| :^?J5YJY: :!?7YJ?7^: ^YB&&@@@&#P7 ::~!!?JJ!: :^!J?Y?7!:: |
| : :: :^^^:P#&##5BPP??|^: :^~~~^ ^^~~77JJ5J7^ ^75PJ5YY~^^ |
| :^!7BB&#G&BB&G#PGJYGGGP555P5JYYY555GPJ?!!~: ::^J55PBGP??|^: |
| :^7~PJBBG#&@&&@B&GJGJP?^~~~7~!7!~^:^7: ::^~~!~?GPB#5P5P?~ |
| :^^~J7YYBG#B#&B&&&&##&#BB5JY?5J?~7!^?5BGG&BB#G&#GJJ!^^: |
| :^!7!JY5YBYG5GBG&G#&#&##&#B&B#BGG###BGBP5YY^^: |
| ^ ~:!^77?YJYPJ5G5P55YGP?57PPJJ7?~^^:: |
| : :^:::: ^~:!^^^ : |
| |
|-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-|
| |
! ░░░ ░░ ░░░░░░░ ░░░░░░░░ ░░░ ░░░ ░░░░░░ ░░░ ░░ !
! ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒▒▒ ▒▒▒▒ ▒▒ ▒▒ ▒▒▒▒ ▒▒ !
: ▒▒ ▒▒ ▒▒ ▒▒▒▒▒ ▒▒ ▒▒ ▒▒▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ ▒▒ :
: ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ ▓▓ :
. ██ ████ ███████ ██ ██ ██ ██████ ██ ████ .
. by lpaulo-m .
. .
. __ __ ___ __ __ __ :
: / / \|\ | | |__)/ \| (_ :
: \__\__/| \| | | \ \__/|____) :
! !
! - CONTROL+Q: Exits program cleanly. !
! - CONTROL+C: Exits program. !
| |
\-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-/This is a network monitor that periodically sends request
and saves the results to a .log file.
It currently handles HTTP, HTTPS, PING and DNS requests.
It can be configured im multiple ways with the netmon.db file.
Each line in the file specifies a target, protocol,
and request frequency (period between requests).
Columns are tab-separated and must conform to the format:
====================================================================================================
| PROTOCOL | ROWS (tab separated) |
====================================================================================================
| HTTP | name HTTP address http_method expected_http_code frequency_in_seconds |
| HTTPS | name HTTPS address http_method expected_http_code frequency_in_seconds |
| PING | name PING address frequency_in_seconds |
| DNS | name DNS address frequency_in_seconds dns_server_ipv4 |
====================================================================================================The program parses the file and spawns a scheduler thread for each target that periodically enqueues a new request in the request pool. It also spawns worker threads that dequeue and perform the requests.
The worker then prints a simplified result of the request to STDOUT
and saves all the relevant data to the specified .log file.
It can also parse the log file and print it to STDOUT
in simple form with the flag --simplify.
The thread pool implementation is based on CodeVault's video:
I handled HTTPS request with libcurl,
and made my own implementation of HTTP, PING and DNS based on:
- https://www.youtube.com/watch?v=bdIiTxtMaKA&list=PL9IEJIKnBJjH_zM5LnovnoaKlXML5qh17&index=2
- https://www.geeksforgeeks.org/ping-in-c/
- https://www.theinsanetechie.in/2016/02/dns-lookup-implementation-in-c.html
This program uses Raw Sockets for the PING implementation
and must be executed with root privileges
(or any other user with CAP_NET_ADMIN capability).
To compile and run this program you will need:
- A shell and a C compiler (
gccideally). GNU Makeinstalled in your computer.
You will also need to install libcurl as a dev dependency.
You can get it through apt-get (recommended):
$ sudo apt-get install libcurl4-openssl-devOr you can install it manually:
$ wget https://curl.se/download/curl-7.84.0.zip
$ unzip curl-7.84.0.zip
$ cd curl-7.84.0
$ ./configure --with-openssl --prefix=$HOME/.local
$ make
$ make installClone the repo and build with make:
$ git clone --recurse-submodules https://github.com/42sp/ft_netmon.git ft_netmon
$ cd ft_netmon
$ makeIt should create a netmon executable that you can run with sudo ./netmon.
-hand--help: Print the help message.-sand--simplify: Parse the.logfile and print it toSTDOUTin simple form.-dand--debug: Verbose, prints debug throughout runtime.--config-file <file>: Specify the config file path (default./netmon.db).--log-file <file>: Specify the log file path (default./netmon.log).--workers <number>: Set the initial number of worker threads (default8).
- Follows
norminette 3.3.51 - Makefile rules:
$(NAME)allcleanfcleanre - Compile an executable named
netmon. - Compiles with
-Wall -Wextra -Werror - Should not quit unexpectedly (segmentation fault, bus error, double free, etc.)
- All allocated heap memory properly freed, no memory leaks.
- Check memory leaks with
valgrind
- Check memory leaks with
- Allowed functions:
- Anything you want, as long as you can reasonably justify it.
- Handle flags
-
-hand—helpdisplay help message and exits cleanly. -
-sand—simplifyreads the log file, prints it in simple form toSTDOUTand exits cleanly. -
-dand—debugflags that print debug info through runtime. -
—config-file <file>Set the config file path (default./netmon.db) -
--log-file <file>Set the log file path (default./netmon.log) -
--workers <number>Set the initial number of worker threads (default8).
-
- Validate config file
netmon.db:- Handle comments with
#. - Validate
HTTPconfigs:- Should have 6 tab-separated fields
- Validate
HTTP_METHOD. - Validate expected
HTTP_CODE. - Validate timeout in seconds (
unsigned int> 0).
- Validate
PINGconfigs:- Should have 4 tab-separated fields
- Validate timeout in seconds (
unsigned int> 0).
- Validate
DNSconfigs:- Should have 5 tab-separated fields
- Validate timeout in seconds (
unsigned int> 0). - Validate IPv4 address
- Handle comments with
- Parse configs for each protocol:
- Parse
HTTPtargets - Parse
PINGtargets - Parse
DNStargets
- Parse
- Each monitoring service/request must use the configurations defined in
netmon.db. - Handle request with a Thread Pool
- Spawn workers that:
- Dequeue task safely (
mutexandcond) - Perform network requests
- Display the simplified result to
STDOUT. - Save all relevant request data to log file in parsable form.
- Dequeue task safely (
- Spawn a scheduler for every target in config file:
- Enqueue target request safely (
mutexandcond) - Enqueue every
timeoutseconds.
- Enqueue target request safely (
- All threads exit cleanly and join main thread on
CONTROL+Qwith no deadlocks.- Enable tty raw mode and manually handle key presses.
- Spawn workers that:
- Requests:
-
HTTP- Get IP with
getaddrinfo() - My own implementation with
sys/socket.h - Save all relevant request data to log file in parsable form.
- Get IP with
-
HTTPS- Use
libcurlfor the entire thing - Save all relevant request data to log file in parsable form.
- Use
-
PING- Get IP with
getaddrinfo() - My own implementation with
sys/socket.h - Save all relevant request data to log file in parsable form.
- Get IP with
-
DNS- My own implementation with
sys/socket.h - Save all relevant request data to log file in parsable form.
- My own implementation with
-
-
netmon.logshould contain all available request data. -
netmon.logshould be saved in parsable form, such that it can be displayed simply with the--simplifyflag. - Should work as an useful and professional network monitoring service.
- Clean and readable code.
- Add a beautiful
README.mdexplaining how the program works. - Come up with simple and creative solutions.
- Follow specs as much as possible.
- Parse add extra flags
- Add help message.
- Set custom config path.
- Set custom log path.
- Take special care with optimizations, code quality and design patterns.
- Use external tools to plan and track various stages of development.
- Notify bad request through Discord, email, Slack or Webhook.
- Thoroughly test the application:
- Flag tests
- Config tests
- Thread Pool tests
- Request handler tests
- Logger tests
- Identifies odd behaviors in target services, like and increase in latency.
- Aggregate analysis of
netmon.logdata, with diagrams and graphs on the CLI. - Handle
MQTTandTCPrequests/monitoring:-
TCP- My own implementation with
sys/socket.h - Save all relevant request data to log file in parsable form.
- My own implementation with
-
MQTT- Use
libcurlfor the entire thing - Save all relevant request data to log file in parsable form.
- Use
-
- Supervisor threads:
- Restart worker and scheduler threads that exit with an error.
Part of the larger 42 Network, 42 São Paulo is a software engineering school that offers a healthy alternative to traditional education:
- It doesn't have any teachers and classes.
- Students learn by cooperating and correcting each other's work (peer-to-peer learning).
- Its focus is as much on social skills as it is on technical skills.
- It's completely free to anyone that passes its selection process - The Piscine
It's an amazing school, and I'm grateful for the opportunity.
- https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
- https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
- https://stackoverflow.com/questions/5133968/using-libcurl-to-monitor-state-of-a-network
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST#example
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET#syntax
- https://stackoverflow.com/questions/69998964/http-headers-as-string-which-delimiter-to-use/70005319
- https://datatracker.ietf.org/doc/html/rfc7230#section-3
- https://medium.com/swlh/looking-under-the-hood-http-over-tcp-sockets-952a944c99da
- https://stackoverflow.com/questions/30470505/http-request-using-sockets-in-c
- https://www.youtube.com/watch?v=bdIiTxtMaKA&list=PL9IEJIKnBJjH_zM5LnovnoaKlXML5qh17&index=2
- https://stackoverflow.com/questions/30470505/http-request-using-sockets-in-c
- https://en.wikipedia.org/wiki/Ping_(networking_utility)
- https://www.geeksforgeeks.org/internet-control-message-protocol-icmp/
- https://www.opensourceforu.com/2015/03/a-guide-to-using-raw-sockets/
- https://www.geeksforgeeks.org/error-detection-in-computer-networks/
- https://www.geeksforgeeks.org/domain-name-system-dns-in-application-layer/
- https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol
- https://curl.se/mail/lib-2012-11/0103.html
- https://www.geeksforgeeks.org/ping-in-c/
- https://github.com/sryze/ping/blob/master/src/ping.c
- https://stackoverflow.com/questions/9688899/sending-icmp-packets-in-a-c-program
- https://www.mycplus.com/source-code/c-source-code/ping/
- https://github.com/a-khakimov/ping
- https://github.com/sryze/ping
- https://en.wikipedia.org/wiki/Domain_Name_System
- https://stackoverflow.com/questions/1128409/how-might-i-perform-dns-lookups-using-c-c-on-linux
- https://gist.github.com/deltheil/6183330
- https://programmersought.com/article/85444274234/
- https://www.binarytides.com/dns-query-code-in-c-with-linux-sockets/
- https://www.theinsanetechie.in/2016/02/dns-lookup-implementation-in-c.html
- https://gist.github.com/fffaraz/9d9170b57791c28ccda9255b48315168
- https://man7.org/linux/man-pages/man3/gethostbyname.3.html
- https://linux.die.net/man/3/res_query
- https://github.com/rofl0r/firedns
- https://mqtt.org/
- https://en.wikipedia.org/wiki/MQTT
- https://mongoose.ws/documentation/#mg_mqtt_ping
- http://www.steves-internet-guide.com/mqtt/
- https://stackoverflow.com/questions/57950145/is-it-possible-to-use-libcurl-to-manage-raw-tcp-connections
- https://curl.se/libcurl/c/sendrecv.html
[getaddrinfo](https://gist.github.com/jirihnidek/bf7a2363e480491da72301b228b35d5d#file-getaddrinfo_example-c)()
- https://en.wikipedia.org/wiki/Getaddrinfo
- https://man7.org/linux/man-pages/man3/getaddrinfo.3.html
- https://gist.github.com/jirihnidek/bf7a2363e480491da72301b228b35d5d
- http://alas.matf.bg.ac.rs/manuals/lspe/snode=77.html
- https://stackoverflow.com/questions/755308/whats-the-hints-mean-for-the-addrinfo-name-in-socket-programming
- https://stackoverflow.com/questions/318236/how-do-you-validate-that-a-string-is-a-valid-ipv4-address-in-c
- https://man7.org/linux/man-pages/man3/inet_pton.3.html
- https://linux.die.net/man/3/inet_addr
- https://programmersought.com/article/76814417359/
- https://stackoverflow.com/questions/23146286/how-to-initialize-sockaddr-in-using-addrinfo
- https://pubs.opengroup.org/onlinepubs/009695399/functions/inet_pton.html
- https://stackoverflow.com/questions/1705885/why-inet-ntoa-is-designed-to-be-a-non-reentrant-function
- https://man7.org/linux/man-pages/man2/connect.2.html
- https://man7.org/linux/man-pages/man7/tcp.7.html
- https://linux.die.net/man/7/socket
- https://man7.org/linux/man-pages/man7/socket.7.html
- https://man7.org/linux/man-pages/man7/capabilities.7.html
- https://stackoverflow.com/questions/30780082/sock-raw-option-in-socket-system-call
- https://linux.die.net/man/7/raw
- https://www.tenouk.com/Module43a.html
- https://austinmarton.wordpress.com/2011/09/14/sending-raw-ethernet-packets-from-a-specific-interface-in-c-on-linux/
- https://man7.org/linux/man-pages/man3/libcap.3.html
- https://man7.org/linux/man-pages/man3/cap_from_text.3.html
- https://stackoverflow.com/questions/8338379/ubuntu-and-libcap-capabilities-undefined-reference
- https://gist.github.com/sbz/1090868
- http://unixetc.co.uk/2016/05/30/linux-capabilities-and-ping/
- https://stackoverflow.com/questions/2876024/linux-is-there-a-read-or-recv-from-socket-with-timeout
- https://linux.die.net/man/3/setsockopt
- https://en.wikipedia.org/wiki/Pthreads
- https://www.geeksforgeeks.org/thread-functions-in-c-c/
- https://www.man7.org/linux/man-pages/man0/pthread.h.0p.html
- https://iq.opengenus.org/multithreading-and-pthread-in-c/
- https://www.geeksforgeeks.org/multithreading-c-2/
- https://www.tutorialspoint.com/multithreading-in-c
- https://github.com/samuelpio01/multithreading-in-c/blob/master/pthread_multithreading.c
- https://www.youtube.com/playlist?list=PLfqABt5AS4FmuQf70psXrsMLEDQXNkLq2
- https://www.youtube.com/watch?v=9axu8CUvOKY
- https://man7.org/linux/man-pages/man3/pthread_create.3.htmlhttps://man7.org/linux/man-pages/man3/pthread_create.3.html
- http://www.cse.cuhk.edu.hk/~ericlo/teaching/os/lab/9-PThread/Pass.html
- https://stackoverflow.com/questions/39117674/how-to-pass-arguments-when-using-pthread-create
- https://linux.die.net/man/3/pthread_mutex_init
- https://stackoverflow.com/questions/20487752/how-to-handle-error-conditions-of-pthread-mutex-destroy
- https://linux.die.net/man/3/pthread_cond_init
- https://manpages.org/pthread_cond_timedwait/3
- https://linux.die.net/man/3/pthread_cond_init
- https://stackoverflow.com/questions/11000331/how-does-pthread-cond-broadcast-works
- https://linux.die.net/man/3/pthread_cond_broadcast
- https://linux.die.net/man/3/pthread_mutex_destroy
- https://docs.oracle.com/cd/E19455-01/806-5257/6je9h032r/index.html
- https://www.thegeekstuff.com/2012/04/terminate-c-thread/
- https://stackoverflow.com/questions/12207684/how-do-i-terminate-a-thread-in-c11
- https://stackoverflow.com/questions/16320838/when-do-i-really-need-to-use-atomicbool-instead-of-bool
- https://man7.org/linux/man-pages/man3/pthread_cancel.3.html
- https://stackoverflow.com/questions/15641145/thread-cancel-and-blocking-function-as-cond-wait
- https://linux.die.net/man/3/pthread_cleanup_push
- https://man7.org/linux/man-pages/man3/pthread_setcanceltype.3.html
- https://stackoverflow.com/questions/20304366/how-to-fix-gcc-error-expected-while-before-void
-
while/sleep -
timer_create - Wild threads
- Thread Pool + Thread Schedulers + Thread Supervisor
- https://en.wikipedia.org/wiki/Thread_pool
- https://github.com/ericomeehan/libeom/blob/main/Systems/ThreadPool.c
- https://github.com/Pithikos/C-Thread-Pool
- https://nachtimwald.com/2019/04/12/thread-pool-in-c/
- https://stackoverflow.com/questions/15752659/thread-pooling-in-c11
- https://www.youtube.com/watch?v=_n2hE2gyPxU&list=PLfqABt5AS4FmuQf70psXrsMLEDQXNkLq2&index=29
- https://www.youtube.com/watch?v=w6dQQt10Dxo
- https://www.youtube.com/watch?v=Pg_4Jz8ZIH4
- https://www.youtube.com/watch?v=WmDOHh7k0Ag
- https://www.youtube.com/watch?v=FMNnusHqjpw
- https://www.geeksforgeeks.org/thread-functions-in-c-c/
- https://stackoverflow.com/questions/7411301/how-to-introduce-date-and-time-in-log-file
- https://linux.die.net/man/3/localtime_r
- https://en.cppreference.com/w/c/chrono/localtime
- https://linux.die.net/man/3/time
- https://stackoverflow.com/questions/17982366/localtime-and-asctime-are-unsafe-but-the-safe-functions-dont-have-the-same-par
- https://stackoverflow.com/questions/42861913/why-use-usleep-and-not-sleep
- https://man7.org/linux/man-pages/man3/clock.3.html
- https://stackoverflow.com/questions/12240059/what-is-the-difference-between-clock-t-time-t-and-struct-tm
- https://www.geeksforgeeks.org/how-to-measure-time-taken-by-a-program-in-c/
- https://stackoverflow.com/questions/7411301/how-to-introduce-date-and-time-in-log-file
- https://man7.org/linux/man-pages/man3/strftime.3.html
- https://stackoverflow.com/questions/467938/stdout-thread-safe-in-c-on-linux
- https://man7.org/linux/man-pages/man3/flockfile.3.html
- https://linux.die.net/man/3/fprintf
- https://linux.die.net/man/3/asprintf
- https://man7.org/linux/man-pages/man3/stdio.3.html
- https://en.cppreference.com/w/c/io/fopen
- https://man7.org/linux/man-pages/man3/fclose.3.html
- https://man7.org/linux/man-pages/man3/fopen.3.html
- https://en.wikipedia.org/wiki/C_file_input/output
- https://stackoverflow.com/questions/61911258/difference-between-file-pointer-stream-file-descriptor-and-file
- https://stackoverflow.com/questions/8714016/calling-a-function-at-exact-every-second-using-a-timer
- https://linux.die.net/man/2/timer_create
- https://github.com/asherikov/thread_supervisor
- https://stackoverflow.com/questions/27594027/supervising-c-multithread-process-using-monit
- https://curl.se/libcurl/
- https://github.com/curl/curl
- https://curl.se/libcurl/c/getinmemory.html
- https://www.youtube.com/watch?v=DVR8N9ob_ZY&list=PLpXAyWkDQy40u-xT-Zr6Rab6EdEFOjO2W&index=6
- https://www.youtube.com/watch?v=daA-KBKfJ_o
- https://hub.docker.com/r/curlimages/curl
- https://stackoverflow.com/questions/57950145/is-it-possible-to-use-libcurl-to-manage-raw-tcp-connections
- https://stackoverflow.com/questions/16476196/undefined-reference-to-curl-global-init-curl-easy-init-and-other-functionc
- https://curl.se/libcurl/c/CURLOPT_DNS_SERVERS.html
# LIBCURL WORKSPACE INSTALL
$ wget https://curl.se/download/curl-7.84.0.zip
$ unzip -d curl-7.84.0.zip
$ ./configure --with-openssl --prefix=$HOME/.local
$ make
$ make install
# Lib in ~/.local/lib
# Includes in ~/.local/include
$ curl-config --cflags
$ curl-config --libs-
HTTP -
HTTPS -
MQTT
- https://github.com/cesanta/mongoose
- https://mongoose.ws/documentation/#minimal-tcp-echo-server
- https://mongoose.ws/tutorials/http-client/
- https://mongoose.ws/tutorials/mqtt-client/
- https://mongoose.ws/documentation/#user-guide
- https://mongoose.ws/tutorials/http-server/#using-mg_printf
- https://mongoose.ws/tutorials/
-
HTTP -
HTTPS -
MQTT
- https://github.com/eclipse/paho.mqtt.c
-
MQTT -
HTTP -
HTTPS
- https://mosquitto.org/
- https://www.youtube.com/watch?v=ERPhUsmbhMo
-
MQTT -
HTTP -
HTTPS
- https://www.doxygen.nl/
- https://stackoverflow.com/questions/8889942/how-to-write-documentation-comments-in-ansi-c
- https://github.com/vcwild/feminist-api/blob/main/sources/cli.c#L3
- https://www.geeksforgeeks.org/check-if-an-url-is-valid-or-not-using-regular-expression/
- https://en.wikipedia.org/wiki/URL
- https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_is_a_URL
A linked list in the control structure with all the allocated memory pointers.
The interface function ft_lalloc allocates memory and adds the pointer to the list.
The interface function ft_free_lalloc frees all pointers and the list.
- https://codereview.stackexchange.com/questions/151019/implementing-realloc-in-c
- https://manpages.org/realloc
- https://stackoverflow.com/questions/10864593/implementation-of-realloc-in-c
git clone --recurse-submodule REMOTE_REPOgit submodule add REMOTE_REPO PATHgit submodule foreach git pullgit submodule update --init --recursive- https://stackoverflow.com/questions/33714063/how-to-update-submodules-in-git
- https://stackoverflow.com/questions/59271919/how-to-clone-public-submodule-in-github-actions
- https://stackoverflow.com/questions/50254184/git-submodule-and-fetch
- https://www.w3docs.com/snippets/git/how-to-add-a-submodule-in-git.html
- https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule#1260982
- https://stackoverflow.com/questions/2006172/git-how-to-reset-a-remote-git-repository-to-remove-all-commits
- https://stackoverflow.com/questions/1765689/what-is-the-best-practice-for-formatting-logs
- https://www.ibm.com/docs/en/i/7.1?topic=logging-log-formats
- https://www.sentinelone.com/blog/log-formatting-best-practices-readable/
- https://en.wikipedia.org/wiki/Syslog
$ bat /var/log/syslog- actions/runner-images#5470
- actions/runner-images#3640
- https://github.com/asozialesnetzwerk/an-website/blob/main/.github/workflows/check.yml
- https://www.lifewire.com/free-and-public-dns-servers-2626062
- https://developers.google.com/speed/public-dns/docs/using
- https://code.visualstudio.com/docs/editor/debugging
- https://code.visualstudio.com/docs/editor/tasks
- https://code.visualstudio.com/docs/cpp/c-cpp-properties-schema-reference
- https://github.com/json-c/json-c
- https://github.com/rbtylee/tutorial-jsonc/blob/master/tutorial/index.md
- https://progur.com/2018/12/how-to-parse-json-in-c.html
- https://github.com/json-c/json-c/wiki/List-of-json-c-tutorials
- https://learning.postman.com/docs/designing-and-developing-your-api/mocking-data/setting-up-mock/
- https://mock-server.com/mock_server/running_mock_server.html
- https://httptoolkit.tech/
- https://github.com/nhanhoangtran/3_multithreaded_webserver_using_condition_variables
- https://github.com/dolev146/JACOB-SORBER-multithreaded-server-all-parts/blob/master/part1/client.rb
- https://docs.microsoft.com/en-us/cpp/c-language/cpp-integer-limits?view=msvc-170
- https://stackoverflow.com/questions/3053561/how-do-i-assign-an-alias-to-a-function-name-in-c
- https://stackoverflow.com/questions/32698293/assign-values-to-structure-variables
- https://stackoverflow.com/questions/41304497/print-the-structure-fields-and-values-in-c
- https://stackoverflow.com/questions/4949254/const-char-const-versus-const-char
- https://stackoverflow.com/questions/668501/are-there-any-open-source-c-libraries-with-common-data-structures
- https://github.com/nothings/single_file_libs
- https://github.com/oz123/awesome-c#concurrency-and-parallelism
- https://stackoverflow.com/questions/1085083/regular-expressions-in-c-examples
- https://manpages.ubuntu.com/manpages/trusty/man7/regex.h.7posix.html
- https://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C
- https://github.com/siu/minunit (minimal)
- https://github.com/ThrowTheSwitch/Unity (average)
- https://stackoverflow.com/questions/242926/comparison-of-c-unit-test-frameworks
- https://github.com/google/googletest (very robust)
- https://docs.microsoft.com/en-us/visualstudio/test/writing-unit-tests-for-c-cpp?view=vs-2022 (very robust)
- https://www.asciiart.eu/art-and-design/escher
- https://www.asciiart.eu/art-and-design/borders
- https://www.asciiart.eu/art-and-design/geometries
- https://www.text-image.com/convert/ascii.html
- https://textfancy.com/multiline-text-art/