「🎉」 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