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 (
gcc
ideally). GNU Make
installed 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-dev
Or 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 install
Clone the repo and build with make
:
$ git clone --recurse-submodules https://github.com/42sp/ft_netmon.git ft_netmon
$ cd ft_netmon
$ make
It should create a netmon
executable that you can run with sudo ./netmon
.
-h
and--help
: Print the help message.-s
and--simplify
: Parse the.log
file and print it toSTDOUT
in simple form.-d
and--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)
all
clean
fclean
re
- 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
-
-h
and—help
display help message and exits cleanly. -
-s
and—simplify
reads the log file, prints it in simple form toSTDOUT
and exits cleanly. -
-d
and—debug
flags 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
HTTP
configs:- Should have 6 tab-separated fields
- Validate
HTTP_METHOD
. - Validate expected
HTTP_CODE
. - Validate timeout in seconds (
unsigned int
> 0).
- Validate
PING
configs:- Should have 4 tab-separated fields
- Validate timeout in seconds (
unsigned int
> 0).
- Validate
DNS
configs:- 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
HTTP
targets - Parse
PING
targets - Parse
DNS
targets
- 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 (
mutex
andcond
) - 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 (
mutex
andcond
) - Enqueue every
timeout
seconds.
- Enqueue target request safely (
- All threads exit cleanly and join main thread on
CONTROL+Q
with 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
libcurl
for 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.log
should contain all available request data. -
netmon.log
should be saved in parsable form, such that it can be displayed simply with the--simplify
flag. - Should work as an useful and professional network monitoring service.
- Clean and readable code.
- Add a beautiful
README.md
explaining 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.log
data, with diagrams and graphs on the CLI. - Handle
MQTT
andTCP
requests/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
libcurl
for 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_REPO
git submodule add REMOTE_REPO PATH
git submodule foreach git pull
git 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/