writeFile function
This commit is contained in:
@ -18,6 +18,116 @@
|
||||
// #define ME "52" // not used
|
||||
#define MESE "55" // server error
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/* funzioni ausiliarie */
|
||||
|
||||
// invio il messaggio al client
|
||||
void sendMessage(char *m, long fd_c, taglia_t *taglia, char *mlog) {
|
||||
if(!m) {
|
||||
m = MEOK;
|
||||
}
|
||||
|
||||
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||
perror("writen");
|
||||
goto _sendM_cleanup;
|
||||
}
|
||||
|
||||
if(taglia_write(taglia, mlog) < 0)
|
||||
goto _sendM_cleanup;
|
||||
|
||||
return;
|
||||
|
||||
_sendM_cleanup:
|
||||
return;
|
||||
}
|
||||
|
||||
// invio il messaggio al client e poi il file
|
||||
void sendMessageFile(char *m, fileT *f, long fd_c, taglia_t *taglia, char *mlog) {
|
||||
if(!f) {
|
||||
errno = EINVAL;
|
||||
serror(MESY, fd_c);
|
||||
goto _sendMF_cleanup;
|
||||
}
|
||||
if(!m) {
|
||||
m = MEPF;
|
||||
}
|
||||
|
||||
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||
perror("writen");
|
||||
goto _sendMF_cleanup;
|
||||
}
|
||||
|
||||
if(sendFile(f, fd_c, taglia) < 0) {
|
||||
perror("sendFile");
|
||||
goto _sendMF_cleanup;
|
||||
}
|
||||
|
||||
if(taglia_write(taglia, mlog) < 0)
|
||||
goto _sendMF_cleanup;
|
||||
|
||||
return;
|
||||
|
||||
_sendMF_cleanup:
|
||||
return;
|
||||
}
|
||||
|
||||
// invio il messaggio al client e poi n file
|
||||
void sendMessageFileN(char *m, fileT **f, int n, long fd_c, taglia *taglia, char *mlog) {
|
||||
if(!f) {
|
||||
errno = EINVAL;
|
||||
serror(MESY, fd_c);
|
||||
goto _sendMFN_cleanup;
|
||||
}
|
||||
if(!m) {
|
||||
m = MEPF;
|
||||
}
|
||||
|
||||
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||
perror("writen");
|
||||
goto _sendMF_cleanup;
|
||||
}
|
||||
|
||||
for(int i=0; i<n && (f[i]!=NULL); ++i) {
|
||||
if(sendFile(f[i], fd_c, taglia) < 0) {
|
||||
perror("sendFile");
|
||||
goto _sendMF_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
if(taglia_write(taglia, mlog) < 0)
|
||||
goto _sendMF_cleanup;
|
||||
|
||||
return;
|
||||
|
||||
_sendMFN_cleanup:
|
||||
return;
|
||||
}
|
||||
|
||||
// invio il messaggio al client e poi l'errno
|
||||
void serror(char *m, long fd_c, taglia_t *taglia, char *mlog) {
|
||||
if(!m) {
|
||||
errno = EINVAL;
|
||||
m = MESY;
|
||||
}
|
||||
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||
perror("writen");
|
||||
goto _serror_cleanup;
|
||||
}
|
||||
if(writen(fd_c, &errno, sizeof(errno)) < 0) {
|
||||
perror("writen");
|
||||
goto _serror_cleanup;
|
||||
}
|
||||
|
||||
if(taglia_write(taglia, mlog) < 0)
|
||||
goto _serror_cleanup;
|
||||
|
||||
return;
|
||||
|
||||
_serror_cleanup:
|
||||
return;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia) {
|
||||
// messaggio da scrivere sul logfile
|
||||
@ -120,88 +230,179 @@ void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia)
|
||||
}
|
||||
}
|
||||
|
||||
// invio il messaggio al client
|
||||
void sendMessage(char *m, long fd_c, taglia_t *taglia, char *mlog) {
|
||||
if(!m) {
|
||||
m = MEOK;
|
||||
|
||||
void readFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia) {
|
||||
// messaggio da scrivere sul logfile
|
||||
char tmp_buf[2048];
|
||||
int n = 0;
|
||||
size_t m = sizeof(tmp_buf);
|
||||
|
||||
if(!filepath || !q || !taglia) {
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile (flags = %x) sul file \"%s\" e' terminata con errore\n", fd_c, flags, filepath);
|
||||
errno = EINVAL;
|
||||
serror(MESY, fd_c, taglia, tmp_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||
perror("writen");
|
||||
goto _sendM_cleanup;
|
||||
}
|
||||
|
||||
if(taglia_write(taglia, mlog) < 0)
|
||||
goto _sendM_cleanup;
|
||||
|
||||
return;
|
||||
|
||||
_sendM_cleanup:
|
||||
return;
|
||||
}
|
||||
|
||||
// invio il messaggio al client e poi il file
|
||||
void sendMessageFile(char *m, fileT *f, long fd_c, taglia_t *taglia, char *mlog) {
|
||||
fileT *f = NULL;
|
||||
f = find(q, filepath);
|
||||
if(!f) {
|
||||
errno = EINVAL;
|
||||
serror(MESY, fd_c);
|
||||
goto _sendMF_cleanup;
|
||||
}
|
||||
if(!m) {
|
||||
m = MEPF;
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile (flags = %x) sul file \"%s\" e' terminata con errore\n", fd_c, flags, filepath);
|
||||
errno = ENOENT;
|
||||
serror(MESE, fd_c, taglia, tmp_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||
perror("writen");
|
||||
goto _sendMF_cleanup;
|
||||
if(f->open != 0) { // file already open
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile (flags = %x) sul file \"%s\" e' terminata con errore\n", fd_c, flags, filepath);
|
||||
errno = EPERM;
|
||||
serror(MENT, fd_c, taglia, tmp_buf);
|
||||
destroyFile(f); // f is a copy so we need to cleen up
|
||||
return;
|
||||
}
|
||||
|
||||
if(sendFile(f, fd_c, taglia) < 0) {
|
||||
perror("sendFile");
|
||||
goto _sendMF_cleanup;
|
||||
}
|
||||
|
||||
if(taglia_write(taglia, mlog) < 0)
|
||||
goto _sendMF_cleanup;
|
||||
|
||||
return;
|
||||
|
||||
_sendMF_cleanup:
|
||||
return;
|
||||
}
|
||||
|
||||
// invio il messaggio al client e poi l'errno
|
||||
void serror(char *m, long fd_c, taglia_t *taglia, char *mlog) {
|
||||
if(!m) {
|
||||
errno = EINVAL;
|
||||
m = MESY;
|
||||
}
|
||||
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||
perror("writen");
|
||||
goto _serror_cleanup;
|
||||
}
|
||||
if(writen(fd_c, &errno, sizeof(errno)) < 0) {
|
||||
perror("writen");
|
||||
goto _serror_cleanup;
|
||||
}
|
||||
|
||||
if(taglia_write(taglia, mlog) < 0)
|
||||
goto _serror_cleanup;
|
||||
|
||||
return;
|
||||
|
||||
_serror_cleanup:
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile (flags = %x) sul file \"%s\" e' terminata con successo\n", fd_c, flags, filepath);
|
||||
sendMessageFile(MEOK, f, fd_c, taglia, tmp_buf);
|
||||
destroyFile(f); // f is a copy so we need to cleen up
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void readFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia);
|
||||
void readNFiles(char *numStr, queueT *q, long fd_c, taglia_t *taglia); // TODO
|
||||
|
||||
|
||||
void readNFiles(char *numStr, queueT *q, long fd_c, taglia_t *taglia);
|
||||
void writeFile(char *filepath, size_t size, queueT *q, long fd_c, taglia_t *taglia, int append) {
|
||||
// messaggio da scrivere sul logfile
|
||||
char tmp_buf[2048];
|
||||
int n = 0;
|
||||
size_t m = sizeof(tmp_buf);
|
||||
|
||||
if(!filepath || !q || !taglia) {
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una writeFile (append = %x) sul file \"%s\" e' terminata con errore\n", fd_c, append, filepath);
|
||||
errno = EINVAL;
|
||||
serror(MESY, fd_c, taglia, tmp_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
void writeFile(char *filepath, size_t size, queueT *q, long fd_c, taglia_t *taglia, int append);
|
||||
fileT *f = NULL;
|
||||
f = find(q, filepath);
|
||||
if(!f) { // file is not present
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una writeFile (append = %x) sul file \"%s\", dimensione = %ld, e' terminata con errore\n", fd_c, append, filepath, size);
|
||||
errno = ENOENT;
|
||||
serror(MENT, fd_c, taglia, tmp_buf);
|
||||
destroyFile(f);
|
||||
return;
|
||||
}
|
||||
|
||||
// file non aperto || !append => locked || lock ma non si è proprietari
|
||||
if(!f->open || (append || f->O_LOCK) || (f->O_LOCK && f->owner != fd_c)) {
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una writeFile (append = %x) sul file \"%s\", dimensione = %ld, e' terminata con errore\n", fd_c, append, filepath, size);
|
||||
errno = EPERM;
|
||||
serror(MENT, fd_c, taglia, tmp_buf);
|
||||
destroyFile(f);
|
||||
return;
|
||||
}
|
||||
int trueSizeAdded = 0; // we may have alredy some space allocated
|
||||
if(append) {
|
||||
trueSizeAdded = size - f->size + f->valid;
|
||||
} else {
|
||||
trueSizeAdded = (size>f->size)? size-f->size : 0;
|
||||
}
|
||||
destroyFile(f); // not needed anymore
|
||||
|
||||
fileT **removed = NULL; // array that may (worst case) hold all files to be sent to the client
|
||||
|
||||
if(trueSizeAdded + getSize(q) > q->maxSize) { // writing would be more than capacity
|
||||
removed = dequeueN(q, filepath, trueSizeAdded);
|
||||
if(!removed) { // internal error
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una writeFile (append = %x) sul file \"%s\", dimensione = %ld, e' terminata con errore\n", fd_c, append, filepath, size);
|
||||
errno = ENOENT;
|
||||
serror(MESY, fd_c, taglia, tmp_buf);
|
||||
return;
|
||||
}
|
||||
int ln = 0;
|
||||
fileT *tmp = removed[ln];
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una writeFile (append = %x) sul file \"%s\", dimensione = %ld, e' terminata con successo. Ha causato una capacity miss e ha fatto espellere i seguenti file:", fd_c, append, filepath, size);
|
||||
while(tmp!=NULL) {
|
||||
n += snprintf(tmp_buf+n, m-n, " \"%s\"", tmp->filepath);
|
||||
++ln;
|
||||
tmp=removed[ln];
|
||||
}
|
||||
n += snprintf(tmp_buf+n, m-n, "\n");
|
||||
taglia_update(taglia, q, ln);
|
||||
|
||||
sendMessageFileN(MEFP, removed, ln, fd_c, taglia, tmp_buf);
|
||||
for(int i=0;i<ln && (removed[i]!=NULL);++i) {
|
||||
destroyFile(removed[i]);
|
||||
}
|
||||
free(removed);
|
||||
// now we can write the actual file
|
||||
|
||||
void *content = NULL;
|
||||
content = malloc(size);
|
||||
if(!content) {
|
||||
perror("malloc");
|
||||
return;
|
||||
}
|
||||
if((readn(fd_c, content, size)) == -1) {
|
||||
perror("readn");
|
||||
return;
|
||||
}
|
||||
|
||||
if(append) {
|
||||
if(appendFileInQueue(q, filepath, content, size, fd_c) == -1) {
|
||||
perror("appendFileInQueue");
|
||||
free(content)
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if(writeFileInQueue(q, filepath, content, size, fd_c) == -1) {
|
||||
perror("writeFileInQueue");
|
||||
free(content)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
taglia_update(taglia, q, 0);
|
||||
free(content)
|
||||
return;
|
||||
}
|
||||
|
||||
// non c'è ancora bisogno di rimuovere file
|
||||
void *content = NULL;
|
||||
content = malloc(size);
|
||||
if(!content) {
|
||||
perror("malloc");
|
||||
return;
|
||||
}
|
||||
if(readn(fd_c, content, size) == -1) {
|
||||
perror("readn");
|
||||
return;
|
||||
}
|
||||
|
||||
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una writeFile (append = %x) sul file \"%s\", dimensione = %ld, e' terminata con successo\n", fd_c, append, filepath, size);
|
||||
|
||||
if(append) {
|
||||
if(appendFileInQueue(q, filepath, content, size, fd_c) == -1) {
|
||||
perror("appendFileInQueue");
|
||||
free(content)
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if(writeFileInQueue(q, filepath, content, size, fd_c) == -1) {
|
||||
perror("writeFileInQueue");
|
||||
free(content)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
taglia_write(taglia, mlog);
|
||||
|
||||
taglia_update(taglia, q, 0);
|
||||
|
||||
free(content)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void lockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting);
|
||||
|
||||
Reference in New Issue
Block a user