/// <summary> /// Carica la versione richiesta del file all'utente che lo richiede. /// </summary> /// <param name="s"></param> /// <param name="dati"> /// [0]: nome_file /// [1]: path relativo /// [2]: timestamp versione (in Ticks) /// </param> /// <returns> /// OK intermedio /// token /// dimensione file /// sha contenuto /// </returns> public override IEnumerable <string> esegui(List <string> dati) { StringBuilder sb = new StringBuilder(); Log l = Log.getLog(); if (user == null) { yield return(sb.Append(CommandErrorCode.UtenteNonLoggato.ToString("D")).Append(" Utente non loggato.").ToString()); yield break; } if (dati.Count < 3) { yield return(sb.Append(CommandErrorCode.DatiIncompleti.ToString("D")) .Append(" I dati inviati non sono sufficienti").ToString()); yield break; } DateTime timestamp = new DateTime(Int64.Parse(dati[2])); string nome_file = dati[0]; string path_relativo = dati[1]; Snapshot snap = null; try { snap = user.FileList[nome_file, path_relativo].Snapshots[timestamp]; } catch (Exception e) { l.log("Errore nel selezionare il file corretto. " + e.Message, Level.ERR); } if (snap == null) { yield return(sb.Append(CommandErrorCode.AperturaFile.ToString("D")).Append(" File non esistente o errore strano").ToString()); yield break; } string token = CollegamentoDati.getNewToken(); yield return(sb.Append(CommandErrorCode.OKIntermedio.ToString("D")).Append(" File pronto. Connettiti alla porta corrispondente").ToString()); yield return(token); yield return(snap.Dim.ToString()); yield return(snap.shaContenuto); yield return(""); //Prepararsi all'invio del file... NetworkStream ns = CollegamentoDati.getCollegamentoDati(token); int buff_size = 1024; int letti = 0; byte[] buff = new byte[buff_size]; do { letti = snap.leggiBytesDalContenuto(buff, buff_size); ns.Write(buff, 0, letti); } while (letti > 0); ns.Close(); sb.Clear(); try { //il file era delete e lo sto ripristinando if (!user.FileList[nome_file, path_relativo].Valido) { user.FileList[nome_file, path_relativo].Valido = true; user.FileList[nome_file, path_relativo].Snapshots[timestamp].Valido = true; } //sto scaricando una versione precedente else { //setto a false lo snapshot vecchio user.FileList[nome_file, path_relativo].Snapshots.getValido().Valido = false; //setto a true lo snapshot nuovo user.FileList[nome_file, path_relativo].Snapshots[timestamp].Valido = true; } } catch (Exception e) { l.log("Errore nel settare il flag a valido: " + e.Message); throw; } yield return(sb.Append(CommandErrorCode.OK.ToString("D")).Append(" File scritto correttamente").ToString()); }
/// <summary> /// Comando che gestisce l'aggiornamento del contenuto di un file /// </summary> /// <param name="s"></param> /// <param name="dati"> /// [0]: nome del file /// [1]: path relativo del file /// [2]: timestamp di modifica (in "ticks") /// [3]: sha256 del file in codifica base64 /// [4]: dimensione del file in formato testuale /// </param> /// <returns> /// Ritorna prima una stringa con il codice "OKIntermedio" seguita dal token assegnato al client. /// Quando il client si connette alla porta dati viene ricevuto il nuovo contenuto del file e in /// caso di successo viene ancora inviato un messaggio di ok. /// </returns> public override IEnumerable <string> esegui(List <string> dati) { Log l = Log.getLog(); StringBuilder sb = new StringBuilder(); if (user == null) { yield return(sb.Append(CommandErrorCode.UtenteNonLoggato.ToString("D")).Append(" Utente non loggato.").ToString()); yield break; } if (dati.Count < 5) { yield return(sb.Append(CommandErrorCode.DatiIncompleti.ToString("D")) .Append(" I dati inviati non sono sufficienti").ToString()); yield break; } FileUtente daModificare; Snapshot snap; string nome_file = dati[0]; string path_relativo = dati[1]; DateTime timestamp = new DateTime(Int64.Parse(dati[2])); string sha256 = dati[3]; int dim = Int32.Parse(dati[4]); try { daModificare = user.FileList[dati[0], dati[1]]; snap = daModificare.Snapshots.Nuovo(timestamp, dim, sha256); } catch (Exception e) { l.log("Errore... " + e.Message, Level.ERR); throw; } string token = CollegamentoDati.getNewToken(); yield return(sb.Append(CommandErrorCode.OKIntermedio.ToString("D")).Append(" Stream dati pronto").ToString()); yield return(token); yield return(""); NetworkStream stream_dati = CollegamentoDati.getCollegamentoDati(token); byte[] buffer = new byte[1024]; int letti = 0; try { do { letti = stream_dati.Read(buffer, 0, 1024); snap.scriviBytes(buffer, letti); } while (letti != 0); snap.completaScrittura(); } catch (Exception e) { l.log("Errore nella scrittura del file: " + e.Message, Level.ERR); throw; } yield return(CommandErrorCode.OK.ToString("D") + " Trasferimento completato con successo"); }
/// <summary> /// Comando per la creazione di un nuovo file sul server. Se l'utente ha troppi file, il più /// vecchio tra quelli eliminati viene distrutto. Se non ci sono file eliminati da distruggere /// viene generato un errore. /// </summary> /// <param name="dati"> /// [0]: nome_file /// [1]: path_relativo /// [2]: timestamp creazione (in ticks) /// [3]: sha256 del contenuto /// [4]: dimensione /// </param> /// <returns></returns> public override IEnumerable <string> esegui(List <string> dati) { Log l = Log.getLog(); StringBuilder sb = new StringBuilder(); if (user == null) { yield return(sb.Append(CommandErrorCode.UtenteNonLoggato.ToString("D")).Append(" Utente non loggato.").ToString()); yield break; } if (dati.Count < 7) { yield return(sb.Append(CommandErrorCode.DatiIncompleti.ToString("D")) .Append(" I dati inviati non sono sufficienti").ToString()); yield break; } string nome_file = dati[0]; string path_relativo = dati[1]; DateTime timestamp = new DateTime(); DateTime t_modifica = new DateTime(); int dim = -1; sb.Clear(); try { timestamp = new DateTime(Int64.Parse(dati[2])); t_modifica = new DateTime(Int64.Parse(dati[3])); dim = Int32.Parse(dati[5]); }catch (Exception e) { sb.Append(CommandErrorCode.FormatoDatiErrato.ToString("D")).Append(" Dimensione o timestamp non corretti"); l.log("Utente: " + user.Nome + " " + e.Message, Level.INFO); } // if exception occurred... if (dim == -1 || timestamp == DateTime.MinValue || t_modifica == DateTime.MinValue) { yield return(sb.ToString()); yield break; } sb.Clear(); string sha256 = dati[4]; FileUtente nuovo = null; try { nuovo = user.FileList.nuovoFile(nome_file, path_relativo, timestamp); } catch (DatabaseException e) { switch (e.ErrorCode) { case DatabaseErrorCode.LimiteFileSuperato: sb.Append(CommandErrorCode.LimiteFileSuperato.ToString("D")).Append(" L'utente ha superato il limite di file creabili."); break; case DatabaseErrorCode.FileEsistente: sb.Append(CommandErrorCode.FileEsistente.ToString("D")).Append(" Un file con quel nome esiste gia'."); break; default: l.log("Server Error!! " + e.Message, Level.ERR); sb.Append(CommandErrorCode.Default.ToString("D")).Append(" Errore del server durante la creazione del file."); break; } l.log("Errore nella creazione del file." + e.Message, Level.ERR); throw; } if (nuovo == null) { yield return(sb.ToString()); yield break; } Snapshot snap; sb.Clear(); try { snap = nuovo.Snapshots.Nuovo(t_modifica, dim, sha256); } catch (Exception e) { l.log("Errore... " + e.Message, Level.ERR); sb.Append(CommandErrorCode.Unknown.ToString("D")).Append(" Un errore sconosciuto è accaduto nel server."); snap = null; } if (snap == null) { yield return(sb.ToString()); yield break; } string token = CollegamentoDati.getNewToken(); yield return(sb.Append(CommandErrorCode.OKIntermedio.ToString("D")).Append(" Stream dati pronto").ToString()); yield return(token); yield return(""); NetworkStream stream_dati = CollegamentoDati.getCollegamentoDati(token); byte[] buffer = new byte[1024]; int letti = 0; try { do { letti = stream_dati.Read(buffer, 0, 1024); snap.scriviBytes(buffer, letti); } while (letti != 0); snap.completaScrittura(); } catch (Exception e) { l.log("Errore nella scrittura del file" + e.Message, Level.ERR); throw; } yield return(CommandErrorCode.OK.ToString("D") + " Trasferimento completato con successo"); }