#include #include #define MAXLENMESS 512 #define MEOK "20" //OK #define MEHE "21" // help message // #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 void openFile(char *filepath, int flags, 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 openFile (flags = %x) sul file \"%s\" e' terminata con errore\n", fd_c, flags, filepath); errno = EINVAL; serror(MESY, fd_c, taglia, tmp_buf); return; } int found = searchFile(q, filepath); // cerco il file nella queue int create = flags & 0x1; // also %2 int lock = flags >> 1 & 0x1; // also >>1%2 fileT *removed = NULL; // file che è stato rimosso if(found && create) { // si vuole creare il file ma esiste già n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminata con errore\n", fd_c, flags, filepath); errno = EEXIST; serror(MENT, fd_c, taglia, tmp_buf); return; } if(!found && !create) { // si vuole aprire e non creare un file inesistente n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore\n", fd_c, flags, filepath); errno = ENOENT; serror(MENT, fd_c, taglia, tmp_buf); return; } if(found && !create) { if(openFileInQueue(q, file, lock, fd_c) == -1) { n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore\n", fd_c, flags, filepath); perror("openFileInQueue"); serror(MESE, fd_c, taglia, tmp_buf); return; } n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminata con successo\n", fd_c, flags, filepath); sendMessage(MEOK, fd_c, taglia, tmp_buf); return; } if(!found && create) { // not found and creating new file if(getLen(q) == queue->maxLen) { // capacity miss removed = dequeue(q); if(!removed) { n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore\n", fd_c, flags, filepath); perror("dequeue"); serror(MESE, fd_c, taglia, tmp_buf); return; } fileT *f = createFileT(filepath, lock, fd_c, 1); // create new file if(!f) { n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore del server\n", fd_c, flags, filepath); perror("createFileT"); serror(MESE, fd_c, taglia); return; } if(enqueue(q, f) != 0) { n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore del server\n", fd_c, flags, filepath); perror("enqueue"); serror(MESE, fd_c, taglia); return; } taglia_update(taglia, q, 1); // removed only one file n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" ha causato una capacity miss. File espulso \"%s\"\n", fd_c, flags, filepath, removed->filepath); sendMessageFile(MEFP, removed, fd_c, taglia, tmp_buf); free(removed); return; } fileT *f = createFileT(filepath, lock, fd_c, 1); if(!f) { n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore del server\n", fd_c, flags, filepath); perror("createFileT"); serror(MESE, fd_c, taglia); return; } if(enqueue(q, f) != 0) { n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con errore del server\n", fd_c, flags, filepath); perror("enqueue"); serror(MESE, fd_c, taglia); return; } // abbiamo aggiunto un file quindi il numero di file è cambiato // quindi bisogna fare un update del log taglia_update(taglia, q, 0); n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una openFile (flags = %x) sul file \"%s\" e' terminato con successo\n", fd_c, flags, filepath); sendMessage(MEOK, fd_c, taglia, tmp_buf); return; } } // 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 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 readFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia); 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); void lockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting); void unlockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting); void closeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting); void removeFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting); int sendFile(fileT *f, long fd_c, taglia_t *taglia); int addWaiting(waitingT **waiting, char *file, int fd); int removeFirstWaiting(waitingT **waiting, char *file); void clearWaiting(waitingT **waiting);