2 * $Id: enigma_mount.cpp,v 1.64 2007/02/18 18:00:57 digi_casi Exp $
4 * (C) 2005, 2007 by digi_casi <digi_casi@tuxbox.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #ifdef ENABLE_EXPERT_WEBIF
29 #include <sys/mount.h>
36 #include <lib/base/estring.h>
37 #include <lib/gui/enumber.h>
38 #include <configfile.h>
39 #include <enigma_dyn_utils.h>
40 #include <enigma_mount.h>
41 #include <configfile.h>
42 #include <enigma_main.h>
46 eMountMgr
*eMountMgr::instance
;
48 eMountPoint::~eMountPoint()
52 eMountPoint::eMountPoint(t_mount pmp
)
57 void eMountPoint::save(FILE *out
, int pid
)
60 fprintf(out
,"ip_%d=%d.%d.%d.%d\n", mp
.id
, mp
.ip
[0], mp
.ip
[1], mp
.ip
[2], mp
.ip
[3]);
61 fprintf(out
,"fstype_%d=%d\n", mp
.id
, mp
.fstype
);
62 fprintf(out
,"localdir_%d=%s\n", mp
.id
, mp
.localDir
.c_str());
63 fprintf(out
,"mountdir_%d=%s\n", mp
.id
, mp
.mountDir
.c_str());
64 fprintf(out
,"username_%d=%s\n", mp
.id
, mp
.userName
.c_str());
65 fprintf(out
,"password_%d=%s\n", mp
.id
, mp
.password
.c_str());
66 fprintf(out
,"options_%d=%s\n", mp
.id
, mp
.options
.c_str());
67 fprintf(out
,"description_%d=%s\n", mp
.id
, mp
.description
.c_str());
68 fprintf(out
,"automount_%d=%d\n", mp
.id
, mp
.automount
);
72 bool eMountPoint::fileSystemIsSupported(eString fsname
)
76 fsname
= fsname
.upper();
77 std::ifstream
in("/proc/filesystems", std::ifstream::in
);
81 if (found
= (s
.upper() == fsname
))
89 bool eMountPoint::isMounted()
96 std::stringstream tmp
;
99 in
.open("/proc/mounts", std::ifstream::in
);
100 while (getline(in
, buffer
, '\n'))
102 mountDev
= mountOn
= mountType
= "";
104 tmp
>> mountDev
>> mountOn
>> mountType
;
106 if (found
= isIdentical(mountOn
, mountDev
))
113 bool eMountPoint::isIdentical(eString mountOn
, eString mountDev
)
117 if (mountOn
== mp
.localDir
)
122 found
= (eString().sprintf("%d.%d.%d.%d:%s", mp
.ip
[0], mp
.ip
[1], mp
.ip
[2], mp
.ip
[3], mp
.mountDir
.c_str()) == mountDev
);
126 found
= (eString().sprintf("//%d.%d.%d.%d/%s", mp
.ip
[0], mp
.ip
[1], mp
.ip
[2], mp
.ip
[3], mp
.mountDir
.c_str()).upper() == mountDev
.upper());
129 found
= ((mountOn
== mp
.localDir
) && (mountDev
== mp
.mountDir
) && (mp
.ip
[0] == 0) && (mp
.ip
[1] == 0) && (mp
.ip
[2] == 0) && (mp
.ip
[3] == 0));
138 int eMountPoint::mount()
148 if (access(mp
.localDir
.c_str(), R_OK
) == -1)
149 system(eString("mkdir " + mp
.localDir
).c_str());
150 if (access(mp
.localDir
.c_str(), R_OK
) == 0)
152 ip
.sprintf("%d.%d.%d.%d", mp
.ip
[0], mp
.ip
[1], mp
.ip
[2], mp
.ip
[3]);
156 if (fileSystemIsSupported("nfs"))
158 cmd
= "mount -t nfs ";
159 cmd
+= ip
+ ":" + mp
.mountDir
+ " " + mp
.localDir
;
160 cmd
+= (mp
.options
) ? (" -o " + mp
.options
) : "";
163 rc
= -4; //NFS filesystem not supported
166 if (fileSystemIsSupported("cifs"))
168 cmd
= "mount -t cifs //";
169 cmd
+= ip
+ "/" + mp
.mountDir
+ " " + mp
.localDir
+ " -o user=";
170 cmd
+= (mp
.userName
) ? mp
.userName
: "anonymous";
171 cmd
+= (mp
.password
) ? (",pass=" + mp
.password
) : "";
172 cmd
+= ",unc=//" + ip
+ "/" + mp
.mountDir
;
173 cmd
+= (mp
.options
) ? ("," + mp
.options
) : "";
176 rc
= -3; //CIFS filesystem not supported
179 cmd
= "mount " + mp
.mountDir
+ " " + mp
.localDir
;
182 if (fileSystemIsSupported("smbfs"))
185 cmd
+= "//" + ip
+ "/" + mp
.mountDir
;
186 cmd
+= " " + ((mp
.password
) ? mp
.password
: "guest");
187 cmd
+= " -U " + ((mp
.userName
) ? mp
.userName
: "guest");
189 cmd
+= " -c \"mount " + mp
.localDir
+ "\"";
192 rc
= -3; //SMBFS filesystem not supported
198 eDebug("[ENIGMA_MOUNT] mounting: %s", cmd
.c_str());
203 eDebug("[ENIGMA_MOUNT] fork failed!");
208 for (unsigned int i
= 0; i
< 90; ++i
)
211 rc
= system(cmd
.c_str());
212 if (mp
.localDir
== "/hdd")
213 system("sleep 5 && wget -O /dev/null http://127.0.0.1/cgi-bin/reloadRecordings&");
221 rc
= -10; //couldn't create local dir
224 rc
= -2; //local dir is already a mountpoint
227 rc
= -1; //mount point is already mounted
231 -1: "Mountpoint is already mounted.";
232 -2: "Local directory is already used as mount point.";
233 -3: "CIFS is not supported.";
234 -4: "NFS is not supported.";
235 -5: "Mount failed (timeout).";
236 -10: "Unable to create mount dir.";
240 int eMountPoint::unmount()
243 int rc
= umount2(mp
.localDir
.c_str(), MNT_FORCE
);
244 if (mp
.localDir
== "/hdd")
245 system("sleep 5 && wget -O /dev/null http://127.0.0.1/cgi-bin/reloadRecordings&");
249 eMountMgr::eMountMgr()
257 eMountMgr::~eMountMgr()
263 int eMountMgr::addMountPoint(t_mount pmp
)
265 pmp
.id
= mountPoints
.size();
266 mountPoints
.push_back(eMountPoint(pmp
));
271 t_mount
eMountMgr::getMountPointData(int pid
)
274 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
276 if (mp_it
->mp
.id
== pid
)
285 void eMountMgr::changeMountPoint(int pid
, t_mount pmp
)
288 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
290 if (mp_it
->mp
.id
== pid
)
292 if (mp_it
->mp
.mounted
)
294 rc
= mp_it
->unmount();
307 void eMountMgr::removeMountPoint(int id
)
309 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
311 if (mp_it
->mp
.id
== id
)
313 mountPoints
.erase(mp_it
);
320 int eMountMgr::mountMountPoint(int id
)
323 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
325 if (mp_it
->mp
.id
== id
)
334 int eMountMgr::mountMountPoint(eString localDir
)
337 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
339 if (mp_it
->mp
.localDir
== localDir
)
341 if (!mp_it
->mp
.mounted
)
349 bool eMountMgr::isMountPointMounted(eString localDir
)
352 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
354 if (mp_it
->mp
.localDir
== localDir
)
356 if (mp_it
->mp
.mounted
)
364 int eMountMgr::unmountMountPoint(int id
)
367 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
369 if (mp_it
->mp
.id
== id
)
371 rc
= mp_it
->unmount();
378 int eMountMgr::selectMovieSource(int id
)
381 eDebug("[ENIGMA_MOUNT] selectMovieSource id: %d", id
);
382 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
384 if ((mp_it
->mp
.localDir
== "/hdd") && mp_it
->mp
.mounted
)
386 eDebug("[ENIGMA_MOUNT] selectMovieSource unmounting: %s", mp_it
->mp
.mountDir
.c_str());
387 rc
= mp_it
->unmount();
391 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
393 if (mp_it
->mp
.id
== id
)
395 eDebug("[ENIGMA_MOUNT] selectMovieSource mounting: %s", mp_it
->mp
.mountDir
.c_str());
396 mp_it
->mp
.localDir
= "/hdd"; // force /hdd
403 eDebug("[ENIGMA_MOUNT] selectMovieSource rc: %d", rc
);
407 void eMountMgr::automountMountPoints(void)
409 eDebug("[ENIGMA_MOUNT] automountMountPoints...");
410 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
412 eDebug("[ENIGMA_MOUNT] automountMountPoints: %s - %d", mp_it
->mp
.mountDir
.c_str(), mp_it
->mp
.automount
);
413 if (mp_it
->mp
.automount
== 1)
415 eDebug("[ENIGMA_MOUNT] automounting %s", mp_it
->mp
.mountDir
.c_str());
421 void eMountMgr::unmountAllMountPoints(void)
423 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
425 if (mp_it
->mp
.mounted
== 1 && mp_it
->mp
.automount
== 1)
430 eString
eMountMgr::listMountPoints(eString skelleton
)
432 eString result
, mountStatus
, action
;
434 if (mountPoints
.size() > 0)
435 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
437 eString tmp
= skelleton
;
438 if (mp_it
->mp
.mounted
)
440 mountStatus
= "<img src=\"on.gif\" alt=\"online\" border=0>";
441 action
= button(75, "Unmount", RED
, "javascript:unmountMountPoint('" + eString().sprintf("%d", mp_it
->mp
.id
) + "')", "#FFFFFF");
445 mountStatus
= "<img src=\"off.gif\" alt=\"offline\" border=0>";
446 action
= button(75, "Mount", BLUE
, "javascript:mountMountPoint('" + eString().sprintf("%d", mp_it
->mp
.id
) + "')", "#FFFFFF");
448 tmp
.strReplace("#ACTIONBUTTON#", action
);
449 tmp
.strReplace("#CHANGEID#", eString().sprintf("%d", mp_it
->mp
.id
));
450 tmp
.strReplace("#DELETEID#", eString().sprintf("%d", mp_it
->mp
.id
));
451 tmp
.strReplace("#MOUNTED#", mountStatus
);
452 tmp
.strReplace("#LDIR#", mp_it
->mp
.localDir
);
453 tmp
.strReplace("#MDIR#", mp_it
->mp
.mountDir
);
454 tmp
.strReplace("#IP#", eString().sprintf("%3d.%3d.%3d.%3d", mp_it
->mp
.ip
[0], mp_it
->mp
.ip
[1], mp_it
->mp
.ip
[2], mp_it
->mp
.ip
[3]));
455 tmp
.strReplace("#USER#", mp_it
->mp
.userName
);
456 tmp
.strReplace("#PW#", mp_it
->mp
.password
);
457 eString type
= "DEV";
458 if (mp_it
->mp
.fstype
== 0)
461 if (mp_it
->mp
.fstype
== 1)
464 if (mp_it
->mp
.fstype
== 3)
466 tmp
.strReplace("#FSTYPE#", type
);
467 tmp
.strReplace("#AUTO#", eString().sprintf("%d", mp_it
->mp
.automount
));
468 tmp
.strReplace("#OPTIONS#", mp_it
->mp
.options
);
469 tmp
.strReplace("#DESCRIPTION#", mp_it
->mp
.description
);
470 result
+= tmp
+ "\n";
473 result
= "<tr><td>No mount points available.</td></tr>";
478 eString
eMountMgr::listMovieSources()
482 if (mountPoints
.size() > 0)
483 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
485 if (mp_it
->mp
.localDir
== "/hdd")
487 tmp
= "<option #SEL# value=\"" + eString().sprintf("%d", mp_it
->mp
.id
) + "\">" + ((mp_it
->mp
.description
) ? mp_it
->mp
.description
: mp_it
->mp
.mountDir
) + "</option>";
488 if (mp_it
->mp
.mounted
)
489 tmp
.strReplace("#SEL#", "selected");
491 tmp
.strReplace("#SEL#", "");
493 result
+= tmp
+ "\n";
497 result
= "<option selected value=\"0\">No movie source available.</option>";
499 if (result
.find("selected") == eString::npos
)
500 result
= "<option selected value=\"0\">No movie source selected.</option>\n" + result
;
505 void eMountMgr::addMountedFileSystems()
512 std::stringstream tmp
;
516 in
.open("/proc/mounts", std::ifstream::in
);
517 while (getline(in
, buffer
, '\n'))
519 mountDev
= mountOn
= mountType
= "";
521 tmp
>> mountDev
>> mountOn
>> mountType
;
524 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
526 if (found
= mp_it
->isIdentical(mountOn
, mountDev
))
532 //add the mount point
533 if (mountType
.upper() == "NFS")
535 if (mountDev
.find("/dev") != eString::npos
)
537 sscanf(mountDev
.c_str(), "%d.%d.%d.%d:%*s", &mp
.ip
[0], &mp
.ip
[1], &mp
.ip
[2], &mp
.ip
[3]);
538 mp
.mountDir
= getRight(mountDev
, ':');
539 mp
.localDir
= mountOn
;
547 mp
.id
= -1; //don't care
552 if (mountType
.upper() == "CIFS")
554 sscanf(mountDev
.c_str(), "//%d.%d.%d.%d/%*s", &mp
.ip
[0], &mp
.ip
[1], &mp
.ip
[2], &mp
.ip
[3]);
555 mountDev
= mountDev
.right(mountDev
.length() - 2); //strip off leading slashes
556 mp
.mountDir
= getRight(mountDev
, '/');
557 mp
.localDir
= mountOn
;
565 mp
.id
= -1; //don't care
569 if (mountType
.upper() == "SMBFS")
571 sscanf(mountDev
.c_str(), "//%d.%d.%d.%d/%*s", &mp
.ip
[0], &mp
.ip
[1], &mp
.ip
[2], &mp
.ip
[3]);
572 mountDev
= mountDev
.right(mountDev
.length() - 2); //strip off leading slashes
573 mp
.mountDir
= getRight(mountDev
, '/');
574 mp
.localDir
= mountOn
;
582 mp
.id
= -1; //don't care
586 if (!((mountOn
== "/") ||(mountOn
== "/dev") || (mountOn
== "/tmp") || (mountOn
== "/proc") || (mountOn
== "/dev/pts") ||
587 (mountDev
.find("/dev/mtdblock") != eString::npos
) || (mountDev
== "usbfs") || (mountOn
== "")))
590 sscanf("//0.0.0.0/nothing", "//%d.%d.%d.%d/%*s", &mp
.ip
[0], &mp
.ip
[1], &mp
.ip
[2], &mp
.ip
[3]);
591 mp
.mountDir
= mountDev
;
592 mp
.localDir
= mountOn
;
600 mp
.id
= -1; //don't care
608 void eMountMgr::init()
612 CConfigFile
*config
= new CConfigFile(',');
613 if (config
->loadConfig(MOUNTCONFIGFILE
))
615 for (int i
= 0; true; i
++)
617 if (config
->getString(eString().sprintf("localdir_%d", i
)) != "")
619 mp
.localDir
= config
->getString(eString().sprintf("localdir_%d", i
));
620 mp
.fstype
= config
->getInt32(eString().sprintf("fstype_%d", i
));
621 mp
.password
= config
->getString(eString().sprintf("password_%d", i
));
622 mp
.userName
= config
->getString(eString().sprintf("username_%d", i
));
623 mp
.mountDir
= config
->getString(eString().sprintf("mountdir_%d", i
));
624 mp
.automount
= config
->getInt32(eString().sprintf("automount_%d", i
));
625 mp
.options
= config
->getString(eString().sprintf("options_%d", i
));
626 mp
.description
= config
->getString(eString().sprintf("description_%d", i
));
627 eString sip
= config
->getString(eString().sprintf("ip_%d", i
));
628 sscanf(sip
.c_str(), "%d.%d.%d.%d", &mp
.ip
[0], &mp
.ip
[1], &mp
.ip
[2], &mp
.ip
[3]);
630 eMountPoint m
= eMountPoint(mp
);
631 m
.mp
.mounted
= m
.isMounted();
632 mountPoints
.push_back(m
);
640 addMountedFileSystems();
643 void eMountMgr::save()
645 FILE *out
= fopen(MOUNTCONFIGFILE
, "w");
649 for (mp_it
= mountPoints
.begin(); mp_it
!= mountPoints
.end(); mp_it
++)
651 if ((mp_it
->mp
.fstype
!= 2) || (mp_it
->mp
.mountDir
.find("disc") != eString::npos
) || (mp_it
->mp
.mountDir
.find("part1") != eString::npos
)) // just save NFS, CIFS, and SMBFS