This file is indexed.

/usr/share/pyshared/scolasync/ownedUsbDisk.py is in scolasync 2.3-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# -*- coding: utf-8 -*-    
# 	$Id: ownedUsbDisk.py 47 2011-06-13 10:20:14Z georgesk $	

licence={}
licence['en']="""
    file ownedUsbDisk.py
    this file is part of the project scolasync
    
    Copyright (C) 2010 Georges Khaznadar <georgesk@ofset.org>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""


import usbDisk, db
import os.path, dbus, subprocess, time
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from globaldef import markFileName

"""
liste statique pour éviter de demander chaque seconde le nom d'un
propriétaire de clé si on n'a pas souhaité le donner.
"""

def editRecord(owd, student=""):
    """
    édition de la base de données
    @param owd une instance de ownedUsbDisk
    @param student nom de propriétaire pour la clé. Chaîne vide par défaut.
    """
    newStudent, ok = QInputDialog.getText(None,
                                          u"Choix du propriétaire",
                                          u"Nouveau nom du propriétaire de la clé",
                                          text=student
                                          )
    if ok:
        newStudent=u"%s" %newStudent
        db.writeStudent(owd.stickid, owd.getFatUuid(), owd.tattoo(), newStudent)

class uDisk(usbDisk.uDisk,QObject):
    """
    une classe qui ajoute un nom de propriétaire aux disque USB,
    et qui en même temps ajoute des particularités selon le nom du
    vendeur et le modèle.
    """
    def __init__(self, path, bus, checkable=False):
        """
        @param path un chemin dans le système dbus
        @param bus un objet dbus.BusSystem
        @param checkable vrai si on fera usage de self.selected
        """
        usbDisk.uDisk.__init__(self,path, bus, checkable)
        QObject.__init__(self)
        self.owner="" # le propriétaire est déterminé plus tard
        self.vendor=self.getProp("drive-vendor")
        self.model=self.getProp("drive-model")
        self.visibleDirs=self.readQuirks()

    def uniqueId(self):
        """
        @return un identifiant unique, composé du nom du propriétaire
        suivi du tatouage
        """
        return "%s~%s" %(self.owner, self.tattoo())

    def tattoo(self):
        """
        Renvoie un tatouage présent sur la clé, quitte à le créer.
        @result un tatouage, supposément unique.
        """
        ff=self.getFirstFat()
        if ff:
            fatPath=ff.ensureMounted()
            tattooFileName=os.path.join(fatPath,".scolasync-tattoo")
            if os.path.exists(tattooFileName):
                tattoo_=open(tattooFileName,"r").read()
                # on vérifie par acquis de conscience, qu'il n'existe pas
                # un tatouage identique dans la base de données
                # s'il est déjà présent : on le change. Il faudrait
                # probablement aussi prévenir le prof !!!
                if tattoo_ in db.tattooList():
                    tattoo_="%12.2f" %time.time()
                    time.sleep(0.05)
            else:
                tattoo_="%12.2f" %time.time()
                time.sleep(0.05)
                outfile=open(tattooFileName,"w")
                outfile.write(tattoo_)
                outfile.close()
            return tattoo_
        else:
            return ""
    
    def readQuirks (self):
        """
        Lit un dictionnaire indexé par le noms de vendeurs et les noms de modèle
        pour associer à ces modèles particuliers un répertoire visible.
        voir la fonction visibleDir. Ce dictionnaire est dans le fichier
        /usr/share/scolasync/marques.py ou dans ${HOME}/.scolasync/marques.py,
        (sous Linux) cette dernière place étant prépondérante.
        """
        f1="/usr/share/scolasync/marques.py"
        f2=os.path.expanduser(markFileName)
        if os.path.exists(f2):
            f=f2
        else:
            f=f1
        result=eval(open(f,"r").read())
        return result
        
    def visibleDir(self):
        """
        Renvoie le répertoire particulier de la partition qui sera visible
        quand le baladeur est utilisé par son interface utilisateur. Ce
        répertoire peut varier selon les vendeurs et les modèles.
        """
        k=self.vendor+":"+self.model
        if k in self.visibleDirs.keys():
            return self.visibleDirs[k]
        else:
            return "."

    def headers(checkable=False,locale="C"):
        """
        Méthode statique
        renvoie des titres pour les items obtenus par __getitem__
        la deuxième colonne sera toujours le propriétaire
        @param checkable vrai si le premier en-tête correspond à une colonne de cases à cocher
        @param locale la locale, pour traduire les titres
        @return une liste de titres de colonnes
        """
        result=usbDisk.uDisk.headers(checkable, locale)
        ownerProp=QApplication.translate("uDisk","owner",None, QApplication.UnicodeUTF8)
        result.insert(1,ownerProp)
        return result

    def ownerByDb(self):
        """
        renvoie un nom de propriétaire dans tous les cas.
        """
        if self.owner != "":
            return self.owner
        else:
            s=db.readStudent(self.stickid, self.getFatUuid(), self.tattoo())
            if s != None:
                self.owner=s
                return s
            else:
                return QApplication.translate("Dialog","inconnu",None, QApplication.UnicodeUTF8)

    def __getitem__(self,n):
        """
        renvoie un élément de listage de données internes au disque
        Fait en sorte que la deuxième colonne soit toujours le propriétaire
        @param n un nombre
        @param checkable vrai si on doit renvoyer une propriété supplémentaire pour n==0
        @return si n==-1, renvoie self ; si checkable est vrai, renvoie un élément si n>0, et le drapeau self.selected si n==0 ; sinon un élément de façon ordinaire. Les noms des éléments sont dans la liste self.itemNames
        """
        propListe=usbDisk.uDisk.headers()
        if n == -1:
            return self # pour accéder à toutes les données d'une partition
        if self.checkable:
            if n==0:
                return self.selected
            elif n==1:
                return self.ownerByDb()
            elif n==2:
                return self.unNumberProp(0)
            else:
                return self.unNumberProp(n-1)
        else:
            if n==0:
                return self.unNumberProp(0)
            elif n==1:
                return self.ownerByDb()
            else:
                return self.unNumberProp(n)
    
    
    headers = staticmethod(headers)

    def ensureOwner(self):
        """
        Demande un nom de propriétaire si celui-ci n'est pas encore défini
        pour cette clé USB
        @return un nom de propriétaire si c'est un disque, sinon None
        """
        if self.getProp("device-is-drive") and self.isUsbDisk():
            if not db.knowsId(self.stickid, self.getFatUuid(), self.tattoo()) :
                prompt=QApplication.translate("Dialog","La cle %1<br>n'est pas identifiee, donnez le nom du proprietaire",None, QApplication.UnicodeUTF8).arg(self.stickid)
                text,ok = QInputDialog.getText(None,
                                               QApplication.translate("Dialog","Entrer un nom",None, QApplication.UnicodeUTF8),
                                               prompt)
                if ok and len(text)>0:
                    db.writeStudent(self.stickid, self.getFatUuid(), self.tattoo(), u"%s" %text.toUtf8())
        return db.readStudent(self.stickid, self.getFatUuid(), self.tattoo())
        
class Available(usbDisk.Available):
    """
    Une classe qui fournit une collection de disques USB connectés,
    avec leurs propriétaires. On a répliqué le code de la classe parente,
    ne sachant pas si le contructeur prendrait les uDisks dans le module
    courant ou dans le module parent. Pour éviter les confusion il faudrait
    peut-être faire une classe abstraite Available
    """
    def __init__(self, checkable=False, access="disk"):
        """
        @param checkable : vrai si on veut pouvoir cocher les disques de la
          collection. Faux par défaut.
        @param access définit le type d'accès souhaité. Par défaut, c'est "disk"
          c'est à dire qu'on veut la liste des disques USB. Autres valeurs
          possibles : "firstFat" pour les premières partitions vfat.
        """
        self.checkable=checkable
        self.access=access
        self.bus = dbus.SystemBus()
        proxy = self.bus.get_object("org.freedesktop.UDisks", 
                                    "/org/freedesktop/UDisks")
        iface = dbus.Interface(proxy, "org.freedesktop.UDisks")
        self.disks={}
        self.enumDev=iface.EnumerateDevices()
        ### récupération des disques usb dans le dictionnaire self.disks
        for path in self.enumDev:
            ud=uDisk(path, self.bus, checkable)
            if ud.isUsbDisk():
                self.disks[ud]=[]
                # cas des disques sans partitions
                if bool(ud.getProp("device-is-partition-table")) == False:
                    # la propriété "device-is-partition-table" est fausse,
                    # probablement qu'il y a un système de fichiers
                    self.disks[ud].append(ud)
        ### une deuxième passe pour récupérer et associer les partitions
        for path in self.enumDev:
            ud=uDisk(path, self.bus, checkable)
            for d in self.disks.keys():
                if ud.master() == d.path:
                    self.disks[d].append(ud)
        ### on s'assure que chaque disque a bien un propriétaire
        ### sinon on le demande
        self.getFirstFats() # premier passage, pour repérer chaque partition FAT
        for d in self.disks.keys():
            d.owner=d.ensureOwner()
        ### on fabrique la liste des premières partitions FAT,
        ### en positionnant les attributs de propriétaire
        self.firstFats = self.getFirstFats(setOwners=True)
        ### on monte les partitions si nécessaire
        if self.access=="firstFat":
            for p in self.firstFats:
                p.ensureMounted()