「🎉」 init: wtf
This commit is contained in:
19
.direnv/bin/nix-direnv-reload
Executable file
19
.direnv/bin/nix-direnv-reload
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
if [[ ! -d "/home/adjoly/workspace/42/miniserv" ]]; then
|
||||||
|
echo "Cannot find source directory; Did you move it?"
|
||||||
|
echo "(Looking for "/home/adjoly/workspace/42/miniserv")"
|
||||||
|
echo 'Cannot force reload with this script - use "direnv reload" manually and then try again'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# rebuild the cache forcefully
|
||||||
|
_nix_direnv_force_reload=1 direnv exec "/home/adjoly/workspace/42/miniserv" true
|
||||||
|
|
||||||
|
# Update the mtime for .envrc.
|
||||||
|
# This will cause direnv to reload again - but without re-building.
|
||||||
|
touch "/home/adjoly/workspace/42/miniserv/.envrc"
|
||||||
|
|
||||||
|
# Also update the timestamp of whatever profile_rc we have.
|
||||||
|
# This makes sure that we know we are up to date.
|
||||||
|
touch -r "/home/adjoly/workspace/42/miniserv/.envrc" "/home/adjoly/workspace/42/miniserv/.direnv"/*.rc
|
1
.direnv/flake-inputs/nzcf7lnys24q231gh97sks5ji5qpw9ca-source
Symbolic link
1
.direnv/flake-inputs/nzcf7lnys24q231gh97sks5ji5qpw9ca-source
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/nix/store/nzcf7lnys24q231gh97sks5ji5qpw9ca-source
|
1
.direnv/flake-inputs/x06djk7jw02qb6y8fxd0mjgaksw2kd9n-source
Symbolic link
1
.direnv/flake-inputs/x06djk7jw02qb6y8fxd0mjgaksw2kd9n-source
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/nix/store/x06djk7jw02qb6y8fxd0mjgaksw2kd9n-source
|
1
.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa
Symbolic link
1
.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
/nix/store/gr4bzvxzzp0hwz6fkr96k8k04986hw6f-nix-shell-env
|
2091
.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc
Normal file
2091
.direnv/flake-profile-a5d5b61aa8a61b7d9d765e1daf971a9a578f1cfa.rc
Normal file
File diff suppressed because it is too large
Load Diff
27
flake.lock
generated
Normal file
27
flake.lock
generated
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1758070117,
|
||||||
|
"narHash": "sha256-uLwwHFCZnT1c3N3biVe/0hCkag2GSrf9+M56+Okf+WY=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "e9b7f2ff62b35f711568b1f0866243c7c302028d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-25.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
44
flake.nix
Normal file
44
flake.nix
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
inputs@{ self, nixpkgs, ... }:
|
||||||
|
let
|
||||||
|
supportedSystems = [
|
||||||
|
"x86_64-linux"
|
||||||
|
"aarch64-linux"
|
||||||
|
"x86_64-darwin"
|
||||||
|
"aarch64-darwin"
|
||||||
|
];
|
||||||
|
forEachSupportedSystem =
|
||||||
|
f:
|
||||||
|
nixpkgs.lib.genAttrs supportedSystems (
|
||||||
|
system:
|
||||||
|
f {
|
||||||
|
pkgs = import nixpkgs { inherit system; };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
devShells = forEachSupportedSystem (
|
||||||
|
{ pkgs }:
|
||||||
|
{
|
||||||
|
default = pkgs.mkShell {
|
||||||
|
hardeningDisable = [ "all" ];
|
||||||
|
nativeBuildInputs = with pkgs; [
|
||||||
|
clang_12
|
||||||
|
];
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
];
|
||||||
|
packages = with pkgs; [
|
||||||
|
nixfmt-rfc-style
|
||||||
|
valgrind
|
||||||
|
gdb
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
0
mini_serv.c
Normal file
0
mini_serv.c
Normal file
96
subjects/mini_serv/main.c
Normal file
96
subjects/mini_serv/main.c
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
int extract_message(char **buf, char **msg)
|
||||||
|
{
|
||||||
|
char *newbuf;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*msg = 0;
|
||||||
|
if (*buf == 0)
|
||||||
|
return (0);
|
||||||
|
i = 0;
|
||||||
|
while ((*buf)[i])
|
||||||
|
{
|
||||||
|
if ((*buf)[i] == '\n')
|
||||||
|
{
|
||||||
|
newbuf = calloc(1, sizeof(*newbuf) * (strlen(*buf + i + 1) + 1));
|
||||||
|
if (newbuf == 0)
|
||||||
|
return (-1);
|
||||||
|
strcpy(newbuf, *buf + i + 1);
|
||||||
|
*msg = *buf;
|
||||||
|
(*msg)[i + 1] = 0;
|
||||||
|
*buf = newbuf;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *str_join(char *buf, char *add)
|
||||||
|
{
|
||||||
|
char *newbuf;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (buf == 0)
|
||||||
|
len = 0;
|
||||||
|
else
|
||||||
|
len = strlen(buf);
|
||||||
|
newbuf = malloc(sizeof(*newbuf) * (len + strlen(add) + 1));
|
||||||
|
if (newbuf == 0)
|
||||||
|
return (0);
|
||||||
|
newbuf[0] = 0;
|
||||||
|
if (buf != 0)
|
||||||
|
strcat(newbuf, buf);
|
||||||
|
free(buf);
|
||||||
|
strcat(newbuf, add);
|
||||||
|
return (newbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int sockfd, connfd, len;
|
||||||
|
struct sockaddr_in servaddr, cli;
|
||||||
|
|
||||||
|
// socket create and verification
|
||||||
|
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sockfd == -1) {
|
||||||
|
printf("socket creation failed...\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("Socket successfully created..\n");
|
||||||
|
bzero(&servaddr, sizeof(servaddr));
|
||||||
|
|
||||||
|
// assign IP, PORT
|
||||||
|
servaddr.sin_family = AF_INET;
|
||||||
|
servaddr.sin_addr.s_addr = htonl(2130706433); //127.0.0.1
|
||||||
|
servaddr.sin_port = htons(8081);
|
||||||
|
|
||||||
|
// Binding newly created socket to given IP and verification
|
||||||
|
if ((bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr))) != 0) {
|
||||||
|
printf("socket bind failed...\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("Socket successfully binded..\n");
|
||||||
|
if (listen(sockfd, 10) != 0) {
|
||||||
|
printf("cannot listen\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
len = sizeof(cli);
|
||||||
|
connfd = accept(sockfd, (struct sockaddr *)&cli, &len);
|
||||||
|
if (connfd < 0) {
|
||||||
|
printf("server acccept failed...\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("server acccept the client...\n");
|
||||||
|
}
|
21
subjects/mini_serv/server.py
Normal file
21
subjects/mini_serv/server.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import socket
|
||||||
|
|
||||||
|
host = 'localhost'
|
||||||
|
port = 9990
|
||||||
|
address = (host, port)
|
||||||
|
|
||||||
|
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
server_socket.bind((address))
|
||||||
|
server_socket.listen(5)
|
||||||
|
print ("Listening for client . . .")
|
||||||
|
conn, address = server_socket.accept()
|
||||||
|
print ("Connected to client at ", address)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
output = conn.recv(3001)
|
||||||
|
if output:
|
||||||
|
print ("Message received from client:")
|
||||||
|
print (output)
|
||||||
|
|
||||||
|
except:
|
||||||
|
sys.exit(0)
|
42
subjects/mini_serv/subject.en.txt
Normal file
42
subjects/mini_serv/subject.en.txt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
Assignment name : mini_serv
|
||||||
|
Expected files : mini_serv.c
|
||||||
|
Allowed functions: write, close, select, socket, accept, listen, send, recv, bind, strstr, malloc, realloc, free, calloc, bzero, atoi, sprintf, strlen, exit, strcpy, strcat, memset
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Write a program that will listen for client to connect on a certain port on 127.0.0.1 and will let clients to speak with each other
|
||||||
|
|
||||||
|
This program will take as first argument the port to bind to
|
||||||
|
If no argument is given, it should write in stderr "Wrong number of arguments" followed by a \n and exit with status 1
|
||||||
|
If a System Calls returns an error before the program start accepting connection, it should write in stderr "Fatal error" followed by a \n and exit with status 1
|
||||||
|
If you cant allocate memory it should write in stderr "Fatal error" followed by a \n and exit with status 1
|
||||||
|
|
||||||
|
Your program must be non-blocking but client can be lazy and if they don't read your message you must NOT disconnect them...
|
||||||
|
|
||||||
|
Your program must not contains #define preproc
|
||||||
|
Your program must only listen to 127.0.0.1
|
||||||
|
The fd that you will receive will already be set to make 'recv' or 'send' to block if select hasn't be called before calling them, but will not block otherwise.
|
||||||
|
|
||||||
|
When a client connect to the server:
|
||||||
|
- the client will be given an id. the first client will receive the id 0 and each new client will received the last client id + 1
|
||||||
|
- %d will be replace by this number
|
||||||
|
- a message is sent to all the client that was connected to the server: "server: client %d just arrived\n"
|
||||||
|
|
||||||
|
clients must be able to send messages to your program.
|
||||||
|
- message will only be printable characters, no need to check
|
||||||
|
- a single message can contains multiple \n
|
||||||
|
- when the server receive a message, it must resend it to all the other client with "client %d: " before every line!
|
||||||
|
|
||||||
|
When a client disconnect from the server:
|
||||||
|
- a message is sent to all the client that was connected to the server: "server: client %d just left\n"
|
||||||
|
|
||||||
|
Memory or fd leaks are forbidden
|
||||||
|
|
||||||
|
To help you, you will find the file main.c with the beginning of a server and maybe some useful functions. (Beware this file use forbidden functions or write things that must not be there in your final program)
|
||||||
|
|
||||||
|
Warning our tester is expecting that you send the messages as fast as you can. Don't do un-necessary buffer.
|
||||||
|
|
||||||
|
Evaluation can be a bit longer than usual...
|
||||||
|
|
||||||
|
Hint: you can use nc to test your program
|
||||||
|
Hint: you should use nc to test your program
|
||||||
|
Hint: To test you can use fcntl(fd, F_SETFL, O_NONBLOCK) but use select and NEVER check EAGAIN (man 2 send)
|
44
subjects/mini_serv/subject.hy.txt
Normal file
44
subjects/mini_serv/subject.hy.txt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
Առաջադրանքի անունը՝ mini_serv
|
||||||
|
Ակնկալվող ֆայլեր՝ mini_serv.c
|
||||||
|
Թույլատրված ֆունկցիաներ՝ write, close, select, socket, accept, listen, send, recv, bind, strstr, malloc, realloc, free, calloc, bzero, atoi, sprintf, strlen, exit, strcpy, strcat, memset
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Գրել ծրագիր, որը կսպասի մինչև հաճախորդը կմիանա 127.0.0.1 հասցեով միացման կետին(port) և թույլ կտա հաճախորդներին իրար հետ խոսել։
|
||||||
|
|
||||||
|
Այս ծրագիրը որպես առաջին արգումենտ վերցնում է միացման կետը։
|
||||||
|
Եթե ոչ մի արգումենտ տրված չէ, այն պետք է stderr-ում գրի «Wrong number of arguments»՝ հաջորդված \n-ով և դուրս է գա 1 վիճակով։
|
||||||
|
Եթե Համակարգային կանչերը սխալ է վերադարձնում մինչև ծրագիրը կսկսի կապեր ընդունել, այն պետք է stderr-ում գրի «Fatal error»՝ հաջորդված \n-ով և դուրս է գա 1 վիճակով։
|
||||||
|
Եթե հիշողությունը չեք կարողանում տեղակայել, այն պետք է գրի stderr-ում գրի «Fatal error»՝ հաջորդված \n և դուրս գա 1 վիճակով։
|
||||||
|
|
||||||
|
Ձեր ծրագիրը պետք է արգելափակող չլինի, բայց հաճախորդը կարող է ծույլ լինել ու եթե ձեր հաղորդագրությունը չկարդա, նրան պետք ՉԷ կապից անջատել։
|
||||||
|
|
||||||
|
|
||||||
|
Ձեր ծրագիրը չպիտի պարունակի #define preproc։
|
||||||
|
Ձեր ծրագիրը պետք է հետևի միայն 127.0.0.1-ին։
|
||||||
|
Ձեր ստացած fd-ին արդեն կարգավորված կլինի ստեղծել «recv» և «send»՝ արգելափակելու համար, եթե select-ը չի կանչվել նրանց կանչելուց առաջ, բայց այլ դեպքերում չի արգելափակի։
|
||||||
|
|
||||||
|
Երբ հաճախորդը միանում է սերվերին՝
|
||||||
|
- Հաճախորդին կտրվի id․ առաջին հաճախորդը կստանա id 0 և յուրաքանչյուր նոր հաճախորդ կստանա վերջին հաճախորդի id + 1
|
||||||
|
- %d-ն կփոխարինվի այս թվով
|
||||||
|
- Սերվերին միացած բոլոր հաճախորդներին կուղարկվի հաղորդագրություն՝ «server: client %d just arrived\n»
|
||||||
|
|
||||||
|
Հաճախորդները պետք է կարողանան հաղորդագրություններ ուղարկել ձեր ծրագրին։
|
||||||
|
- Հաղորդագրությունը միայն տպելի նիշերով է լինելու, ստուգելու կարիք չկա
|
||||||
|
- Յուրաքանչյուր հաղորդագրությունը պետք է ավարտվի \n-ով։
|
||||||
|
- Երբ սերվերը հաղորդագրություն ստանա, այն պետք է դա ուղարկի մյուս բոլոր հաճախորդներին՝ հաղորդագրությունից առաջ «client %d:»-ով։
|
||||||
|
|
||||||
|
Երբ հաճախորդը սերվերից անջատվում է,
|
||||||
|
- սերվերին կապված բոլոր հաճախորդներին նամակ է ուղարկվում՝ «server: client %d just left\n»։
|
||||||
|
|
||||||
|
Հիշողության կամ fd արտահոսքեր չեն թույլատրվում։
|
||||||
|
|
||||||
|
Ձեզ օգնելու համար, ֆայլի main.c-ն կգտնեք սերվերի սկզբնական տողերով ու որոշ օգտակար ֆունկցիաներով։ (Ուշադի՛ր եղեք այս ֆայլում չթույլատրված ֆունկցիաներ գործածելիս կամ այնպիսի բաներ գրելիս, որոնք ձեր վերջնական ծրագրում չպիտի լինեն)
|
||||||
|
To help you, you will find the file main.c with the beginning of a server and maybe some useful functions. (Beware this file use forbidden functions or write things that must not be there in your final program)
|
||||||
|
|
||||||
|
Զգուշացում։ Մեր փորձարկիչը ակնկալում է, որ հաղորդագրությունները ինչքան հնարավոր է արագ ուղարկեք։ Անիմաստ բուֆերներ պետք չէ անել։
|
||||||
|
|
||||||
|
Գնահատումը կարող է սովարականից մի քիչ երկար տևել
|
||||||
|
|
||||||
|
Հուշում՝ կարող եք nc-ն գործածել ձեր ծրագիրը փորձարկելու համար։
|
||||||
|
Հուշում՝ պետք է nc-ն գործածեք ձեր ծրագիրը փորձարկելու համար։
|
||||||
|
Հուշում՝ փորձարկելու համար կարող եք գործածել fcntl(fd, F_SETFL, O_NONBLOCK), բայց գործածե՛ք select և ԱՅԼԵՎՍ ԵՐԲԵՔ մի՛ ստուգեք (man 2 send)։
|
42
subjects/mini_serv/subject.ru.txt
Normal file
42
subjects/mini_serv/subject.ru.txt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
Имя назначения : mini_serv
|
||||||
|
Ожидаемые файлы : mini_serv.c
|
||||||
|
Разрешенные функции : write, close, select, socket, accept, listen, send, recv, bind, strstr, malloc, realloc, free, calloc, bzero, atoi, sprintf, strlen, exit, strcpy, strcat, memset
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Напишите программу, которая будет прослушивать подключение клиента к определенному порту на 127.0.0.1 и позволит клиентам разговаривать друг с другом
|
||||||
|
|
||||||
|
Эта программа будет принимать в качестве первого аргумента порт для привязки
|
||||||
|
Если аргумент не задан, он должен написать в stderr "Wrong number of arguments", за которым следует a \n и выйти со статусом 1
|
||||||
|
Если системный вызов возвращает ошибку до того, как программа начнет принимать соединение, она должна написать в stderr "Fatal error", а затем a \n и выйти со статусом 1
|
||||||
|
Если вы не можете выделить память, он должен написать в stderr "Fatal error", а затем a \n и выйти со статусом 1
|
||||||
|
|
||||||
|
Ваша программа должна быть неблокирующей, но клиент может быть ленивым, и если он не читает ваше сообщение, вы не должны отключать его...
|
||||||
|
|
||||||
|
Ваша программа не должна содержать #define preproc
|
||||||
|
Ваша программа должна слушать только 127.0.0.1
|
||||||
|
Fd, который вы получите, уже будет настроен на блокировку 'recv' или 'send', если select не был вызван до их вызова, но в противном случае не будет заблокирован.
|
||||||
|
|
||||||
|
Когда клиент подключается к серверу:
|
||||||
|
- клиенту будет выдано удостоверение личности. первый клиент получит идентификатор 0, а каждый новый клиент получит последний идентификатор клиента + 1
|
||||||
|
- %d будет заменено на это число
|
||||||
|
- всем клиентам, которые были подключены к серверу, отправляется сообщение: "server: client %d just arrived\n"
|
||||||
|
|
||||||
|
клиенты должны иметь возможность отправлять сообщения в вашу программу.
|
||||||
|
- сообщение будет состоять только из печатаемых символов, проверять его не нужно
|
||||||
|
- одно сообщение может содержать несколько \n
|
||||||
|
- когда сервер получает сообщение, он должен повторно отправить его всем другим клиентам с "client %d:" перед каждой строкой!
|
||||||
|
|
||||||
|
Когда клиент отключается от сервера:
|
||||||
|
- всем клиентам, которые были подключены к серверу, отправляется сообщение: "server: client %d just left\n"
|
||||||
|
|
||||||
|
Утечки памяти или fd запрещены
|
||||||
|
|
||||||
|
Чтобы помочь вам, вы найдете файл main.c с началом работы сервера и, возможно, некоторые полезные функции. (Остерегайтесь, чтобы этот файл использовал запрещенные функции или писал вещи, которых не должно быть в вашей окончательной программе)
|
||||||
|
|
||||||
|
Предупреждение наш тестер ожидает, что вы будете отправлять сообщения так быстро, как только сможете. Не делайте ненужного буфера.
|
||||||
|
|
||||||
|
Оценка может быть немного дольше, чем обычно...
|
||||||
|
|
||||||
|
Подсказка: вы можете использовать nc для тестирования вашей программы
|
||||||
|
Подсказка: вы должны использовать nc для тестирования вашей программы
|
||||||
|
Подсказка: Для тестирования вы можете использовать fcntl(fd, F_SETFL, O_NONBLOCK), но используйте select и НИКОГДА НЕ проверяйте EAGAIN (man 2 send)
|
Reference in New Issue
Block a user