Code release

This commit is contained in:
2025-10-16 14:12:55 +03:00
parent 09414d96c9
commit fdb2c3ba4f
18 changed files with 1058 additions and 2 deletions
+47
View File
@@ -0,0 +1,47 @@
#include "client.h"
#include "file_p.h"
#include "main.h"
#include "session.h"
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
// TODO: синхронизовать c C++
void process_client_command(char *line, session *sess, server_data_t *s_d) {
char arg_1[32];
char arg_2[32];
int res;
sscanf(line, "%s %s", arg_1, arg_2);
if (!strcmp(arg_1, "file")) {
/* LIST */
if (!strcmp(arg_2, "list")) {
file_list(sess, s_d);
return;
}
/* UPLOAD */
if (!strcmp(arg_2, "upload")) {
res = file_receive_prepare(sess, line, s_d);
if (!res)
sess->state = OP_UPLOAD;
return;
}
/* DOWNLOAD */
if (!strcmp(arg_2, "download")) {
res = file_send_prepare(sess, line, s_d);
if (!res)
sess->state = OP_DOWNLOAD;
return;
}
}
if (!strncmp(line, "exit", sizeof "exit")) {
sess->state = ERR;
sess->reason = EXIT;
session_send_string(sess, "OK. Bye!\n");
}
}
+7
View File
@@ -0,0 +1,7 @@
#ifndef CLIENT_H
#define CLIENT_H
#include "main.h"
void process_client_command(char *line, session *sess, server_data_t *s_d);
#endif
+305
View File
@@ -0,0 +1,305 @@
#include "file_p.h"
#include "main.h"
#include "session.h"
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/statvfs.h>
#include <sys/syslog.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
char *extract_second_arg(char *);
size_t get_file_size(char *, char *);
void file_list(session *sess, server_data_t *s_d) {
// TODO: change of format (rewrite in C++)
char list_end[] = "list_end\n";
fl_t *current;
current = s_d->fl_start;
char item_h[256];
do {
int n_len = strlen(sess->uname);
if (strncmp(current->owner, sess->uname, n_len) && !current->permissions) {
continue;
}
int h_len = sprintf(item_h, "%s %zu %s", current->name, current->size,
current->owner);
int d_len = strlen(current->description);
int f_len = h_len + d_len + 2;
char *full_str = malloc(sizeof(char) * f_len);
sprintf(full_str, "%s %s", item_h, current->description);
int i;
for (i = h_len; i < h_len + d_len; i++) {
if (full_str[i] == '\n') {
full_str[i] = '\a';
}
}
write(sess->sd, full_str, f_len-1); // -1 : do not include \0
free(full_str);
} while ((current = current->next) != NULL);
write(sess->sd, list_end, sizeof(list_end));
}
int file_send_prepare(session *sess, char *line, server_data_t *s_d) {
// TODO: рефактор в C++
int sd = sess->sd;
char fname[32];
sscanf(line, "%*s %*s %s", fname);
char filepath[256];
sprintf(filepath, "%s/%s", STORAGE_FOLDER, fname);
size_t fsize;
char st_message[256];
int file_d = open(filepath, O_RDONLY);
if (file_d == -1) {
fprintf(stdout, "ERROR: %d\n", errno);
char err_mes[256];
int mlen;
mlen = sprintf(err_mes, "Can't open file named \"%s\"\n", fname);
write(sd, err_mes, mlen);
return -1;
}
fsize = lseek(file_d, 0, SEEK_END);
lseek(file_d, 0, SEEK_SET);
sess->fd = file_d;
sess->fsize = fsize;
sess->f_rest = fsize;
sess->fname = malloc(strlen(fname));
int fname_len = strlen(fname) - 1;
strncpy(sess->fname, fname, fname_len);
sess->fname[fname_len] = 0;
return 0;
}
int file_receive_prepare(session *sess, char *line, server_data_t *s_d) {
int sd = sess->sd;
char fname[64];
size_t fsize;
int perm;
sscanf(line, "file upload \"%s %zd %d", fname, &fsize, &perm);
sess->fname = malloc(sizeof(char) * strlen(fname));
sess->f_perm = (char)perm;
strncpy(sess->fname, fname, strlen(fname) - 1); // remove the last \"
sess->fpath = malloc(strlen(sess->fname) + sizeof(STORAGE_FOLDER) + 2);
sprintf(sess->fpath, "%s/%s", STORAGE_FOLDER, sess->fname);
char mes[256];
char mes_len = 0;
struct statvfs st_str;
statvfs(".", &st_str);
size_t available_space = st_str.f_bavail * st_str.f_bsize;
if (strlen(sess->fname) > st_str.f_namemax) {
mes_len = sprintf(mes, "file name is tool long\n");
write(sd, mes, mes_len);
sess->state = OP_WAIT;
clear_file_from_sess(sess);
return -1;
}
if (fsize > available_space) {
mes_len = sprintf(mes, "There is no space for such length! (%ld)\n", fsize);
write(sd, mes, mes_len);
clear_file_from_sess(sess);
return -1;
}
int file_d = open(sess->fpath, O_WRONLY | O_CREAT | O_EXCL, 0666);
if (file_d == -1) {
if (errno == EEXIST) {
mes_len =
sprintf(mes, "File with name \"%s\" is already exist\n", sess->fname);
write(sd, mes, mes_len);
}
mes_len =
sprintf(mes, "Can't create file with such name: \"%s\"\n", sess->fname);
write(sd, mes, mes_len);
clear_file_from_sess(sess);
return -1;
}
mes_len = sprintf(mes, "accept");
sess->fd = file_d;
sess->fsize = fsize;
sess->f_rest = fsize;
write(sd, mes, mes_len);
return 0;
}
void clear_file_from_sess(session *sess) {
if (sess->fname != NULL) {
free(sess->fname);
sess->fname = NULL;
}
if (sess->fpath != NULL) {
free(sess->fpath);
sess->fpath = NULL;
}
if (sess->fdesc != NULL) {
free(sess->fdesc);
sess->fdesc = NULL;
}
if (sess->fd > -1) {
close(sess->fd);
}
sess->fd = -1;
sess->fsize = 0;
sess->f_rest = 0;
}
void file_download_upload(session *sess, enum f_actions f_action) {
int source_d = f_action == F_DOWNLOAD ? sess->fd : sess->sd;
int dest_d = f_action == F_DOWNLOAD ? sess->sd : sess->fd;
char buf[INBUFSIZE];
int rlen = read(source_d, buf, INBUFSIZE);
if (rlen == 0) {
if (sess->f_rest) {
if (f_action == F_DOWNLOAD) {
fprintf(stderr, "Error downloading file %s!\n", sess->fname);
} else {
fprintf(stderr, "Error uploading file %s!\n", sess->fname);
unlink(sess->fpath); /* remove file */
}
clear_file_from_sess(sess);
}
sess->state = OP_WAIT;
return;
}
write(dest_d, buf, rlen);
sess->f_rest -= rlen;
if (!sess->f_rest) {
if (f_action == F_DOWNLOAD) {
printf("File %s is downloaded from the server\n", sess->fname);
clear_file_from_sess(sess);
} else {
printf("File %s is uploaded to the server\n", sess->fname);
}
if (f_action == F_UPLOAD) {
sess->state = OP_UPLOAD_DESCRIPTION;
} else {
sess->state = OP_WAIT;
}
}
}
size_t get_file_size(char *dir_n, char *file_n) {
char filepath[256];
int dn_len;
size_t fsize;
strcpy(filepath, dir_n);
dn_len = strlen(filepath);
strcat(filepath + dn_len, file_n);
int file_d = open(filepath, O_RDONLY);
if (file_d == -1)
return 0;
fsize = lseek(file_d, 0, SEEK_END);
lseek(file_d, 0, SEEK_SET);
close(file_d);
return fsize;
}
/* returns 1 if there is :END: ; 0 if opposite */
int file_upload_description(session *sess, char *line, server_data_t *s_d) {
for (;;) {
if (line != NULL && sess->fdesc == NULL) { /* first query */
sess->fdesc = malloc(strlen(line) + 1);
strcpy(sess->fdesc, line);
} else { /* subsequent queries */
if (line == NULL) {
if (sess->buf_used > 0) {
query_extract_from_buf(sess, &line);
} else {
return 0;
}
}
sess->fdesc =
realloc(sess->fdesc, strlen(sess->fdesc) + strlen(line) + 1);
strcat(sess->fdesc, line);
}
char *desc_end = strstr(line, ":END:");
if (desc_end != NULL) {
return 1;
}
}
}
// TODO: синхронизовать c C++
void get_files_descriptions(server_data_t *s_d) {
int fd = open(FILE_DESCRIPTIONS_NAME, O_RDONLY);
if (-1 == fd) {
perror(FILE_DESCRIPTIONS_NAME);
exit(8);
}
int rlen;
char buf[INBUFSIZE] = "";
chdir(STORAGE_FOLDER);
while ((rlen = read(fd, buf, FILEBUFSIZE)) > 0) {
char *buf_pos = buf;
char tmp[256];
while (buf_pos[0] != '\0') {
fl_t *fl_item = malloc(sizeof(fl_t));
fl_item->next = NULL;
/* file name */
sscanf(buf_pos, "%s\n", tmp);
buf_pos += strlen(tmp)+1;
fl_item->name = malloc(sizeof(char) * (strlen(tmp) + 1));
strcpy(fl_item->name,tmp);
/* file owner */
sscanf(buf_pos, "%s\n", tmp);
buf_pos += strlen(tmp)+1;
fl_item->owner = malloc(sizeof(char) * (strlen(tmp) + 1));
strcpy(fl_item->owner, tmp);
/* file permissions */
sscanf(buf_pos, "%s\n", tmp);
buf_pos += strlen(tmp)+1;
fl_item->permissions = atoi(tmp);
/* file size */
int fd = open(fl_item->name, O_RDONLY);
if (-1 == fd) {
perror(fl_item->name);
free(fl_item->name);
free(fl_item->owner);
free(fl_item);
buf_pos += strstr(buf_pos, ":END:") + 6 - buf_pos;
continue;
}
fl_item->size = lseek(fd, 0, SEEK_END);
close(fd);
/* file description */
int d_len = strstr(buf_pos, ":END:\n") - buf_pos;
fl_item->description = malloc(d_len + 1);
strncpy(fl_item->description, buf_pos, d_len);
fl_item->description[d_len] = 0;
buf_pos += d_len + 6;
if (s_d->fl_start == NULL) {
s_d->fl_start = fl_item;
s_d->fl_current = fl_item;
} else {
s_d->fl_current->next = fl_item;
s_d->fl_current = fl_item;
}
}
}
close(fd);
chdir("..");
}
+16
View File
@@ -0,0 +1,16 @@
#ifndef FILEP_H
#define FILEP_H
#include "main.h"
void get_files_descriptions(server_data_t *);
void file_list(session *, server_data_t *);
int file_send_prepare(session *, char *, server_data_t *);
enum f_actions {
F_UPLOAD,
F_DOWNLOAD,
};
void file_download_upload(session *sess, enum f_actions);
int file_receive_prepare(session *sess, char *line, server_data_t *s_d);
int file_upload_description(session *sess, char *line, server_data_t *s_d);
int file_save_db(session *sess, server_data_t *s_d);
void clear_file_from_sess(session *sess);
#endif
+16
View File
@@ -0,0 +1,16 @@
#include "main.h"
#include "file_p.h"
#include "server.h"
/* *** MAIN *** */
int main(int argc, char *argv[]) {
server_data_t server_data;
prepare_start(argc, argv);
server_data.welcome_message = get_welcome_mes();
server_data.fl_start = NULL;
server_data.fl_current = NULL;
get_files_descriptions(&server_data);
server_data.ls = start_server();
server_main_loop(&server_data);
return 0;
}
+77
View File
@@ -0,0 +1,77 @@
#ifndef MAIN_H
#define MAIN_H
#include <stddef.h>
#define PORT 2000
#define MAX_CONNECTIONS 1024
#define INBUFSIZE 1024
#define FILEBUFSIZE 4096
#define WSIZE 128
#define LISTEN_QLEN 32
#define STORAGE_FOLDER "./storage"
#define FILE_DESCRIPTIONS_NAME "./file_descriptions"
#define FILE_USER_LIST_NAME "userlist"
#define WELCOME_FILE_NAME "welcome"
enum sess_states {
OP_EDIT_FILE,
OP_DOWNLOAD,
OP_EDIT_USER,
OP_LOGIN_USR,
OP_LOGIN_PSS,
OP_WAIT,
OP_UPLOAD,
OP_UPLOAD_DESCRIPTION,
ERR,
FIN
};
enum user_privileges {
ADD_FILE = 01,
EDIT_FILES = 02,
REMOVE_FILES = 04,
EDIT_USER = 010
};
enum error_reason {
NO_REASON,
LOGIN,
EXIT,
};
typedef struct session {
unsigned long from_ip;
unsigned short from_port;
char buf[INBUFSIZE];
int buf_used;
enum sess_states state;
enum error_reason reason;
char privileges;
char *uname;
int sd; /* session descriptor */
int fd; /* file descriptor */
char *fname;
char *fpath;
char f_perm;
char *fdesc;
size_t fsize;
size_t f_rest;
long int userpos; /* hint to the position in user list */
} session;
typedef struct fl_t {
char *name;
char *description;
char *owner;
char permissions;
size_t size;
struct fl_t *next;
} fl_t;
typedef struct server_data_t {
fl_t *fl_start;
fl_t *fl_current;
char *welcome_message;
int ls;
} server_data_t;
#endif
+143
View File
@@ -0,0 +1,143 @@
#include "main.h"
#include "session.h"
#include "user.h"
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
void server_main_loop(server_data_t *s_d) {
fd_set readfds;
int i, sr;
session *connections[MAX_CONNECTIONS];
for (i = 0; i < MAX_CONNECTIONS; i++) {
connections[i] = NULL;
}
int maxfd, res;
for (;;) {
FD_ZERO(&readfds);
FD_SET(s_d->ls, &readfds);
maxfd = s_d->ls;
for (i = 0; i < MAX_CONNECTIONS; i++) {
if (connections[i] != NULL) {
FD_SET(i, &readfds);
if (i > maxfd)
maxfd = i;
/* active uploads/downloads */
int fd = connections[i]->fd;
if (fd > -1) {
FD_SET(fd, &readfds);
if (fd > maxfd)
maxfd = fd;
}
}
}
sr = select(maxfd + 1, &readfds, NULL, NULL, NULL);
if (sr == -1) {
perror("select");
exit(6);
}
if (FD_ISSET(s_d->ls, &readfds)) {
if (-1 == accept_client(s_d->ls, connections, s_d->welcome_message)) {
fprintf(stderr, "Can't accept connection, error: %d\n", errno);
}
}
for (i = 0; i < MAX_CONNECTIONS; i++) {
/* download/upload file */
if (connections[i] != NULL && (connections[i]->state == OP_UPLOAD ||
connections[i]->state == OP_DOWNLOAD)) {
if (connections[i] != NULL && connections[i]->fd > -1 &&
FD_ISSET(connections[i]->fd, &readfds)) {
perform_session_action(connections[i], NULL, s_d);
}
} else if (connections[i] != NULL && FD_ISSET(i, &readfds)) {
/* server/client requests */
session *sess = connections[i];
char *line;
res = session_do_read(sess, &line);
if (line != NULL && res) {
perform_session_action(sess, line, s_d);
free(line);
if (process_error(sess)) {
close_session(connections, i);
}
}
if (res == 0) {
close_session(connections, i);
}
}
}
}
}
char *get_welcome_mes() {
int fd = open(WELCOME_FILE_NAME, O_RDONLY);
if (fd == -1) {
perror(WELCOME_FILE_NAME);
exit(7);
}
int filesize = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
char *welcome_message =
mmap(NULL, filesize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (welcome_message == MAP_FAILED) {
perror(WELCOME_FILE_NAME);
close(fd);
exit(5);
}
close(fd);
return welcome_message;
}
int start_server() {
int res;
int ls = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in s_addr;
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
int opt = 1;
setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
res = bind(ls, (struct sockaddr *)&s_addr, sizeof(s_addr));
if (res == -1) {
perror("bind");
exit(3);
}
res = listen(ls, LISTEN_QLEN);
if (res == -1) {
perror("listen");
exit(4);
}
return ls;
}
void prepare_start(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <work_dir>\n", argv[0]);
exit(1);
}
if (-1 == chdir(argv[1])) {
perror(argv[1]);
exit(2);
}
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef SERVER_H
#define SERVER_H
#include "main.h"
int start_server();
char *get_welcome_mes();
void server_main_loop(server_data_t *);
void prepare_start(int argc, char *argv[]);
#endif
+237
View File
@@ -0,0 +1,237 @@
#include "session.h"
#include "client.h"
#include "file_p.h"
#include "main.h"
#include "user.h"
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
session *make_new_session(int fd, struct sockaddr_in *from, char *wm);
int accept_client(int ls, session *connections[], char *wm) {
int sd;
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
sd = accept(ls, (struct sockaddr *)&addr, &len);
if (sd == -1) {
perror("accept");
return -1;
}
session *sess = make_new_session(sd, &addr, wm);
fprintf(stdout, "New connection: %s:%u\n", inet_ntoa(addr.sin_addr),
ntohs(addr.sin_port));
connections[sd] = sess;
return 0;
}
session *make_new_session(int fd, struct sockaddr_in *from, char *wm) {
struct session *sess = malloc(sizeof(*sess));
sess->from_ip = ntohl(from->sin_addr.s_addr);
sess->from_port = ntohs(from->sin_port);
sess->buf_used = 0;
sess->state = OP_LOGIN_USR;
sess->reason = NO_REASON;
sess->uname = NULL;
sess->f_perm = 0;
sess->fdesc = NULL;
sess->sd = fd;
sess->fd = -1;
sess->fsize = 0;
sess->f_rest = 0;
sess->fname = NULL;
sess->fpath = NULL;
session_send_string(sess, wm);
session_send_string(sess, "login> ");
return sess;
}
void session_send_string(struct session *sess, const char *str) {
write(sess->sd, str, strlen(str));
}
int session_do_read(session *sess, char **read_str) {
int rc, bufp = sess->buf_used;
rc = read(sess->sd, sess->buf + bufp, INBUFSIZE - bufp);
sess->buf[bufp + rc] = 0;
if (rc <= 0) {
sess->state = ERR;
return 0;
}
sess->buf_used += rc;
char *line;
query_extract_from_buf(sess, &line);
if (line == NULL) {
*read_str = line;
return 0;
} else {
*read_str = line;
}
if (sess->buf_used >= INBUFSIZE) {
/* we can't read further, no room in the buffer, no whole line yet */
session_send_string(sess, "Line too long! Good bye...\n");
sess->state = ERR;
return 0;
}
if (sess->state == FIN)
return 0;
return 1;
}
// TODO: синхронизовать c C++
int query_extract_from_buf(session *sess, char **output_line) {
char *line;
int pos = -1;
if (sess->buf_used > 0) {
char *cptr = strchr(sess->buf, '\n');
if (cptr != NULL)
pos = cptr - sess->buf;
} else {
return 0;
}
if (pos == -1) {
int b_used = sess->buf_used;
sess->buf_used = 0;
line = malloc(b_used + 1);
strncpy(line, sess->buf, b_used);
line[b_used] = 0;
*output_line = line;
return b_used;
} else {
line = malloc(pos + 2);
strncpy(line, sess->buf, pos + 1);
line[++pos] = 0;
sess->buf_used -= (pos);
if (!pos)
pos++;
memmove(sess->buf, sess->buf + pos, sess->buf_used);
sess->buf[sess->buf_used] = 0;
if (line[pos-2] == '\r') {
line[pos-2] = line[pos-1];
pos--;
line[pos-1] = 0;
}
*output_line = line;
}
return pos + 1;
}
void perform_session_action(session *sess, char *line, server_data_t *s_d) {
int state = sess->state;
char tmp_buf[256];
int priv;
int tmp_buf_pos;
int res;
/* while (sess->buf_used) { */
switch (state) {
case OP_LOGIN_USR:
res = find_user(line);
if (res == -2) {
sess->state = ERR;
sess->reason = EXIT;
session_send_string(sess, "Bye!");
break;
}
sess->userpos = res;
sess->state = OP_LOGIN_PSS;
session_send_string(sess, "password> ");
break;
case OP_LOGIN_PSS:
if (sess->userpos == -1) {
sess->state = ERR;
sess->reason = LOGIN;
} else {
if (login(sess, line)) {
sess->state = OP_WAIT;
sprintf(tmp_buf, "Welcome, %s\n", sess->uname);
session_send_string(sess, tmp_buf);
} else {
sess->state = ERR;
sess->reason = LOGIN;
}
}
break;
case OP_WAIT:
process_client_command(line, sess, s_d);
break;
case OP_DOWNLOAD:
file_download_upload(sess, F_DOWNLOAD);
break;
case OP_UPLOAD:
file_download_upload(sess, F_UPLOAD);
break;
case OP_UPLOAD_DESCRIPTION:
res = file_upload_description(sess, line, s_d);
if (res) {
file_save_db(sess, s_d);
session_send_string(sess, "File is saved!\n");
sess->state = OP_WAIT;
}
break;
}
/* } */
}
int file_save_db(session *sess, server_data_t *s_d) {
/* crate and fill the new item */
fl_t *nitem = malloc(sizeof(fl_t));
nitem->description = sess->fdesc;
nitem->name = sess->fname;
nitem->size = sess->fsize;
nitem->owner = malloc(strlen(sess->uname));
strcpy(nitem->owner, sess->uname);
nitem->permissions = sess->f_perm;
nitem->next = NULL;
/* set to NULL and clear */
sess->fname = NULL;
free(sess->fpath);
sess->fpath = NULL;
sess->fdesc = NULL;
if (sess->fd > -1) {
close(sess->fd);
}
sess->fd = -1;
sess->fsize = 0;
sess->f_rest = 0;
/* add new item to list */
s_d->fl_current->next = nitem;
s_d->fl_current = nitem;
/* save to the db file */
int fd = open(FILE_DESCRIPTIONS_NAME, O_WRONLY);
lseek(fd, 0, SEEK_END);
char permissions[4];
snprintf(permissions, 3, "%d", nitem->permissions);
unsigned int res_len = strlen(nitem->name) + 1 + strlen(nitem->owner) + 1 +
strlen(permissions) + 1 + strlen(nitem->description) +
1;
char *res_str = malloc(res_len);
res_len = sprintf(res_str, "%s\n%s\n%s\n%s", nitem->name, nitem->owner,
permissions, nitem->description);
nitem->description[strlen(nitem->description) - 6] = 0;
write(fd, res_str, res_len);
close(fd);
return 0;
}
void close_session(session *connections[], int sd) {
if (connections[sd] != NULL) {
close(sd);
connections[sd]->sd = -1;
free(connections[sd]->uname);
free(connections[sd]);
connections[sd] = NULL;
}
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef SESSION_H
#define SESSION_H
#include "main.h"
int accept_client(int ls, session *connections[], char *wm);
void session_send_string(struct session *sess, const char *str);
int query_extract_from_buf(session *sess, char **output_line);
int session_do_read(session *sess, char **read_str);
void perform_session_action(session *sess, char *line, server_data_t *s_d);
void close_session(session *connections[], int sd);
/* session *make_new_session(int fd, struct sockaddr_in *from, char *wm); */
/* int query_extract_from_sess(session *sess, char **output_line); */
#endif
+89
View File
@@ -0,0 +1,89 @@
#include "main.h"
#include "session.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
long int find_user(char *uname) {
FILE *fptr = fopen(FILE_USER_LIST_NAME, "r");
if (fptr == NULL) {
perror(FILE_USER_LIST_NAME);
exit(9);
}
char *line = NULL;
size_t bsize = WSIZE;
char b_uname[32];
long int cur_pos = 0;
int lsize = 0;
if (!strncmp(uname, "exit", sizeof "exit")) {
return -2;
}
while (getline(&line, &bsize, fptr)) {
if (line[0] == '\b')
break;
sscanf(line, "%s", b_uname);
if (!strcmp(uname, b_uname)) {
line = NULL;
fclose(fptr);
return cur_pos;
} else {
cur_pos += lsize;
line = NULL;
}
}
fclose(fptr);
return -1;
}
/* returns 1 if success */
int login(session *sess, char *pass) {
FILE *fptr = fopen(FILE_USER_LIST_NAME, "r");
fseek(fptr, sess->userpos, SEEK_SET);
int res = 0;
char *line = NULL;
size_t lsize = WSIZE;
char *pass_tok, *name_tok, *priv_tok;
getline(&line, &lsize, fptr);
name_tok = strtok(line, " ");
pass_tok = strtok(NULL, " ");
if (!strcmp(pass_tok, pass)) {
int n_len = pass_tok - name_tok - 1; /* exclude space */
sess->uname = malloc(n_len + 1);
strncpy(sess->uname, name_tok, n_len);
sess->uname[n_len] = 0;
priv_tok = strtok(NULL, " ");
sess->privileges = (char)atoi(priv_tok);
res = 1;
}
fclose(fptr);
return res;
}
// TODO: синхронизовать c C++
/* returns 1 if session needs to be closed, 0 - in the opposite case */
int process_error(session *sess) {
if (sess->state == ERR) {
switch (sess->reason) {
case NO_REASON:
case EXIT:
return 1;
break;
case LOGIN:
session_send_string(sess, "Can't find the user with such credentials\n");
sess->state = OP_LOGIN_USR;
sess->reason = NO_REASON;
session_send_string(sess, "login_again> ");
break;
}
}
return 0;
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef USER_H
#define USER_H
#include "main.h"
int login(session *sess, char *pass);
int process_error(session *sess);
long int find_user(char *uname);
#endif