Files
progettoso/lib/api/api.c

1724 lines
37 KiB
C
Raw Normal View History

2022-04-24 13:01:13 +02:00
#define _POSIX_C_SOURCE 200809L
2022-04-21 18:56:47 +02:00
#include <errno.h>
2022-04-22 21:59:40 +02:00
#include <fcntl.h>
2022-04-21 18:56:47 +02:00
#include <stdio.h>
#include <stdlib.h>
2022-04-22 21:59:40 +02:00
#include <string.h>
2022-04-21 18:56:47 +02:00
#include <sys/socket.h>
2022-04-22 21:59:40 +02:00
#include <sys/stat.h>
2022-04-21 18:56:47 +02:00
#include <sys/time.h>
2022-04-24 13:01:13 +02:00
#include <time.h>
2022-04-22 21:59:40 +02:00
#include <sys/un.h>
#include <unistd.h>
2022-04-24 01:36:43 +02:00
#include <math.h>
2022-04-21 18:56:47 +02:00
2022-04-16 21:21:04 +02:00
#include <api.h>
2022-04-22 21:59:40 +02:00
#include <conn.h>
2022-04-16 21:21:04 +02:00
2022-04-21 18:56:47 +02:00
#define SOCKNAMEMAX 256 // should be at least 108
2022-04-22 21:59:40 +02:00
#define MEOK "20" //OK
// #define ME "21" // not used
// #define ME "22" // not used
#define MEFP "25" // file purged
// #define ME "40" // not used
// #define ME "41" // not used
#define MESD "42" // shutting down
#define MENT "45" // requested file action not taken
#define MESY "50" // syntax error
// #define ME "51" // not used
// #define ME "52" // not used
#define MESE "55" // server error
2022-04-25 20:24:55 +02:00
#define debughere(str) \
fprintf(stdout, "\nIn function: %s\n", __func__); \
fprintf(stdout, "\t%s\n", str); \
fflush(stdout); \
2022-04-24 12:20:31 +02:00
2022-04-21 18:56:47 +02:00
// -----------------------------------------------------------------------------
2022-04-21 19:56:50 +02:00
/* structs */
typedef struct files_s {
char *filename;
2022-04-25 20:24:55 +02:00
int locked;
2022-04-21 19:56:50 +02:00
struct files_s *next;
} files_t;
typedef struct openfiles_s {
int numOfFiles;
2022-04-22 21:59:40 +02:00
files_t *f; // list of files
2022-04-24 01:36:43 +02:00
int validwDir; // 1 if wDir is allocated
2022-04-21 19:56:50 +02:00
char *wDir; // for files sent from the server after openFile
2022-04-24 01:36:43 +02:00
int validrDir; // 1 if rDir is allocated
2022-04-21 19:56:50 +02:00
char *rDir; // for files read from the server
2022-04-22 21:59:40 +02:00
char *createdAndLocked; // path of the last file that was created and locked
2022-04-21 20:08:22 +02:00
int print; // whether to print
FILE *out; // where to print
2022-04-21 19:56:50 +02:00
} openfiles_t;
2022-04-16 21:21:04 +02:00
2022-04-22 21:59:40 +02:00
typedef struct recivedFile_s {
int64_t pathlen;
char *path;
int64_t filelen;
char *file;
} recivedFile_t;
typedef struct response_s {
char ME[2]; // response
int meerrno; // errno if sent
2022-04-27 21:18:25 +02:00
int64_t numfiles; // number of files if sent
2022-04-22 21:59:40 +02:00
recivedFile_t *rf; // array of files
} response_t;
2022-04-21 19:56:50 +02:00
// -----------------------------------------------------------------------------
/* variabili globali */
2022-04-24 01:36:43 +02:00
static long fd_skt; // descriptor of the socket
2022-04-21 19:56:50 +02:00
static char socketName[SOCKNAMEMAX] = ""; // name of the socket
static openfiles_t *openedFiles = NULL;
2022-04-16 21:21:04 +02:00
// -----------------------------------------------------------------------------
/* funzioni ausiliarie */
2022-04-21 19:56:50 +02:00
// closes every file opened by the client
int closeEveryFile();
// closes and frees memory
2022-04-23 00:56:30 +02:00
int removeOpenFile(const char *pathname);
2022-04-22 21:59:40 +02:00
// adds element
2022-04-25 20:24:55 +02:00
int addOpenFile(const char *pathname, const int flags);
2022-04-22 21:59:40 +02:00
// checks if the file is open already
2022-04-25 20:24:55 +02:00
int isOpen(const char *pathname, const int flags);
2022-04-22 21:59:40 +02:00
// reads everything the server sent into the variable passed to the function
// expected is 1 if a file could be sent (if no server errors occurs)
int reciveData(response_t *res, int expected);
// saves the files in the specified directory
2022-04-23 00:56:30 +02:00
int storeFilesInDirectory(const char *dirname, int n, recivedFile_t *rf);
2022-04-22 21:59:40 +02:00
// frees memory inside response_t element
void freeResponse(response_t *res);
2022-04-24 01:36:43 +02:00
// creates the global variable
int createOpenedFiles(void);
2022-04-16 21:21:04 +02:00
// -----------------------------------------------------------------------------
2022-04-21 19:56:50 +02:00
int openConnection(const char* sockname, int msec, const struct timespec abstime) {
2022-04-21 18:56:47 +02:00
if(!sockname){
errno = EINVAL;
return -1;
}
2022-04-21 19:56:50 +02:00
if(!openedFiles) {
2022-04-24 01:36:43 +02:00
if(createOpenedFiles()<0) {
perror("createOpenedfiles");
2022-04-21 19:56:50 +02:00
return -1;
}
}
2022-04-21 18:56:47 +02:00
struct sockaddr_un sa;
struct timespec ts;
ts.tv_sec = msec/1000;
ts.tv_nsec = (msec % 1000) * 1000000;
struct timeval t1, t2; // for gettimeofday
long long start, end; // to calculate the time elapsed
long long elapsedTime;
// select socket
2022-04-21 19:56:50 +02:00
strncpy(sa.sun_path, sockname, sizeof(sa.sun_path)-1);
2022-04-21 18:56:47 +02:00
sa.sun_family = AF_UNIX;
if ((fd_skt = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
errno = EINVAL;
perror("socket");
return -1;
}
if(gettimeofday(&t1, NULL) != 0) {
perror("gettimeofday");
return -1;
}
start = (long long) (t1.tv_sec * 1000000000 + t1.tv_usec * 1000);
while (connect(fd_skt, (struct sockaddr*) &sa, sizeof(sa)) == -1) {
gettimeofday(&t2, NULL);
end = (long long) t2.tv_sec * 1000000000 + t2.tv_usec * 1000;
elapsedTime = (end - start);
// return if more time has elapsed than allowed
if (elapsedTime > (abstime.tv_sec * 1000000000) + abstime.tv_nsec) {
errno = ETIMEDOUT;
return -1;
}
nanosleep(&ts, &ts);
}
2022-04-21 19:56:50 +02:00
strncpy(socketName, sockname, sizeof(socketName)-1);
return 0;
2022-04-16 21:21:04 +02:00
}
2022-04-21 19:56:50 +02:00
int closeConnection(const char* sockname) {
2022-04-29 21:04:45 +02:00
if (!sockname) {
errno = EINVAL;
return -1;
}
// if closing a different socket -> error
if(strncmp(socketName, "", sizeof(socketName)) != 0
&& strncmp(socketName, sockname, sizeof(socketName)) != 0) {
2022-04-21 19:56:50 +02:00
errno = EINVAL;
return -1;
}
// close every file
if (closeEveryFile() == -1) {
perror("closeEveryFile");
return -1;
}
// close socket
if (close(fd_skt) == -1) {
// return errno from close
return -1;
}
memset(socketName, 0, SOCKNAMEMAX);
return 0;
2022-04-16 21:21:04 +02:00
}
2022-04-21 19:56:50 +02:00
int openFile(const char* pathname, int flags) {
2022-04-22 21:59:40 +02:00
if(!pathname){
errno = EINVAL;
return -1;
}
if(!openedFiles){
errno = EPROTO;
return -1;
}
if(openedFiles->createdAndLocked)
free(openedFiles->createdAndLocked);
openedFiles->createdAndLocked = NULL;
if(strcmp(socketName, "") == 0) {
errno = ENOTCONN;
return -1;
}
2022-04-27 21:18:25 +02:00
if(isOpen(pathname, flags) == 1) { // already open
return 0;
2022-04-22 21:59:40 +02:00
}
// invio al server la stringa "openFile|$(pathname)|$(flags)"
2022-04-29 21:04:45 +02:00
int leng_flags = snprintf(NULL, 0, "%d", flags);
long len = strlen("openFile")+1+strlen(pathname)+1+leng_flags+1;
2022-04-22 21:59:40 +02:00
char *cmd = malloc(len);
if(!cmd) {
perror("malloc");
return -1;
}
memset(cmd, 0, len);
snprintf(cmd, len, "openFile|%s|%d", pathname, flags);
2022-04-24 01:36:43 +02:00
len = strnlen(cmd, len);
2022-04-22 21:59:40 +02:00
// send cmd
2022-04-23 00:56:30 +02:00
if (writen(fd_skt, &len, sizeof(long)) == -1) {
// writen sets errno
free(cmd);
return -1;
}
if (writen(fd_skt, cmd, len) == -1) {
// writen sets errno
free(cmd);
return -1;
}
// recive response
response_t *res = calloc(1, sizeof(response_t));
if(!res){
perror("calloc");
free(cmd);
return -1;
}
if(reciveData(res, 0) < 0) { // 0 because if we get a MEOK we dont expect a file
// errno is set by reciveData
freeResponse(res);
free(res);
free(cmd);
return -1;
}
if(res->meerrno != 0) {
// errno from server
freeResponse(res);
errno = res->meerrno;
free(res);
free(cmd);
return -1;
}
if(strncmp(res->ME, MEFP, sizeof(res->ME)) == 0) {
// some files were purged
if(openedFiles->print){
2022-05-03 23:14:39 +02:00
fprintf(openedFiles->out, "\nIl server ha espulso i seguenti file:\n");
2022-04-23 00:56:30 +02:00
fflush(openedFiles->out);
for(int i=0;i<res->numfiles;++i) {
2022-05-03 23:14:39 +02:00
fprintf(openedFiles->out, "\t%d) %s\n", i+1, res->rf[i].path);
2022-04-23 00:56:30 +02:00
}
}
if(openedFiles->wDir) {
if(openedFiles->print) {
2022-05-03 23:14:39 +02:00
fprintf(openedFiles->out, "\tI file espulsi sono stati scritti nella cartella: %s\n", openedFiles->wDir);
2022-04-23 00:56:30 +02:00
fflush(openedFiles->out);
}
if(storeFilesInDirectory(openedFiles->wDir, res->numfiles, res->rf) == -1) {
perror("storeFilesindirectory");
freeResponse(res);
free(res);
free(cmd);
return -1;
}
} else {
if(openedFiles->print) {
2022-05-03 23:14:39 +02:00
fprintf(openedFiles->out, "\tI file espulsi non sono stati memorizzati su disco\n");
2022-04-23 00:56:30 +02:00
fflush(openedFiles->out);
}
}
}
2022-04-25 20:24:55 +02:00
if(addOpenFile(pathname, flags) == -1) {
2022-04-23 00:56:30 +02:00
perror("addOpenFile");
return -1;
}
if(flags == (O_CREATE | O_LOCK)) {
if(openedFiles->createdAndLocked)
free(openedFiles->createdAndLocked);
openedFiles->createdAndLocked = calloc(strlen(pathname)+1, sizeof(char));
if(!openedFiles->createdAndLocked) {
perror("calloc");
freeResponse(res);
free(res);
free(cmd);
return -1;
}
strcpy(openedFiles->createdAndLocked, pathname);
}
freeResponse(res);
free(res);
free(cmd);
return 0;
}
int readFile(const char* pathname, void** buf, size_t* size) {
if(!pathname) {
errno = EINVAL;
return -1;
}
if(!openedFiles){
errno = EPROTO;
return -1;
}
if(openedFiles->createdAndLocked)
free(openedFiles->createdAndLocked);
openedFiles->createdAndLocked = NULL;
if(strcmp(socketName, "") == 0) {
errno = ENOTCONN;
return -1;
}
2022-04-25 20:24:55 +02:00
if(isOpen(pathname, 0) != 1) { // if it's not open => error
2022-04-23 00:56:30 +02:00
errno = EPERM;
return -1;
}
// invio al server la stringa readFile|$(pathname)"
long len = strlen("readFile")+1+strlen(pathname)+1;
char *cmd = malloc(len);
if(!cmd) {
perror("malloc");
return -1;
}
memset(cmd, 0, len);
snprintf(cmd, len, "readFile|%s", pathname);
2022-04-24 01:36:43 +02:00
len = strnlen(cmd, len);
2022-04-23 00:56:30 +02:00
// send cmd
if (writen(fd_skt, &len, sizeof(long)) == -1) {
// writen sets errno
free(cmd);
return -1;
}
if (writen(fd_skt, cmd, len) == -1) {
// writen sets errno
free(cmd);
return -1;
}
// recive response
response_t *res = calloc(1, sizeof(response_t));
if(!res){
perror("calloc");
free(cmd);
return -1;
}
if(reciveData(res, 1) < 0) { // 1 because if we get a MEOK we expect a file
// errno is set by reciveData
freeResponse(res);
free(res);
free(cmd);
return -1;
}
if(res->meerrno != 0) { // errno from server
freeResponse(res);
errno = res->meerrno;
free(res);
free(cmd);
return -1;
}
// no errors from server
if(res->numfiles != 1) {
freeResponse(res);
free(res);
free(cmd);
errno = EMSGSIZE;
return -1;
}
*size = (size_t) res->rf[0].filelen;
*buf = malloc(*size);
if(!*buf) {
freeResponse(res);
free(res);
free(cmd);
perror("malloc");
return -1;
}
memcpy(*buf, res->rf[0].file, *size);
if(openedFiles->print) {
printf("Letto il file: %s\n", res->rf[0].path);
printf("Di dimensione: %ld B\n", *size);
fflush(openedFiles->out);
}
if(openedFiles->rDir) {
if(openedFiles->print) {
fprintf(openedFiles->out, "Il file letto e' stato scritto nella cartella: %s\n", openedFiles->rDir);
fflush(openedFiles->out);
}
if(storeFilesInDirectory(openedFiles->rDir, 1, res->rf) == -1) {
2022-04-29 15:47:27 +02:00
perror("storeFilesInDirectory");
2022-04-23 00:56:30 +02:00
freeResponse(res);
free(res);
free(cmd);
return -1;
}
} else {
if(openedFiles->print) {
fprintf(openedFiles->out, "Il file letto non è stato memorizzato su disco\n");
fflush(openedFiles->out);
}
}
freeResponse(res);
free(res);
free(cmd);
return 0;
}
int readNFiles(int N, const char* dirname) {
if(!dirname) {
errno = EINVAL;
return -1;
}
if(!openedFiles){
errno = EPROTO;
return -1;
}
if(openedFiles->createdAndLocked)
free(openedFiles->createdAndLocked);
openedFiles->createdAndLocked = NULL;
if(strcmp(socketName, "") == 0) {
errno = ENOTCONN;
return -1;
}
2022-04-29 21:04:45 +02:00
// invio al server la stringa "readNFiles|$(N)"
int lenght_n = snprintf(NULL, 0, "%d", N);
long len = strlen("readNFiles")+1+lenght_n+1;
2022-04-23 00:56:30 +02:00
char *cmd = malloc(len);
if(!cmd) {
perror("malloc");
return -1;
}
memset(cmd, 0, len);
2022-04-29 21:04:45 +02:00
snprintf(cmd, len, "readNFiles|%d", N);
2022-04-24 01:36:43 +02:00
len = strnlen(cmd, len);
2022-04-23 00:56:30 +02:00
// send cmd
if (writen(fd_skt, &len, sizeof(long)) == -1) {
// writen sets errno
free(cmd);
return -1;
}
if (writen(fd_skt, cmd, len) == -1) {
// writen sets errno
free(cmd);
return -1;
}
// recive response
response_t *res = calloc(1, sizeof(response_t));
if(!res){
perror("calloc");
free(cmd);
return -1;
}
if(reciveData(res, 1) < 0) { // 1 because if we get a MEOK we expect N files
// errno is set by reciveData
freeResponse(res);
free(res);
free(cmd);
return -1;
}
if(res->meerrno != 0) { // errno from server
freeResponse(res);
errno = res->meerrno;
free(res);
free(cmd);
return -1;
}
2022-04-29 21:04:45 +02:00
if(openedFiles->print){
for(int i=0;i<res->numfiles;++i) {
fprintf(openedFiles->out, "%d) %s\n", i, res->rf[i].path);
}
fflush(openedFiles->out);
}
2022-04-23 00:56:30 +02:00
// save files to directory
if(storeFilesInDirectory(dirname, res->numfiles, res->rf) == -1) {
perror("storeFilesindirectory");
freeResponse(res);
free(res);
free(cmd);
return -1;
}
int n = res->numfiles;
freeResponse(res);
free(res);
free(cmd);
return n;
}
int writeFile(const char* pathname, const char* dirname) {
if(!pathname) {
errno = EINVAL;
return -1;
}
if(!openedFiles){
errno = EPROTO;
return -1;
}
if (strcmp(openedFiles->createdAndLocked, pathname) != 0) {
errno = EPERM;
return -1;
}
if(openedFiles->createdAndLocked)
free(openedFiles->createdAndLocked);
openedFiles->createdAndLocked = NULL;
if(strcmp(socketName, "") == 0) {
errno = ENOTCONN;
return -1;
}
// leggo il file da scrivere sul server
int fdi = -1;
size_t lung = 0;
size_t incr = 0;
size_t size = 0;
2022-04-29 22:31:08 +02:00
2022-04-23 00:56:30 +02:00
if ((fdi = open(pathname, O_RDONLY)) == -1) {
perror("open");
return -1;
}
// get file length
struct stat sb;
if (fstat(fdi, &sb) == -1) {
perror("stat");
return -1;
}
lung = sb.st_size;
void *content = malloc(lung);
if(!content) {
perror("malloc");
return -1;
}
// read file
while ((incr = read(fdi, content, lung)) > 0) {
size += incr;
lung -= incr;
}
if (incr == -1) {
free(content);
return -1;
}
if (openedFiles->print) {
2022-04-24 01:36:43 +02:00
fprintf(openedFiles->out, "Dimensione: %ldB ", size);
2022-04-23 00:56:30 +02:00
fflush(openedFiles->out);
}
if (close(fdi) == -1) {
2022-04-25 20:24:55 +02:00
perror("closing file");
2022-04-23 00:56:30 +02:00
free(content);
return -1;
}
// invio al server la stringa "writeFile|$(pathname)|$(size)"
2022-04-29 21:04:45 +02:00
int leng_size = snprintf(NULL, 0, "%zu", size);
long len = strlen("writeFile")+1+strlen(pathname)+1+leng_size+1;
2022-04-27 21:18:25 +02:00
char *cmd = calloc(len, sizeof(char));
2022-04-23 00:56:30 +02:00
if(!cmd) {
2022-04-27 21:18:25 +02:00
perror("calloc");
2022-04-23 00:56:30 +02:00
free(content);
return -1;
}
snprintf(cmd, len, "writeFile|%s|%zu", pathname, size);
2022-04-24 01:36:43 +02:00
len = strnlen(cmd, len);
2022-04-23 00:56:30 +02:00
// send cmd
if (writen(fd_skt, &len, sizeof(long)) == -1) {
// writen sets errno
free(content);
free(cmd);
return -1;
}
if (writen(fd_skt, cmd, len) == -1) {
// writen sets errno
free(content);
free(cmd);
return -1;
}
// recive response
response_t *res = calloc(1, sizeof(response_t));
if(!res){
perror("calloc");
free(content);
2022-04-24 01:36:43 +02:00
free(cmd);
2022-04-23 00:56:30 +02:00
return -1;
}
2022-04-24 01:36:43 +02:00
2022-04-23 00:56:30 +02:00
if(reciveData(res, 0) < 0) { // 0 because if we get a MEOK we don't expect files
// errno is set by reciveData
freeResponse(res);
free(res);
free(cmd);
free(content);
return -1;
}
if(res->meerrno != 0) { // errno from server
freeResponse(res);
errno = res->meerrno;
free(res);
free(cmd);
free(content);
return -1;
}
if(strncmp(res->ME, MEFP, sizeof(res->ME)) == 0) {
// some files were purged
if(openedFiles->print){
fprintf(openedFiles->out, "Il server ha espulso i seguenti file:\n");
fflush(openedFiles->out);
for(int i=0;i<res->numfiles;++i) {
fprintf(openedFiles->out, "%d) %s\n", i, res->rf[i].path);
}
}
if(dirname) {
if(storeFilesInDirectory(dirname, res->numfiles, res->rf) == -1) {
perror("storeFilesindirectory");
freeResponse(res);
free(res);
free(content);
free(cmd);
return -1;
}
if(openedFiles->print) {
fprintf(openedFiles->out, "I file espulsi sono stati scritti nella cartella: %s\n", dirname);
fflush(openedFiles->out);
}
} else {
if(openedFiles->print) {
fprintf(openedFiles->out, "I file espulsi non sono stati memorizzati su disco\n");
fflush(openedFiles->out);
}
}
}
// send file to server
if (writen(fd_skt, content, size) == -1) {
// errno set by writen
freeResponse(res);
free(res);
free(cmd);
free(content);
return -1;
}
2022-04-24 01:36:43 +02:00
// recive response
if(reciveData(res, 0) < 0) { // 0 because if we get a MEOK we don't expect files
// errno is set by reciveData
freeResponse(res);
free(res);
free(cmd);
free(content);
return -1;
}
if(res->meerrno != 0) { // errno from server
freeResponse(res);
errno = res->meerrno;
free(res);
free(cmd);
free(content);
return -1;
}
2022-04-23 00:56:30 +02:00
freeResponse(res);
free(res);
free(cmd);
free(content);
return 0;
}
int appendToFile(const char* pathname, void* buf, size_t size, const char* dirname) {
if(!pathname || !buf) {
errno = EINVAL;
return -1;
}
if(!openedFiles){
errno = EPROTO;
return -1;
}
if(openedFiles->createdAndLocked)
free(openedFiles->createdAndLocked);
openedFiles->createdAndLocked = NULL;
if(strcmp(socketName, "") == 0) {
errno = ENOTCONN;
return -1;
}
2022-04-25 20:24:55 +02:00
if (isOpen(pathname, 0) != 1) {
2022-04-23 00:56:30 +02:00
errno = EPERM;
return -1;
}
if (openedFiles->print) {
fprintf(openedFiles->out, "Dimensione: %ld B\n", size);
fflush(openedFiles->out);
}
// invio al server la stringa "appendToFile|$(pathname)|$(size)"
long len = strlen("appendToFile")+1+strlen(pathname)+1+sizeof(size)+1;
char *cmd = malloc(len);
if(!cmd) {
perror("malloc");
return -1;
}
memset(cmd, 0, len);
snprintf(cmd, len, "appendToFile|%s|%zu", pathname, size);
// send cmd
if (writen(fd_skt, &len, sizeof(long)) == -1) {
// writen sets errno
free(cmd);
return -1;
}
if (writen(fd_skt, cmd, len) == -1) {
// writen sets errno
free(cmd);
return -1;
}
// recive response
response_t *res = calloc(1, sizeof(response_t));
if(!res){
perror("calloc");
free(cmd);
return -1;
}
if(reciveData(res, 0) < 0) { // 0 because if we get a MEOK we don't expect files
// errno is set by reciveData
freeResponse(res);
free(res);
free(cmd);
return -1;
}
if(res->meerrno != 0) { // errno from server
freeResponse(res);
errno = res->meerrno;
free(res);
free(cmd);
return -1;
}
if(strncmp(res->ME, MEFP, sizeof(res->ME)) == 0) {
// some files were purged
if(openedFiles->print){
fprintf(openedFiles->out, "Il server ha espulso i seguenti file:\n");
fflush(openedFiles->out);
for(int i=0;i<res->numfiles;++i) {
fprintf(openedFiles->out, "%d) %s\n", i, res->rf[i].path);
}
}
if(dirname) {
if(storeFilesInDirectory(dirname, res->numfiles, res->rf) == -1) {
perror("storeFilesindirectory");
freeResponse(res);
free(res);
free(cmd);
return -1;
}
if(openedFiles->print) {
fprintf(openedFiles->out, "I file espulsi sono stati scritti nella cartella: %s\n", dirname);
fflush(openedFiles->out);
}
} else {
if(openedFiles->print) {
fprintf(openedFiles->out, "I file espulsi non sono stati memorizzati su disco\n");
fflush(openedFiles->out);
}
}
}
// send file to server
if (writen(fd_skt, buf, size) == -1) {
// errno set by writen
freeResponse(res);
free(res);
free(cmd);
return -1;
}
freeResponse(res);
free(res);
free(cmd);
return 0;
}
int lockFile(const char* pathname) {
if(!pathname){
errno = EINVAL;
return -1;
}
if(!openedFiles){
errno = EPROTO;
return -1;
}
if(openedFiles->createdAndLocked)
free(openedFiles->createdAndLocked);
openedFiles->createdAndLocked = NULL;
if(strcmp(socketName, "") == 0) {
errno = ENOTCONN;
return -1;
}
int existing = 0;
2022-04-25 20:24:55 +02:00
if(isOpen(pathname, 0)){ // file is already open
2022-04-23 00:56:30 +02:00
existing = 1;
goto _unlockFile;
}
2022-04-25 20:24:55 +02:00
if(isOpen(pathname, O_LOCK)){ // file is already locked
return 0;
}
2022-04-23 00:56:30 +02:00
if (openFile(pathname, O_LOCK) == 0) // open the file with the lock
return 0;
if (errno == ENOENT) // file created but not locked
goto _unlockFile;
return -1; // errno != ENOENT
_unlockFile: {
// invio al server la stringa "lockFile|$(pathname)"
long len = strlen("lockFile")+1+strlen(pathname)+1;
char *cmd = malloc(len);
if(!cmd) {
perror("malloc");
return -1;
}
memset(cmd, 0, len);
snprintf(cmd, len, "lockFile|%s", pathname);
// send cmd
if (writen(fd_skt, &len, sizeof(long)) == -1) {
// writen sets errno
free(cmd);
return -1;
}
if (writen(fd_skt, cmd, len) == -1) {
// writen sets errno
free(cmd);
return -1;
}
// recive response
response_t *res = calloc(1, sizeof(response_t));
if(!res){
perror("calloc");
free(cmd);
return -1;
}
// 0 because if we get a MEOK we dont expect a file
if(reciveData(res, 0) < 0) {
// errno is set by reciveData
freeResponse(res);
free(res);
free(cmd);
return -1;
}
if(res->meerrno != 0) {
// errno from server
freeResponse(res);
errno = res->meerrno;
free(res);
free(cmd);
return -1;
}
if(!existing) {
2022-04-25 20:24:55 +02:00
if(addOpenFile(pathname, O_LOCK) == -1) {
2022-04-23 00:56:30 +02:00
perror("addOpenFile");
freeResponse(res);
free(res);
free(cmd);
return -1;
}
}
freeResponse(res);
free(res);
free(cmd);
return 0;
}
}
int unlockFile(const char* pathname) {
if(!pathname){
errno = EINVAL;
return -1;
}
if(!openedFiles){
errno = EPROTO;
return -1;
}
if(openedFiles->createdAndLocked)
free(openedFiles->createdAndLocked);
openedFiles->createdAndLocked = NULL;
if(strcmp(socketName, "") == 0) {
errno = ENOTCONN;
return -1;
}
2022-04-25 20:24:55 +02:00
if(isOpen(pathname, 0) != 1) { // not open or not locked
2022-04-23 00:56:30 +02:00
errno = EPERM;
return -1;
}
// invio al server la stringa "unlockFile|$(pathname)"
long len = strlen("unlockFile")+1+strlen(pathname)+1;
char *cmd = malloc(len);
if(!cmd) {
perror("malloc");
return -1;
}
memset(cmd, 0, len);
snprintf(cmd, len, "unlockFile|%s", pathname);
// send cmd
if (writen(fd_skt, &len, sizeof(long)) == -1) {
// writen sets errno
free(cmd);
return -1;
}
2022-04-22 21:59:40 +02:00
if (writen(fd_skt, cmd, len) == -1) {
// writen sets errno
free(cmd);
return -1;
}
// recive response
response_t *res = calloc(1, sizeof(response_t));
if(!res){
perror("calloc");
free(cmd);
return -1;
}
if(reciveData(res, 0) < 0) { // 0 because if we get a MEOK we dont expect a file
// errno is set by reciveData
freeResponse(res);
free(res);
free(cmd);
return -1;
}
if(res->meerrno != 0) {
// errno from server
freeResponse(res);
errno = res->meerrno;
free(res);
free(cmd);
return -1;
}
freeResponse(res);
free(res);
free(cmd);
return 0;
2022-04-16 21:21:04 +02:00
}
2022-04-23 00:56:30 +02:00
int closeFile(const char *pathname) {
if(!pathname){
2022-04-22 21:59:40 +02:00
errno = EINVAL;
return -1;
}
if(!openedFiles){
errno = EPROTO;
return -1;
}
if(openedFiles->createdAndLocked)
free(openedFiles->createdAndLocked);
openedFiles->createdAndLocked = NULL;
if(strcmp(socketName, "") == 0) {
errno = ENOTCONN;
return -1;
}
2022-04-25 20:24:55 +02:00
if(isOpen(pathname, 0) != 1) { // not open
2022-04-22 21:59:40 +02:00
errno = EPERM;
return -1;
}
2022-04-23 00:56:30 +02:00
// invio al server la stringa "closeFile|$(pathname)"
long len = strlen("closeFile")+1+strlen(pathname)+1;
2022-04-22 21:59:40 +02:00
char *cmd = malloc(len);
if(!cmd) {
perror("malloc");
return -1;
}
memset(cmd, 0, len);
2022-04-23 00:56:30 +02:00
snprintf(cmd, len, "closeFile|%s", pathname);
2022-04-22 21:59:40 +02:00
// send cmd
2022-04-23 00:56:30 +02:00
if (writen(fd_skt, &len, sizeof(long)) == -1) {
// writen sets errno
free(cmd);
return -1;
}
2022-04-22 21:59:40 +02:00
if (writen(fd_skt, cmd, len) == -1) {
// writen sets errno
free(cmd);
return -1;
}
// recive response
response_t *res = calloc(1, sizeof(response_t));
if(!res){
perror("calloc");
free(cmd);
return -1;
}
2022-04-23 00:56:30 +02:00
if(reciveData(res, 0) < 0) { // 0 because if we get a MEOK we dont expect a file
2022-04-22 21:59:40 +02:00
// errno is set by reciveData
freeResponse(res);
free(res);
free(cmd);
return -1;
}
if(res->meerrno != 0) {
// errno from server
freeResponse(res);
errno = res->meerrno;
free(res);
free(cmd);
return -1;
}
2022-04-23 00:56:30 +02:00
if (removeOpenFile(pathname) == -1) {
perror("removeOpenFile");
2022-04-22 21:59:40 +02:00
} else {
2022-04-23 00:56:30 +02:00
openedFiles->numOfFiles--;
2022-04-22 21:59:40 +02:00
}
freeResponse(res);
free(res);
free(cmd);
return 0;
2022-04-16 21:21:04 +02:00
}
2022-04-23 00:56:30 +02:00
int removeFile(const char* pathname) {
if(!pathname){
errno = EINVAL;
return -1;
}
if(!openedFiles){
errno = EPROTO;
return -1;
}
if(openedFiles->createdAndLocked)
free(openedFiles->createdAndLocked);
openedFiles->createdAndLocked = NULL;
2022-04-16 21:21:04 +02:00
2022-04-23 00:56:30 +02:00
if(strcmp(socketName, "") == 0) {
errno = ENOTCONN;
return -1;
}
2022-04-16 21:21:04 +02:00
2022-04-25 20:24:55 +02:00
if (isOpen(pathname, 0) != 1) { // not open
2022-04-23 00:56:30 +02:00
errno = EPERM;
return -1;
}
2022-04-16 21:21:04 +02:00
2022-04-23 00:56:30 +02:00
// invio al server la stringa "removeFile|$(pathname)"
long len = strlen("removeFile")+1+strlen(pathname)+1;
char *cmd = malloc(len);
if(!cmd) {
perror("malloc");
return -1;
}
memset(cmd, 0, len);
snprintf(cmd, len, "removeFile|%s", pathname);
2022-04-16 21:21:04 +02:00
2022-04-23 00:56:30 +02:00
// send cmd
if (writen(fd_skt, &len, sizeof(long)) == -1) {
// writen sets errno
free(cmd);
return -1;
}
if (writen(fd_skt, cmd, len) == -1) {
// writen sets errno
free(cmd);
return -1;
}
2022-04-16 21:21:04 +02:00
2022-04-23 00:56:30 +02:00
// recive response
response_t *res = calloc(1, sizeof(response_t));
if(!res){
perror("calloc");
free(cmd);
return -1;
}
if(reciveData(res, 0) < 0) { // 0 because if we get a MEOK we dont expect a file
// errno is set by reciveData
freeResponse(res);
free(res);
free(cmd);
return -1;
}
if(res->meerrno != 0) {
// errno from server
freeResponse(res);
errno = res->meerrno;
free(res);
free(cmd);
return -1;
}
2022-04-16 21:21:04 +02:00
2022-04-23 00:56:30 +02:00
if (removeOpenFile(pathname) == -1) {
perror("removeOpenFile");
} else {
openedFiles->numOfFiles--;
}
2022-04-30 00:37:59 +02:00
freeResponse(res);
free(res);
2022-04-23 00:56:30 +02:00
free(cmd);
2022-04-24 01:36:43 +02:00
return 0;
2022-04-16 21:21:04 +02:00
}
2022-04-21 19:56:50 +02:00
// -----------------------------------------------------------------------------
int setDirectory(char* Dir, int rw) {
2022-04-23 00:56:30 +02:00
if (!Dir) {
errno = EINVAL;
return -1;
}
if (rw == 1) {
2022-04-24 01:36:43 +02:00
if(openedFiles->validwDir) {
2022-04-23 00:56:30 +02:00
free(openedFiles->wDir);
2022-04-24 01:36:43 +02:00
openedFiles->wDir = NULL;
2022-05-03 23:30:47 +02:00
openedFiles->validwDir = 0;
}
if(strncmp(Dir, "/dev/null", strlen("/dev/null")+1) == 0) {
return 0;
2022-04-24 01:36:43 +02:00
}
openedFiles->validwDir = 1;
2022-04-23 00:56:30 +02:00
openedFiles->wDir = malloc(strlen(Dir)+1);
strncpy(openedFiles->wDir, Dir, strlen(Dir)+1);
} else {
2022-04-24 01:36:43 +02:00
if(openedFiles->validrDir) {
2022-04-23 00:56:30 +02:00
free(openedFiles->rDir);
2022-04-24 01:36:43 +02:00
openedFiles->rDir = NULL;
2022-05-03 23:30:47 +02:00
openedFiles->validrDir = 0;
}
if(strncmp(Dir, "/dev/null", strlen("/dev/null")+1) == 0) {
return 0;
2022-04-24 01:36:43 +02:00
}
openedFiles->validrDir = 1;
2022-04-23 00:56:30 +02:00
openedFiles->rDir = malloc(strlen(Dir)+1);
strncpy(openedFiles->rDir, Dir, strlen(Dir)+1);
}
2022-04-24 01:36:43 +02:00
return 0;
2022-04-16 21:21:04 +02:00
}
2022-04-21 20:08:22 +02:00
void printInfo(int p, FILE *stream) {
// 1 prints, 0 does not print
2022-04-24 01:36:43 +02:00
if(!openedFiles) {
if(createOpenedFiles()<0) {
perror("createOpenedfiles");
return;
}
}
2022-04-21 20:08:22 +02:00
openedFiles->print = (p)? 1: 0;
openedFiles->out = stream;
2022-04-16 21:21:04 +02:00
return;
}
2022-04-21 19:56:50 +02:00
// -----------------------------------------------------------------------------
2022-04-22 21:59:40 +02:00
int reciveData(response_t *res, int expected) {
if(!res) {
errno = EINVAL;
return -1;
}
int readnres;
2022-04-24 01:36:43 +02:00
readnres = readn(fd_skt, &res->ME, sizeof(res->ME));
2022-04-22 21:59:40 +02:00
if(readnres <= 0) {
// readn sets errno
return -1;
}
if(expected == 0) // no file expected
goto _nofile;
// file is expected
if(strncmp(res->ME, MEOK, sizeof(res->ME))==0){
// ok response
res->meerrno = 0;
// get number of files sent
2022-04-27 21:18:25 +02:00
readnres = readn(fd_skt, &res->numfiles, sizeof(int64_t));
2022-04-22 21:59:40 +02:00
if(readnres<=0) // readn sets errno
return -1;
if(res->rf)
free(res->rf);
2022-04-27 21:18:25 +02:00
if(res->numfiles < 0) {
errno = EINVAL;
return -1;
}
2022-04-22 21:59:40 +02:00
res->rf = calloc(res->numfiles, sizeof(recivedFile_t));
if(!res->rf){
perror("calloc");
return -1;
}
2022-04-29 21:04:45 +02:00
2022-04-22 21:59:40 +02:00
// get files
for(int i=0;i<res->numfiles;++i) {
// read path
readnres = readn(fd_skt, &res->rf[i].pathlen, sizeof(int64_t));
if(readnres<=0) // readn sets errno
return -1;
res->rf[i].path = calloc(res->rf[i].pathlen, sizeof(char));
if(!res->rf[i].path){
perror("calloc");
return -1;
}
readnres = readn(fd_skt, res->rf[i].path, res->rf[i].pathlen);
if(readnres<=0) // readn sets errno
return -1;
// we replace '/' char with '-'
for(int j=0;j<res->rf[i].pathlen; ++j){
if(res->rf[i].path[j] == '/')
res->rf[i].path[j] = '-';
}
// read file
readnres = readn(fd_skt, &res->rf[i].filelen, sizeof(int64_t));
if(readnres<=0) // readn sets errno
return -1;
2022-04-29 21:04:45 +02:00
if(res->rf[i].filelen == 0) {
res->rf[i].file = calloc(1, sizeof(char));
if(!res->rf[i].file){
perror("calloc");
return -1;
}
continue;
}
2022-04-22 21:59:40 +02:00
res->rf[i].file = calloc(res->rf[i].filelen, sizeof(char));
if(!res->rf[i].file){
perror("calloc");
return -1;
}
readnres = readn(fd_skt, res->rf[i].file, res->rf[i].filelen);
2022-04-29 21:04:45 +02:00
if(readnres<=0) {// readn sets errno
2022-04-22 21:59:40 +02:00
return -1;
2022-04-29 21:04:45 +02:00
}
2022-04-22 21:59:40 +02:00
}
return 0;
}
if(strncmp(res->ME, MEFP, sizeof(res->ME))==0){
// file purged
res->meerrno = 0;
// get number of files sent
readnres = readn(fd_skt, &res->numfiles, sizeof(int));
if(readnres<=0) // readn sets errno
return -1;
if(res->rf)
free(res->rf);
res->rf = calloc(res->numfiles, sizeof(recivedFile_t));
if(!res->rf){
perror("calloc");
return -1;
}
2022-04-29 01:26:31 +02:00
2022-04-22 21:59:40 +02:00
// get files
for(int i=0;i<res->numfiles;++i) {
// read path
readnres = readn(fd_skt, &res->rf[i].pathlen, sizeof(int64_t));
if(readnres<=0) // readn sets errno
return -1;
res->rf[i].path = calloc(res->rf[i].pathlen, sizeof(char));
if(!res->rf[i].path){
perror("calloc");
return -1;
}
readnres = readn(fd_skt, res->rf[i].path, res->rf[i].pathlen);
if(readnres<=0) // readn sets errno
return -1;
// we replace '/' char with '-'
for(int j=0;j<res->rf[i].pathlen; ++j){
if(res->rf[i].path[j] == '/')
res->rf[i].path[j] = '-';
}
// read file
readnres = readn(fd_skt, &res->rf[i].filelen, sizeof(int64_t));
if(readnres<=0) // readn sets errno
return -1;
2022-04-29 21:04:45 +02:00
if(res->rf[i].filelen == 0) {
res->rf[i].file = calloc(1, sizeof(char));
if(!res->rf[i].file){
perror("calloc");
return -1;
}
continue;
}
2022-04-22 21:59:40 +02:00
res->rf[i].file = calloc(res->rf[i].filelen, sizeof(char));
if(!res->rf[i].file){
perror("calloc");
return -1;
}
readnres = readn(fd_skt, res->rf[i].file, res->rf[i].filelen);
if(readnres<=0) // readn sets errno
return -1;
}
return 0;
}
if(strncmp(res->ME, MESD, sizeof(res->ME))==0){
// server shutting down
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
if(readnres <= 0)// readn sets errno
return -1;
return 0;
}
if(strncmp(res->ME, MENT, sizeof(res->ME))==0){
// requested file action not taken
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
if(readnres <= 0)// readn sets errno
return -1;
return 0;
}
if(strncmp(res->ME, MESY, sizeof(res->ME))==0){
// syntax error
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
if(readnres <= 0)// readn sets errno
return -1;
return 0;
}
if(strncmp(res->ME, MESE, sizeof(res->ME))==0){
// server error
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
if(readnres <= 0)// readn sets errno
return -1;
return 0;
}
errno = ENOPROTOOPT;
return -2;
_nofile:
res->numfiles = 0;
if(res->rf)
free(res->rf);
res->rf = NULL;
if(strncmp(res->ME, MEOK, sizeof(res->ME))==0){
// simple ok response
res->meerrno = 0;
return 0;
}
if(strncmp(res->ME, MEFP, sizeof(res->ME))==0){
// file purged
res->meerrno = 0;
// get number of files sent
2022-04-29 01:26:31 +02:00
readnres = readn(fd_skt, &res->numfiles, sizeof(int64_t));
2022-04-22 21:59:40 +02:00
if(readnres<=0) // readn sets errno
return -1;
2022-04-29 01:26:31 +02:00
2022-04-22 21:59:40 +02:00
if(res->rf)
free(res->rf);
res->rf = calloc(res->numfiles, sizeof(recivedFile_t));
if(!res->rf){
perror("calloc");
return -1;
}
// get files
for(int i=0;i<res->numfiles;++i) {
// read path
readnres = readn(fd_skt, &res->rf[i].pathlen, sizeof(int64_t));
if(readnres<=0) // readn sets errno
return -1;
res->rf[i].path = calloc(res->rf[i].pathlen, sizeof(char));
if(!res->rf[i].path){
perror("calloc");
return -1;
}
readnres = readn(fd_skt, res->rf[i].path, res->rf[i].pathlen);
if(readnres<=0) // readn sets errno
return -1;
// we replace '/' char with '-'
for(int j=0;j<res->rf[i].pathlen; ++j){
if(res->rf[i].path[j] == '/')
res->rf[i].path[j] = '-';
}
// read file
readnres = readn(fd_skt, &res->rf[i].filelen, sizeof(int64_t));
if(readnres<=0) // readn sets errno
return -1;
2022-04-29 01:26:31 +02:00
// file has lenght 0 -> allocate memory but dont read
if(res->rf[i].filelen == 0) {
res->rf[i].file = calloc(1, sizeof(char));
if(!res->rf[i].file){
perror("calloc");
return -1;
}
continue;
}
2022-04-22 21:59:40 +02:00
res->rf[i].file = calloc(res->rf[i].filelen, sizeof(char));
if(!res->rf[i].file){
perror("calloc");
return -1;
}
readnres = readn(fd_skt, res->rf[i].file, res->rf[i].filelen);
if(readnres<=0) // readn sets errno
return -1;
}
return 0;
}
if(strncmp(res->ME, MESD, sizeof(res->ME))==0){
// server shutting down
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
if(readnres <= 0)// readn sets errno
return -1;
return 0;
}
if(strncmp(res->ME, MENT, sizeof(res->ME))==0){
// requested file action not taken
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
if(readnres <= 0)// readn sets errno
return -1;
return 0;
}
if(strncmp(res->ME, MESY, sizeof(res->ME))==0){
// syntax error
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
if(readnres <= 0)// readn sets errno
return -1;
return 0;
}
if(strncmp(res->ME, MESE, sizeof(res->ME))==0){
// server error
readnres = readn(fd_skt, &res->meerrno, sizeof(errno));
if(readnres <= 0)// readn sets errno
return -1;
return 0;
}
errno = ENOPROTOOPT;
return -2;
}
2022-04-23 00:56:30 +02:00
int storeFilesInDirectory(const char *dirname, int n, recivedFile_t *rf) {
2022-04-29 15:47:27 +02:00
if(!dirname || strcmp(dirname, "")==0 || !rf || n<0) {
2022-04-22 21:59:40 +02:00
errno = EINVAL;
return -1;
}
// create directory
if(mkdir(dirname, 0777) == -1) {
if(errno != EEXIST) { // unknown error
return -1;
}
}
size_t basepathlen = strlen(dirname)+1+1; // +1 for '/' and +1 for '\0'
char *basepath = calloc(basepathlen, sizeof(char));
if(!basepath) {
perror("calloc");
return -1;
}
strcpy(basepath, dirname);
2022-04-24 13:01:13 +02:00
strncat(basepath, "/", basepathlen);
2022-04-22 21:59:40 +02:00
// for each file, create and write
for(int i=0;i<n;++i) {
char *filename = calloc(basepathlen + rf[i].pathlen, sizeof(char));
if(!filename){
perror("calloc");
free(basepath);
return -1;
}
strcpy(filename, basepath);
2022-04-24 13:01:13 +02:00
strncat(filename, rf[i].path, basepathlen + rf[i].pathlen);
2022-04-22 21:59:40 +02:00
int fdo;
if((fdo = open(filename, O_WRONLY | O_CREAT, 0666)) == -1) { // open
free(filename);
free(basepath);
return -1;
}
if(write(fdo, rf[i].file, rf[i].filelen) == -1) { // write
free(filename);
free(basepath);
return -1;
}
if(close(fdo) == -1) { // close
free(filename);
free(basepath);
return -1;
}
free(filename);
}
free(basepath);
return 0;
}
void freeResponse(response_t *res) {
if(!res)
return;
if(res->numfiles>0 && res->rf){
for(int i=0;i<res->numfiles;++i){
2022-04-24 01:36:43 +02:00
if(res->rf[i].path)
free(res->rf[i].path);
res->rf[i].path = NULL;
if(res->rf[i].file)
free(res->rf[i].file);
res->rf[i].file = NULL;
2022-04-22 21:59:40 +02:00
}
free(res->rf);
}
return;
}
2022-04-25 20:24:55 +02:00
int isOpen(const char *pathname, const int flags) {
2022-04-22 21:59:40 +02:00
if(!pathname) {
errno = EINVAL;
return -1;
}
if (openedFiles == NULL || openedFiles->f == NULL || openedFiles->numOfFiles == 0) {
return 0;
}
files_t *tmp = openedFiles->f;
while(tmp) {
2022-04-27 21:18:25 +02:00
if(strcmp(tmp->filename, pathname) == 0 && (tmp->locked || !(flags&O_LOCK)))
2022-04-22 21:59:40 +02:00
return 1;
tmp = tmp->next;
}
return 0;
}
2022-04-25 20:24:55 +02:00
int addOpenFile(const char *pathname, const int flags) {
2022-04-22 21:59:40 +02:00
if(!pathname) {
errno = EINVAL;
return -1;
}
files_t *new = malloc(sizeof(files_t));
if(!new) {
perror("malloc");
return -1;
}
size_t len = strlen(pathname)+1;
2022-04-25 20:24:55 +02:00
new->locked = flags&O_LOCK;
2022-04-22 21:59:40 +02:00
new->filename = calloc(len, sizeof(char));
if(!new->filename) {
perror("calloc");
free(new);
return -1;
}
2022-04-24 13:01:13 +02:00
strncpy(new->filename, pathname, len);
2022-04-22 21:59:40 +02:00
new->next = NULL;
if(openedFiles->f == NULL) {
openedFiles->f = new;
openedFiles->numOfFiles = 1;
return 0;
}
files_t *tail = openedFiles->f;
while(tail->next) {
tail = tail->next;
}
tail->next = new;
openedFiles->numOfFiles++;
return 0;
}
2022-04-23 00:56:30 +02:00
int removeOpenFile(const char *pathname) {
2022-04-21 19:56:50 +02:00
if(!pathname) {
errno = EINVAL;
return -1;
}
if(!openedFiles || !openedFiles->f || openedFiles->numOfFiles == 0) {
errno = ENOENT;
return -1;
}
files_t *tmp = openedFiles->f;
// the element to remove is the first
if(strcmp(tmp->filename, pathname) == 0) {
openedFiles->f = tmp->next;
free(tmp->filename);
free(tmp);
2022-04-24 01:36:43 +02:00
return 0;
2022-04-21 19:56:50 +02:00
}
files_t *prc = NULL;
while(tmp->next) {
prc = tmp;
tmp = tmp->next;
if(strcmp(tmp->filename, pathname) == 0) {
prc->next = tmp->next;
free(tmp->filename);
free(tmp);
return 0;
}
}
// file not found
errno = ENOENT;
return -1;
}
int closeEveryFile() {
2022-04-24 01:36:43 +02:00
if (openedFiles == NULL)
2022-04-21 19:56:50 +02:00
return 0;
2022-04-24 01:36:43 +02:00
2022-04-21 19:56:50 +02:00
if (openedFiles->numOfFiles > 0 && openedFiles->f != NULL) {
files_t *tmp = openedFiles->f;
files_t *prc = NULL;
while(tmp){
prc = tmp;
tmp = tmp->next;
if(closeFile(prc->filename) != 0) {
if(removeOpenFile(prc->filename) != 0) {
perror("removeOpenfile");
}
openedFiles->numOfFiles--;
}
}
}
2022-04-24 12:20:31 +02:00
2022-04-24 01:36:43 +02:00
if(openedFiles->createdAndLocked) {
free(openedFiles->createdAndLocked);
openedFiles->createdAndLocked = NULL;
}
if(openedFiles->validrDir) {
free(openedFiles->rDir);
openedFiles->validrDir = 0;
openedFiles->rDir = NULL;
}
if(openedFiles->validwDir) {
free(openedFiles->wDir);
openedFiles->validwDir = 0;
openedFiles->wDir = NULL;
}
2022-04-25 20:24:55 +02:00
free(openedFiles);
openedFiles = NULL;
2022-04-24 01:36:43 +02:00
return 0;
}
int createOpenedFiles(void) {
2022-04-24 15:38:30 +02:00
openedFiles = calloc(1, sizeof(*openedFiles));
2022-04-24 01:36:43 +02:00
if(!openedFiles) {
perror("calloc");
return -1;
}
openedFiles->f = NULL;
openedFiles->numOfFiles = 0;
openedFiles->createdAndLocked = NULL;
openedFiles->validrDir = 0;
openedFiles->rDir = NULL;
openedFiles->validwDir = 0;
openedFiles->wDir = NULL;
openedFiles->print = 0;
openedFiles->out = NULL;
2022-04-21 19:56:50 +02:00
return 0;
}