fix selection and bsod
[enigma2-plugins.git] / networkbrowser / src / AutoMount.py
1 # -*- coding: utf-8 -*-
2 # for localized messages
3 from __init__ import _
4 from re import compile as re_compile
5 from os import path as os_path, mkdir, rmdir
6
7 from enigma import eTimer
8 from Components.Console import Console
9 from Components.Harddisk import harddiskmanager #global harddiskmanager
10
11 from xml.etree.cElementTree import parse as cet_parse
12
13 XML_FSTAB = "/etc/enigma2/automounts.xml"
14
15 class AutoMount():
16         """Manages Mounts declared in a XML-Document."""
17         def __init__(self):
18                 self.automounts = {}
19                 self.restartConsole = Console()
20                 self.MountConsole = Console()
21                 self.removeConsole = Console()
22                 self.activeMountsCounter = 0
23                 # Initialize Timer
24                 self.callback = None
25                 self.timer = eTimer()
26                 self.timer.callback.append(self.mountTimeout)
27
28                 self.getAutoMountPoints()
29
30         def getAutoMountPoints(self, callback = None):
31                 # Initialize mounts to empty list
32                 automounts = []
33                 self.automounts = {}
34                 self.activeMountsCounter = 0
35
36                 if not os_path.exists(XML_FSTAB):
37                         return
38                 tree = cet_parse(XML_FSTAB).getroot()
39
40                 def getValue(definitions, default):
41                         # Initialize Output
42                         ret = ""
43                         # How many definitions are present
44                         Len = len(definitions)
45                         return Len > 0 and definitions[Len-1].text or default
46                 # Config is stored in "mountmanager" element
47                 # Read out NFS Mounts
48                 for nfs in tree.findall("nfs"):
49                         for mount in nfs.findall("mount"):
50                                 data = { 'isMounted': False, 'active': False, 'ip': False, 'sharename': False, 'sharedir': False, 'username': False, 'password': False, 'mounttype' : False, 'options' : False }
51                                 try:
52                                         data['mounttype'] = 'nfs'.encode("UTF-8")
53                                         data['active'] = getValue(mount.findall("active"), False).encode("UTF-8")
54                                         if data["active"] == 'True' or data["active"] == True:
55                                                 self.activeMountsCounter +=1
56                                         data['ip'] = getValue(mount.findall("ip"), "192.168.0.0").encode("UTF-8")
57                                         data['sharedir'] = getValue(mount.findall("sharedir"), "/exports/").encode("UTF-8")
58                                         data['sharename'] = getValue(mount.findall("sharename"), "MEDIA").encode("UTF-8")
59                                         data['options'] = getValue(mount.findall("options"), "rw,nolock").encode("UTF-8")
60                                         print "NFSMOUNT",data
61                                         self.automounts[data['sharename']] = data
62                                 except Exception, e:
63                                         print "[MountManager] Error reading Mounts:", e
64                         # Read out CIFS Mounts
65                 for nfs in tree.findall("cifs"):
66                         for mount in nfs.findall("mount"):
67                                 data = { 'isMounted': False, 'active': False, 'ip': False, 'sharename': False, 'sharedir': False, 'username': False, 'password': False, 'mounttype' : False, 'options' : False }
68                                 try:
69                                         data['mounttype'] = 'cifs'.encode("UTF-8")
70                                         data['active'] = getValue(mount.findall("active"), False).encode("UTF-8")
71                                         if data["active"] == 'True' or data["active"] == True:
72                                                 self.activeMountsCounter +=1
73                                         data['ip'] = getValue(mount.findall("ip"), "192.168.0.0").encode("UTF-8")
74                                         data['sharedir'] = getValue(mount.findall("sharedir"), "/exports/").encode("UTF-8")
75                                         data['sharename'] = getValue(mount.findall("sharename"), "MEDIA").encode("UTF-8")
76                                         data['options'] = getValue(mount.findall("options"), "rw,nolock").encode("UTF-8")
77                                         data['username'] = getValue(mount.findall("username"), "guest").encode("UTF-8")
78                                         data['password'] = getValue(mount.findall("password"), "").encode("UTF-8")
79                                         print "CIFSMOUNT",data
80                                         self.automounts[data['sharename']] = data
81                                 except Exception, e:
82                                         print "[MountManager] Error reading Mounts:", e
83
84                 print "[AutoMount.py] -getAutoMountPoints:self.automounts -->",self.automounts
85                 if len(self.automounts) == 0:
86                         print "[AutoMount.py] self.automounts without mounts",self.automounts
87                         if callback is not None:
88                                 callback(True)
89                 else:
90                         for sharename, sharedata in self.automounts.items():
91                                 self.CheckMountPoint(sharedata, callback)
92
93         def CheckMountPoint(self, data, callback):
94                 print "[AutoMount.py] CheckMountPoint"
95                 print "[AutoMount.py] activeMounts:--->",self.activeMountsCounter
96                 if not self.MountConsole:
97                         self.MountConsole = Console()
98
99                 self.command = None
100                 if self.activeMountsCounter == 0:
101                         print "self.automounts without active mounts",self.automounts
102                         if data['active'] == 'False' or data['active'] is False:
103                                 path = '/media/net/'+ data['sharename']
104                                 umountcmd = 'umount -f '+ path
105                                 print "[AutoMount.py] UMOUNT-CMD--->",umountcmd
106                                 self.MountConsole.ePopen(umountcmd, self.CheckMountPointFinished, [data, callback])
107                 else:
108                         if data['active'] == 'False' or data['active'] is False:
109                                 path = '/media/net/'+ data['sharename']
110                                 self.command = 'umount -f '+ path
111
112                         if data['active'] == 'True' or data['active'] is True:
113                                 path = '/media/net/'+ data['sharename']
114                                 if os_path.exists(path) is False:
115                                         mkdir(path)
116                                 tmpsharedir = data['sharedir'].replace(" ", "\\ ")
117                                 if tmpsharedir[-1:] == "$":
118                                         tmpdir = tmpsharedir.replace("$", "\\$")
119                                         tmpsharedir = tmpdir
120
121                                 if data['mounttype'] == 'nfs':
122                                         if not os_path.ismount(path):
123                                                 tmpcmd = 'mount -t nfs -o tcp,'+ data['options'] +',rsize=8192,wsize=8192 ' + data['ip'] + ':' + tmpsharedir + ' ' + path
124                                                 self.command = tmpcmd.encode("UTF-8")
125
126                                 if data['mounttype'] == 'cifs':
127                                         if not os_path.ismount(path):
128                                                 tmpusername = data['username'].replace(" ", "\\ ")
129                                                 tmpcmd = 'mount -t cifs -o '+ data['options'] +',iocharset=utf8,rsize=8192,wsize=8192,username='+ tmpusername + ',password='+ data['password'] + ' //' + data['ip'] + '/' + tmpsharedir + ' ' + path
130                                                 self.command = tmpcmd.encode("UTF-8")
131
132                         if self.command is not None:
133                                 print "[AutoMount.py] U/MOUNTCMD--->",self.command
134                                 self.MountConsole.ePopen(self.command, self.CheckMountPointFinished, [data, callback])
135                         else:
136                                 self.CheckMountPointFinished(None,None, [data, callback])
137
138         def CheckMountPointFinished(self, result, retval, extra_args):
139                 print "[AutoMount.py] CheckMountPointFinished"
140                 print "[AutoMount.py] result",result
141                 print "[AutoMount.py] retval",retval
142                 (data, callback ) = extra_args
143                 print "LEN",len(self.MountConsole.appContainers)
144                 path = '/media/net/'+ data['sharename']
145                 print "PATH im CheckMountPointFinished",path
146                 if os_path.exists(path):
147                         if os_path.ismount(path):
148                                 if self.automounts.has_key(data['sharename']):
149                                         self.automounts[data['sharename']]['isMounted'] = True
150                                         desc = data['sharename']
151                                         harddiskmanager.addMountedPartition(path, desc)
152                         else:
153                                 if self.automounts.has_key(data['sharename']):
154                                         self.automounts[data['sharename']]['isMounted'] = False
155                                 if os_path.exists(path):
156                                         if not os_path.ismount(path):
157                                                 rmdir(path)
158                                                 harddiskmanager.removeMountedPartition(path)
159
160                 if self.MountConsole:
161                         if len(self.MountConsole.appContainers) == 0:
162                                 if callback is not None:
163                                         self.callback = callback
164                                         self.timer.startLongTimer(10)
165
166         def mountTimeout(self):
167                 self.timer.stop()
168                 if self.MountConsole:
169                         if len(self.MountConsole.appContainers) == 0:
170                                 print "self.automounts after mounting",self.automounts
171                                 if self.callback is not None:
172                                         self.callback(True)
173
174         def getMountsList(self):
175                 return self.automounts
176
177         def getMountsAttribute(self, mountpoint, attribute):
178                 if self.automounts.has_key(mountpoint):
179                         if self.automounts[mountpoint].has_key(attribute):
180                                 return self.automounts[mountpoint][attribute]
181                 return None
182
183         def setMountsAttribute(self, mountpoint, attribute, value):
184                 print "setting for mountpoint", mountpoint, "attribute", attribute, " to value", value
185                 if self.automounts.has_key(mountpoint):
186                         self.automounts[mountpoint][attribute] = value
187
188         def writeMountsConfig(self):
189                 # Generate List in RAM
190                 list = ['<?xml version="1.0" ?>\n<mountmanager>\n']
191
192                 for sharename, sharedata in self.automounts.items():
193                         if sharedata['mounttype'] == 'nfs':
194                                 list.append('<nfs>\n')
195                                 list.append(' <mount>\n')
196                                 list.append(''.join(["  <active>", str(sharedata['active']), "</active>\n"]))
197                                 list.append(''.join(["  <ip>", sharedata['ip'], "</ip>\n"]))
198                                 list.append(''.join(["  <sharename>", sharedata['sharename'], "</sharename>\n"]))
199                                 list.append(''.join(["  <sharedir>", sharedata['sharedir'], "</sharedir>\n"]))
200                                 list.append(''.join(["  <options>", sharedata['options'], "</options>\n"]))
201                                 list.append(' </mount>\n')
202                                 list.append('</nfs>\n')
203
204                         if sharedata['mounttype'] == 'cifs':
205                                 list.append('<cifs>\n')
206                                 list.append(' <mount>\n')
207                                 list.append(''.join(["  <active>", str(sharedata['active']), "</active>\n"]))
208                                 list.append(''.join(["  <ip>", sharedata['ip'], "</ip>\n"]))
209                                 list.append(''.join(["  <sharename>", sharedata['sharename'], "</sharename>\n"]))
210                                 list.append(''.join(["  <sharedir>", sharedata['sharedir'], "</sharedir>\n"]))
211                                 list.append(''.join(["  <options>", sharedata['options'], "</options>\n"]))
212                                 list.append(''.join(["  <username>", sharedata['username'], "</username>\n"]))
213                                 list.append(''.join(["  <password>", sharedata['password'], "</password>\n"]))
214                                 list.append(' </mount>\n')
215                                 list.append('</cifs>\n')
216
217                 # Close Mountmanager Tag
218                 list.append('</mountmanager>\n')
219
220                 # Try Saving to Flash
221                 file = None
222                 try:
223                         file = open(XML_FSTAB, "w")
224                         file.writelines(list)
225                 except Exception, e:
226                         print "[AutoMount.py] Error Saving Mounts List:", e
227                 finally:
228                         if file is not None:
229                                 file.close()
230
231         def stopMountConsole(self):
232                 if self.MountConsole is not None:
233                         self.MountConsole = None
234
235         def removeMount(self, mountpoint, callback = None):
236                 print "[AutoMount.py] removing mount: ",mountpoint
237                 self.newautomounts = {}
238                 for sharename, sharedata in self.automounts.items():
239                         if sharename is not mountpoint.strip():
240                                 self.newautomounts[sharename] = sharedata
241                 self.automounts.clear()
242                 self.automounts = self.newautomounts
243                 if not self.removeConsole:
244                         self.removeConsole = Console()
245                 path = '/media/net/'+ mountpoint
246                 umountcmd = 'umount -f '+ path
247                 print "[AutoMount.py] UMOUNT-CMD--->",umountcmd
248                 self.removeConsole.ePopen(umountcmd, self.removeMountPointFinished, [path, callback])
249
250         def removeMountPointFinished(self, result, retval, extra_args):
251                 print "[AutoMount.py] removeMountPointFinished"
252                 print "[AutoMount.py] result",result
253                 print "[AutoMount.py] retval",retval
254                 (path, callback ) = extra_args
255                 if os_path.exists(path):
256                         if not os_path.ismount(path):
257                                 rmdir(path)
258                                 harddiskmanager.removeMountedPartition(path)
259
260                 if self.removeConsole:
261                         if len(self.removeConsole.appContainers) == 0:
262                                 if callback is not None:
263                                         self.callback = callback
264                                         self.timer.startLongTimer(10)
265
266
267 # currently unused autofs support stuff
268 """
269 class AutoMount_Unused:
270         def __init__(self):
271                 self.automounts = {}
272                 self.restartConsole = Console()
273                 self.MountConsole = Console()
274                 self.activeMountsCounter = 0
275                 self.getAutoMountPoints()
276
277         # helper function
278         def regExpMatch(self, pattern, string):
279                 if string is None:
280                         return None
281                 try:
282                         return pattern.search(string).group()
283                 except AttributeError:
284                         None
285
286         # helper function to convert ips from a sring to a list of ints
287         def convertIP(self, ip):
288                 strIP = ip.split('.')
289                 ip = []
290                 for x in strIP:
291                         ip.append(int(x))
292                 return ip
293
294
295         def getAutoMountPoints(self, callback = None):
296                 print "[AutoMount.py] getAutoMountPoints"
297                 automounts = []
298                 self.automounts = {}
299                 self.activeMountsCounter = 0
300                 fp = None
301                 try:
302                         fp = file('/etc/auto.network', 'r')
303                         automounts = fp.readlines()
304                         fp.close()
305                 except:
306                         print "[AutoMount.py] /etc/auto.network - opening failed"
307
308                 ipRegexp = '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
309                 cifsIpLinePattern = re_compile('://' + ipRegexp + '/')
310                 nfsIpLinePattern = re_compile(ipRegexp + ':/')
311                 ipPattern = re_compile(ipRegexp)
312                 for line in automounts:
313                         print "[AutoMount.py] Line:",line
314                         split = line.strip().split('\t',2)
315                         if split[0] == '*':
316                                 continue
317                         if len(split) == 2 and split[0][0] == '*':
318                                 continue
319                         if len(split) == 3:
320                                 data = { 'isMounted': False, 'active': False, 'ip': False, 'sharename': False, 'sharedir': False, 'username': False, 'password': False, 'mounttype' : False, 'options' : False }
321                                 currshare = ""
322                                 if split[0][0] == '#':
323                                         data['active'] = False
324                                         currshare = split[0][1:]
325                                         data['sharename'] = currshare
326                                 else:
327                                         data['active'] = True
328                                         self.activeMountsCounter +=1
329                                         currshare = split[0]
330                                         data['sharename'] = currshare
331                                 if '-fstype=cifs' in split[1]:
332                                         data['mounttype'] = 'cifs'
333                                         options = split[1][split[1].index('-fstype=cifs')+13 : split[1].index(',user=')]
334                                         if options is not None:
335                                                 data['options'] = options
336                                         if 'user=' in split[1]:
337                                                 username = split[1][split[1].index(',user=')+6 : split[1].index(',pass=')]
338                                                 if username is not None:
339                                                         data['username'] = username
340                                         if 'pass=' in split[1]:
341                                                 password = split[1][split[1].index(',pass=')+6 : ]
342                                                 if password is not None:
343                                                         data['password'] = password
344                                         ip = self.regExpMatch(ipPattern, self.regExpMatch(cifsIpLinePattern, split[2]))
345                                         if ip is not None:
346                                                 data['ip'] = ip
347                                         sharedir = split[2][split[2].index(ip)+len(ip)+1 : ]
348                                         if sharedir is not None:
349                                                 tmpsharedir = sharedir.replace("\\ ", " ")
350                                                 if tmpsharedir[-2:] == "\$":
351                                                         tmpdir = tmpsharedir.replace("\$", "$")
352                                                         tmpsharedir = tmpdir
353                                                 data['sharedir'] = tmpsharedir
354
355                                 if '-fstype=nfs' in split[1]:
356                                         data['mounttype'] = 'nfs'
357                                         options = split[1][split[1].index('-fstype=nfs')+12 : ]
358                                         if options is not None:
359                                                 data['options'] = options
360                                         ip = self.regExpMatch(ipPattern, self.regExpMatch(nfsIpLinePattern, split[2]))
361                                         if ip is not None:
362                                                 data['ip'] = ip
363                                         sharedir = split[2][split[2].index(ip)+len(ip)+1 : ]
364                                         if sharedir is not None:
365                                                 tmpsharedir = sharedir.replace("\\ ", " ")
366                                                 if tmpsharedir[-2:] == "\$":
367                                                         tmpdir = tmpsharedir.replace("\$", "$")
368                                                         tmpsharedir = tmpdir
369                                                 data['sharedir'] = tmpsharedir
370
371                                 self.automounts[currshare] = data
372                 if len(self.automounts) == 0:
373                         print "[AutoMount.py] self.automounts without mounts",self.automounts
374                         if callback is not None:
375                                 callback(True)
376                 else:
377                         #print "automounts",self.automounts
378                         for sharename, sharedata in self.automounts.items():
379                                 self.CheckMountPoint(sharedata, callback)
380
381         def CheckMountPoint(self, data, callback):
382                 print "[AutoMount.py] CheckMountPoint"
383                 if not self.MountConsole:
384                         self.MountConsole = Console()
385                 print "[AutoMount.py] activeMounts--->",self.activeMountsCounter
386                 if self.activeMountsCounter == 0:
387                 #if data['active'] is False:
388                         if self.MountConsole:
389                                 if len(self.MountConsole.appContainers) == 0:
390                                         print "self.automounts without active mounts",self.automounts
391                                         if callback is not None:
392                                                 callback(True)
393                 else:
394                         if data['mounttype'] == 'nfs' and data['active'] is True:
395                                 path = '/tmp/'+ data['sharename']
396                                 if os_path.exists(path) is False:
397                                         mkdir(path)
398                                 tmpsharedir = data['sharedir'].replace(" ", "\\ ")
399                                 if tmpsharedir[-1:] == "$":
400                                         tmpdir = tmpsharedir.replace("$", "\\$")
401                                         tmpsharedir = tmpdir
402                                 nfscmd = 'mount -o nolock -t nfs ' + data['ip'] + ':' + tmpsharedir + ' ' + path
403                                 print "[AutoMount.py] nfsscmd--->",nfscmd
404                                 self.MountConsole.ePopen(nfscmd, self.CheckMountPointFinished, [data, callback])
405                         if data['mounttype'] == 'cifs' and data['active'] is True:
406                                 self.activeMountsCounter +=1
407                                 path = '/tmp/'+ data['sharename']
408                                 if os_path.exists(path) is False:
409                                         mkdir(path)
410                                 tmpsharedir = data['sharedir'].replace(" ", "\\ ")
411                                 if tmpsharedir[-1:] == "$":
412                                         tmpdir = tmpsharedir.replace("$", "\\$")
413                                         tmpsharedir = tmpdir
414                                 cifscmd = 'mount -t cifs -o rw,username='+ data['username'] + ',password='+ data['password'] + ' //' + data['ip'] + '/' + tmpsharedir + ' ' + path
415                                 print "[AutoMount.py] cifscmd--->",cifscmd
416                                 self.MountConsole.ePopen(cifscmd, self.CheckMountPointFinished, [data, callback])
417
418         def CheckMountPointFinished(self, result, retval, extra_args):
419                 print "[AutoMount.py] CheckMountPointFinished"
420                 (data, callback ) = extra_args
421                 path = '/tmp/'+ data['sharename']
422                 if not self.MountConsole:
423                         self.MountConsole = Console()
424                 if os_path.ismount(path):
425                         if self.automounts.has_key(data['sharename']):
426                                 self.automounts[data['sharename']]['isMounted'] = True
427                 else:
428                         if self.automounts.has_key(data['sharename']):
429                                 self.automounts[data['sharename']]['isMounted'] = False
430                 umountcmd = 'umount /tmp/'+ data['sharename']
431                 self.MountConsole.ePopen(umountcmd, self.CleanMountPointFinished, [data, callback])
432
433         def CleanMountPointFinished(self, result, retval, extra_args):
434                 print "[AutoMount.py] CleanMountPointFinished"
435                 (data, callback ) = extra_args
436                 path = '/tmp/'+ data['sharename']
437                 if os_path.exists(path):
438                         rmdir(path)
439                 if self.MountConsole:
440                         if len(self.MountConsole.appContainers) == 0:
441                                 print "self.automounts after mountcheck",self.automounts
442                                 if callback is not None:
443                                         callback(True)
444
445         def getMountsList(self):
446                 return self.automounts
447
448         def getMountsAttribute(self, mountpoint, attribute):
449                 if self.automounts.has_key(mountpoint):
450                         if self.automounts[mountpoint].has_key(attribute):
451                                 return self.automounts[mountpoint][attribute]
452                 return None
453
454         def setMountsAttribute(self, mountpoint, attribute, value):
455                 print "setting for mountpoint", mountpoint, "attribute", attribute, " to value", value
456                 if self.automounts.has_key(mountpoint):
457                         self.automounts[mountpoint][attribute] = value
458
459         def removeMount(self, mountpoint):
460                 self.newautomounts = {}
461                 #self.automounts[currshare] = data
462                 print "[AutoMount.py] removing mount: ",mountpoint
463                 for sharename, sharedata in self.automounts.items():
464                         if sharename is not mountpoint.strip():
465                                 self.newautomounts[sharename] = sharedata
466                 self.automounts.clear()
467                 self.automounts = self.newautomounts
468
469         def writeMountsConfig(self):
470                 fp = file('/etc/auto.network', 'w')
471                 fp.write("# automatically generated by enigma 2\n# do NOT change manually!\n\n")
472                 for sharename, sharedata in self.automounts.items():
473                         if sharedata['mounttype'] == 'nfs':
474                                 if sharedata['active'] is False:
475                                         fp.write("#" + sharedata['sharename'] + "\t")
476                                 else:
477                                         fp.write( sharedata['sharename'] + "\t")
478                                 fp.write( "-fstype=nfs," + sharedata['options'] + "\t")
479                                 fp.write(sharedata['ip'] + ":")
480                                 tmpsharedir = sharedata['sharedir'].replace(" ", "\\ ")
481                                 if tmpsharedir[-1:] == "$":
482                                         tmpdir = tmpsharedir.replace("$", "\\$")
483                                         tmpsharedir = tmpdir
484                                 fp.write( tmpsharedir + "\n")
485                         if sharedata['mounttype'] == 'cifs':
486                                 if sharedata['active'] is False:
487                                         fp.write("#" + sharedata['sharename'] + "\t")
488                                 else:
489                                         fp.write( sharedata['sharename'] + "\t")
490                                 fp.write( "-fstype=cifs," + sharedata['options'] + ",")
491                                 fp.write( "user=" + sharedata['username'] + ",")
492                                 fp.write( "pass=" + sharedata['password'] + "\t://")
493                                 fp.write(sharedata['ip'] + "/")
494                                 tmpsharedir = sharedata['sharedir'].replace(" ", "\\ ")
495                                 if tmpsharedir[-1:] == "$":
496                                         tmpdir = tmpsharedir.replace("$", "\\$")
497                                         tmpsharedir = tmpdir
498                                 fp.write( tmpsharedir + "\n")
499                 fp.write("\n")
500                 fp.close()
501
502         def restartAutoFS(self,callback = None):
503                 print "[AutoMount.py] restartAutoFS "
504                 self.restartConsole = Console()
505                 self.commands = []
506                 self.commands.append("/etc/init.d/autofs stop")
507                 self.commands.append("killall -9 automount")
508                 self.commands.append("rm -rf /var/run/autofs")
509                 self.commands.append("/etc/init.d/autofs start")
510                 self.restartConsole.eBatch(self.commands, self.restartAutoFSFinished, callback, debug=True)
511
512         def restartAutoFSFinished(self,extra_args):
513                 print "[AutoMount.py] restartAutoFSFinished "
514                 ( callback ) = extra_args
515                 if callback is not None:
516                         callback(True)
517
518         def stopMountConsole(self):
519                 if self.MountConsole is not None:
520                         self.MountConsole = None """
521
522 iAutoMount = AutoMount()
523