diff --git a/client.py b/client.py
index 8eaa5cfa95f152ddba1a83115ffaed7833b8e7d5..091ac19c976103def355b2e861c4c533e753441d 100755
--- a/client.py
+++ b/client.py
@@ -65,7 +65,7 @@ GPG_TRUSTLEVELS = {
 VERB = False
 #: Par défaut, place-t-on le mdp dans le presse-papier ?
 CLIPBOARD = bool(os.getenv('DISPLAY')) and os.path.exists('/usr/bin/xclip')
-#: Mode «ne pas demaner confirmation»
+#: Mode «ne pas demander confirmation»
 FORCED = False
 #: Droits à définir sur le fichier en édition
 NROLES = None
@@ -255,11 +255,9 @@ def encrypt(roles, contents):
     stdin.close()
     out = stdout.read().decode("utf-8")
     if out == '':
-        if not QUIET:
-            print(u"Échec de chiffrement".encode("utf-8"))
-        return None
+        return [False, u"Échec de chiffrement"]
     else:
-        return out
+        return [True, out]
 
 def decrypt(contents):
     """Déchiffre le contenu"""
@@ -271,20 +269,24 @@ def decrypt(contents):
 def put_password(name, roles, contents):
     """Dépose le mot de passe après l'avoir chiffré pour les
     destinataires donnés"""
-    enc_pwd = encrypt(roles, contents)
+    success, enc_pwd_or_error = encrypt(roles, contents)
     if NROLES != None:
         roles = NROLES
         if VERB:
             print(u"Pas de nouveaux rôles".encode("utf-8"))
-    if enc_pwd <> None:
+    if success:
+        enc_pwd = enc_pwd_or_error
         return put_file(name, roles, enc_pwd)
     else:
-        return False
+        error = enc_pwd_or_error
+        return [False, error]
 
 def get_password(name):
     """Récupère le mot de passe donné par name"""
-    remotefile = get_file(name)
-    return decrypt(remotefile['contents'])
+    gotit, remotefile = get_file(name)
+    if gotit:
+        remotefile = decrypt(remotefile['contents'])
+    return [gotit, remotefile]
 
 ######
 ## Interface
@@ -308,9 +310,7 @@ def editor(texte, annotations=u""):
     ntexte = f.read().decode("utf-8")
     f.close()
     ntexte = u'\n'.join(filter(lambda l: not l.startswith('#'), ntexte.split('\n')))
-    if texte != ntexte:
-        return ntexte
-    return None
+    return ntexte
 
 def show_files():
     """Affiche la liste des fichiers disponibles sur le serveur distant"""
@@ -328,9 +328,9 @@ def show_files():
 def show_roles():
     """Affiche la liste des roles existants"""
     print(u"Liste des roles disponibles".encode("utf-8"))
-    for role in all_roles().keys():
+    for (role, usernames) in all_roles().iteritems():
         if not role.endswith('-w'):
-            print((u" * " + role ).encode("utf-8"))
+            print((u" * %s : %s" % (role, ", ".join(usernames))).encode("utf-8"))
 
 def show_servers():
     """Affiche la liste des serveurs disponibles"""
@@ -367,9 +367,9 @@ def clipboard(texte):
 
 def show_file(fname):
     """Affiche le contenu d'un fichier"""
-    value = get_file(fname)
-    if value == False:
-        print(u"Fichier introuvable".encode("utf-8"))
+    gotit, value = get_file(fname)
+    if not gotit:
+        print(value.encode("utf-8")) # value contient le message d'erreur
         return
     (sin, sout) = gpg('decrypt')
     sin.write(value['contents'].encode("utf-8"))
@@ -395,10 +395,10 @@ def show_file(fname):
         
 def edit_file(fname):
     """Modifie/Crée un fichier"""
-    value = get_file(fname)
+    gotit, value = get_file(fname)
     nfile = False
     annotations = u""
-    if value == False:
+    if not gotit and not "pas les droits" in value:
         nfile = True
         print(u"Fichier introuvable".encode("utf-8"))
         if not confirm(u"Créer fichier ?"):
@@ -415,13 +415,16 @@ Enregistrez le fichier vide pour annuler.\n"""
             print(u"Vous ne possédez aucun rôle en écriture ! Abandon.".encode("utf-8"))
             return
         value = {'roles' : roles}
+    elif not gotit:
+        print(value.encode("utf-8")) # value contient le message d'erreur
+        return
     else:
         (sin, sout) = gpg('decrypt')
         sin.write(value['contents'].encode("utf-8"))
         sin.close()
         texte = sout.read().decode("utf-8")
     value['roles'] = NROLES or value['roles']
-
+    
     annotations += u"""Ce fichier sera chiffré pour les rôles suivants :\n%s\n
 C'est-à-dire pour les utilisateurs suivants :\n%s""" % (
            ', '.join(value['roles']),
@@ -429,15 +432,14 @@ C'est-à-dire pour les utilisateurs suivants :\n%s""" % (
         )
         
     ntexte = editor(texte, annotations)
-
-    if ntexte == None and not nfile and NROLES == None:
-        print(u"Pas de modifications effectuées".encode("utf-8"))
+    
+    if ((not nfile and ntexte in [u'', texte] and NROLES == None) or # Fichier existant vidé ou inchangé
+        (nfile and ntexte == u'')):                                  # Nouveau fichier créé vide
+        print(u"Pas de modification effectuée".encode("utf-8"))
     else:
         ntexte = texte if ntexte == None else ntexte
-        if put_password(fname, value['roles'], ntexte):
-            print(u"Modifications enregistrées".encode("utf-8"))
-        else:
-            print(u"Erreur lors de l'enregistrement (avez-vous les droits suffisants ?)".encode("utf-8"))
+        success, message = put_password(fname, value['roles'], ntexte)
+        print(message.encode("utf-8"))
 
 def confirm(text):
     """Demande confirmation, sauf si on est mode ``FORCED``"""
@@ -451,12 +453,10 @@ def confirm(text):
 
 def remove_file(fname):
     """Supprime un fichier"""
-    if not confirm((u'Êtes-vous sûr de vouloir supprimer %s ?' % fname).encode("utf-8")):
+    if not confirm(u'Êtes-vous sûr de vouloir supprimer %s ?' % fname):
         return
-    if rm_file(fname):
-        print(u"Suppression effectuée".encode("utf-8"))
-    else:
-        print(u"Erreur de suppression (avez-vous les droits ?)".encode("utf-8"))
+    message = rm_file(fname)
+    print(message.encode("utf-8"))
 
 
 def my_check_keys():
@@ -482,7 +482,8 @@ def recrypt_files():
         if set(roles).intersection(froles) == set([]):
             continue
         print((u"Rechiffrement de %s" % fname).encode("utf-8"))
-        put_password(fname, froles, get_password(fname))
+        _, password = get_password(fname)
+        put_password(fname, froles, password)
 
 def parse_roles(strroles):
     """Interprête une liste de rôles fournie par l'utilisateur"""
diff --git a/server.py b/server.py
index 941866a23b9a7827b4392ae366c9bde8cf608fe4..5d7d4fc70bd1c8603c5db65c25525e59f34591f0 100755
--- a/server.py
+++ b/server.py
@@ -72,10 +72,10 @@ def getfile(filename):
     try:
         obj = json.loads(open(filepath).read())
         if not validate(obj['roles']):
-	        return False
-        return obj
+	        return [False, u"Vous n'avez pas les droits de lecture sur le fichier %s." % filename]
+        return [True, obj]
     except IOError:
-        return False
+        return [False, u"Le fichier %s n'existe pas." % filename]
      
 
 def putfile(filename):
@@ -87,41 +87,38 @@ def putfile(filename):
         roles = parsed_stdin['roles']
         contents = parsed_stdin['contents']
     except KeyError:
-        return False
+        return [False, u"Entrée invalide"]
     
-    try:
-        old = getfile(filename)
-        oldroles = old['roles']
-    except TypeError:
+    gotit, old = getfile(filename)
+    if not gotit:
         old = u"[Création du fichier]"
         pass
     else:
-        if not validate(oldroles,'w'):
-            return False
-        
-        corps = u"Le fichier %s a été modifié par %s." % (filename, MYUID)
-        backup(corps, filename, old)
-        notification(u"Modification de %s" % filename, corps, filename, old)
+        oldroles = old['roles']
+        if not validate(oldroles, 'w'):
+            return [False, u"Vous n'avez pas le droit d'écriture sur %s." % filename]
+    
+    corps = u"Le fichier %s a été modifié par %s." % (filename, MYUID)
+    backup(corps, filename, old)
+    notification(u"Modification de %s" % filename, corps, filename, old)
     
     writefile(filepath, json.dumps({'roles': roles, 'contents': contents}))
-    return True
+    return [True, u"Modification effectuée."]
 
 def rmfile(filename):
     """Supprime le fichier filename après avoir vérifié les droits sur le fichier"""
-    try:
-        old = getfile(filename)
-        roles = old['roles']
-    except TypeError:
-        return True
+    gotit, old = getfile(filename)
+    if not gotit:
+        return old # contient le message d'erreur
+    roles = old['roles']
+    if validate(roles, 'w'):
+        corps = u"Le fichier %s a été supprimé par %s." % (filename, MYUID)
+        backup(corps, filename, old)
+        notification(u"Suppression de %s" % filename, corps, filename, old)
+        os.remove(getpath(filename))
     else:
-        if validate(roles,'w'):
-            corps = u"Le fichier %s a été supprimé par %s." % (filename, MYUID)
-            backup(corps, filename, old)
-            notification(u"Suppression de %s" % filename, corps, filename, old)
-            os.remove(getpath(filename))
-        else:
-            return False
-    return True
+        return u"Vous n'avez pas les droits d'écriture sur le fichier %s." % filename
+    return u"Suppression effectuée"
 
 def backup(corps, fname, old):
     """Backupe l'ancienne version du fichier"""
@@ -164,20 +161,23 @@ if __name__ == "__main__":
     except IndexError:
         pass
     
+    answer = None
     if command == "listroles":
-        print(json.dumps(listroles()))
+        answer = listroles()
     elif command == "listkeys":
-        print(json.dumps(listkeys()))
+        answer = listkeys()
     elif command == "listfiles":
-        print(json.dumps(listfiles()))
+        answer = listfiles()
     else:
         if not filename:
             sys.exit(1)
         if command == "getfile":
-            print(json.dumps(getfile(filename)))
+            answer = getfile(filename)
         elif command == "putfile":
-            print(json.dumps(putfile(filename)))
+            answer = putfile(filename)
         elif command == "rmfile":
-            print(json.dumps(rmfile(filename)))
+            answer = rmfile(filename)
         else:
             sys.exit(1)
+    if not answer is None:
+        print(json.dumps(answer))