]> git.phdru.name Git - extfs.d.git/blobdiff - obexftp
Ignore my Siemens-S55 obexftp transport file and obexftp-mcextfs.log.
[extfs.d.git] / obexftp
diff --git a/obexftp b/obexftp
index 12c9f529859583cb3be38ccefe5eeef8890bd67a..1f4a0339b324b4e165a0a3f5fc4040a06fe4a143 100755 (executable)
--- a/obexftp
+++ b/obexftp
@@ -4,7 +4,7 @@
 ObexFTP Virtual FileSystem for Midnight Commander.
 
 Author: Oleg BroytMann <phd@phd.pp.ru>.
 ObexFTP Virtual FileSystem for Midnight Commander.
 
 Author: Oleg BroytMann <phd@phd.pp.ru>.
-Copyright (C) 2004 PhiloSoft Design.
+Copyright (C) 2004, 2005 PhiloSoft Design.
 License: GPL.
 
 Manipulate a cell phone's filesystem calling obexftp binary. This is a
 License: GPL.
 
 Manipulate a cell phone's filesystem calling obexftp binary. This is a
@@ -60,44 +60,75 @@ Commander shows the same cached VFS image. Exit Midnight Commander and
 restart it.
 
 If something goes wrong set the logging level (see setLevel() below) to INFO
 restart it.
 
 If something goes wrong set the logging level (see setLevel() below) to INFO
-or DEBUG and look in the obexftp-mcextfs.log file(s).
-
+or DEBUG and look in the obexftp-mcextfs.log file. The file is put in the same
+directory as the transport file, if it possible; if not the file will be put
+into a temporary directory, usually /tmp, or /var/tmp, or whatever directory
+is named in $TMP environment variable.
 """
 
 """
 
-__version__ = "1.1.0"
-__revision__ = "$Id: obexftp,v 1.16 2004/07/27 17:55:15 phd Exp $"
-__date__ = "$Date: 2004/07/27 17:55:15 $"[7:-2]
+__version__ = "1.2.2"
+__revision__ = "$Id$"
+__date__ = "$Date$"[7:-2]
 __author__ = "Oleg Broytmann <phd@phd.pp.ru>"
 __author__ = "Oleg Broytmann <phd@phd.pp.ru>"
-__copyright__ = "Copyright (C) 2004 PhiloSoft Design"
+__copyright__ = "Copyright (C) 2004, 2005 PhiloSoft Design"
 
 
 # Change this to suite your needs
 obexftp_prog = "/usr/local/obex/bin/obexftp"
 
 
 
 
 # Change this to suite your needs
 obexftp_prog = "/usr/local/obex/bin/obexftp"
 
 
-import sys, time
-import os, shutil
-import xml.dom.minidom
-from tempfile import mkdtemp
+import sys, os, shutil
+from time import sleep
+import xml.dom.minidom, locale
+from tempfile import mkstemp, mkdtemp, _candidate_tempdir_list
 
 
 import logging
 logger = logging.getLogger('obexftp-mcextfs')
 
 
 import logging
 logger = logging.getLogger('obexftp-mcextfs')
-logger.addHandler(logging.FileHandler('obexftp-mcextfs.log'))
+log_err_handler = logging.StreamHandler(sys.stderr)
+logger.addHandler(log_err_handler)
 logger.setLevel(logging.ERROR)
 
 
 logger.setLevel(logging.ERROR)
 
 
-if len(sys.argv) < 2:
-   logger.error("""\
+if len(sys.argv) < 3:
+   logger.critical("""\
 ObexFTP Virtual FileSystem for Midnight Commander version %s
 Author: %s
 %s
 ObexFTP Virtual FileSystem for Midnight Commander version %s
 Author: %s
 %s
+
+This is not a program. It is ObexFTP Virtual FileSystem for Midnight Commander.
 Put it in /usr/lib/mc/extfs. For more information read the source!""",
    __version__, __author__, __copyright__
 )
    sys.exit(1)
 
 
 Put it in /usr/lib/mc/extfs. For more information read the source!""",
    __version__, __author__, __copyright__
 )
    sys.exit(1)
 
 
+tempdirlist = _candidate_tempdir_list()
+tempdirlist.insert(0, os.path.abspath(os.path.dirname(sys.argv[2])))
+
+found = False
+for tempdir in tempdirlist:
+   try:
+      logfile_name = os.path.join(tempdir, 'obexftp-mcextfs.log')
+      logfile = open(logfile_name, 'w')
+   except IOError:
+      pass
+   else:
+      found = True
+      logfile.close()
+      break
+
+if not found:
+   logger.critical("Cannot initialize error log file in directories %s" % str(tempdirlist))
+   sys.exit(1)
+
+logger.removeHandler(log_err_handler)
+logger.addHandler(logging.FileHandler(logfile_name))
+
+locale.setlocale(locale.LC_ALL, '')
+charset = locale.getpreferredencoding()
+
+
 # Parse ObexFTP XML directory listings
 
 class DirectoryEntry(object):
 # Parse ObexFTP XML directory listings
 
 class DirectoryEntry(object):
@@ -150,18 +181,49 @@ def get_entries(dom, type):
    return entries
 
 
    return entries
 
 
+# A unique directory for temporary files
+tmpdir_name = None
+
+def setup_tmpdir():
+   global tmpdir_name
+   tmpdir_name = mkdtemp(".tmp", "mcobex-")
+   os.chdir(tmpdir_name)
+
+def cleanup_tmpdir():
+   os.chdir(os.pardir)
+   shutil.rmtree(tmpdir_name)
+
+
+def _read(fd):
+   out = []
+   while True:
+      s = os.read(fd, 1024)
+      if not s:
+         break
+      out.append(s)
+   return ''.join(out)
+
+
 def _run(*args):
    """Run the obexftp binary catching errors"""
 def _run(*args):
    """Run the obexftp binary catching errors"""
-   command = "%s %s %s" % (obexftp_prog, obexftp_args, ' '.join(args))
+
+   out_fd, out_filename = mkstemp(".tmp", "mcobex-", tmpdir_name)
+   err_fd, err_filename = mkstemp(".tmp", "mcobex-", tmpdir_name)
+
+   command = "%s %s %s >%s 2>%s" % (obexftp_prog, obexftp_args, ' '.join(args),
+      out_filename, err_filename)
+
    logger.debug("Running command %s", command)
    logger.debug("Running command %s", command)
-   w, r, e = os.popen3(command, 'r')
-   w.close()
-   errors = e.read()
-   e.close()
-   result = r.read()
-   r.close()
-   logger.debug("    errors: %s", errors)
+   os.system(command)
+
+   result = _read(out_fd)
+   os.remove(out_filename)
+
+   errors = _read(err_fd)
+   os.remove(err_filename)
+
    logger.debug("    result: %s", result)
    logger.debug("    result: %s", result)
+   logger.debug("    errors: %s", errors)
    return result, errors
 
 
    return result, errors
 
 
@@ -179,31 +241,23 @@ def recursive_list(directory='/'):
 
    for entry in directories + files:
       fullpath = "%s/%s" % (directory, entry.name)
 
    for entry in directories + files:
       fullpath = "%s/%s" % (directory, entry.name)
+      fullpath = fullpath.encode(charset)
       if fullpath.startswith('//'): fullpath = fullpath[1:]
       print entry.perm, "1 user group", entry.size, entry.mtime, fullpath
 
    for entry in directories:
       fullpath = "%s/%s" % (directory, entry.name)
       if fullpath.startswith('//'): fullpath = fullpath[1:]
       if fullpath.startswith('//'): fullpath = fullpath[1:]
       print entry.perm, "1 user group", entry.size, entry.mtime, fullpath
 
    for entry in directories:
       fullpath = "%s/%s" % (directory, entry.name)
       if fullpath.startswith('//'): fullpath = fullpath[1:]
-      time.sleep(1)
+      sleep(1)
       recursive_list(fullpath)
 
 def mcobex_list():
    """List the entire VFS"""
       recursive_list(fullpath)
 
 def mcobex_list():
    """List the entire VFS"""
-   recursive_list()
-
-
-# A unique directory for temporary files
-tmpdir_name = None
-
-def setup_tmpdir():
-   global tmpdir_name
-   tmpdir_name = mkdtemp(".tmp", "mcobex-")
-   os.chdir(tmpdir_name)
-
-def cleanup_tmpdir():
-   os.chdir(os.pardir)
-   shutil.rmtree(tmpdir_name)
+   setup_tmpdir()
+   try:
+      recursive_list()
+   finally:
+      cleanup_tmpdir()
 
 
 def mcobex_copyout():
 
 
 def mcobex_copyout():
@@ -217,7 +271,7 @@ def mcobex_copyout():
       try:
          os.rename(os.path.basename(obex_filename), real_filename)
       except OSError:
       try:
          os.rename(os.path.basename(obex_filename), real_filename)
       except OSError:
-         logger.exception("CopyOut %s to %s", obex_filename, real_filename)
+         logger.exception("Error CopyOut %s to %s", obex_filename, real_filename)
    finally:
       cleanup_tmpdir()
 
    finally:
       cleanup_tmpdir()
 
@@ -235,7 +289,7 @@ def mcobex_copyin():
          _run("-c '%s' -p '%s'" % (dirname, filename))
          os.rename(filename, real_filename) # by some reason MC wants the file back
       except OSError:
          _run("-c '%s' -p '%s'" % (dirname, filename))
          os.rename(filename, real_filename) # by some reason MC wants the file back
       except OSError:
-         logger.exception("CopyIn %s to %s", real_filename, obex_filename)
+         logger.exception("Error CopyIn %s to %s", real_filename, obex_filename)
    finally:
       cleanup_tmpdir()
 
    finally:
       cleanup_tmpdir()
 
@@ -243,53 +297,81 @@ def mcobex_copyin():
 def mcobex_rm():
    """Remove a file from the VFS"""
    obex_filename = sys.argv[3]
 def mcobex_rm():
    """Remove a file from the VFS"""
    obex_filename = sys.argv[3]
-   _run("-k '%s'" % obex_filename)
+   try:
+      _run("-k '%s'" % obex_filename)
+   finally:
+      cleanup_tmpdir()
 
 
 def mcobex_mkdir():
    """Create a directory in the VFS"""
    obex_dirname = sys.argv[3]
 
 
 def mcobex_mkdir():
    """Create a directory in the VFS"""
    obex_dirname = sys.argv[3]
-   _run("-C '%s'" % obex_dirname)
+   try:
+      _run("-C '%s'" % obex_dirname)
+   finally:
+      cleanup_tmpdir()
 
 
 mcobex_rmdir = mcobex_rm
 
 
 
 
 mcobex_rmdir = mcobex_rm
 
 
-g = globals()
-command = sys.argv[1]
-procname = "mcobex_" + command
-
-if not g.has_key(procname):
-   logger.error("Unknown command %s", command)
+def transport_error(error_str):
+   logger.critical("Error parsing the transport file: %s" % error_str)
    sys.exit(1)
 
    sys.exit(1)
 
-
 def setup_transport():
    """Setup transport parameters for the obexftp program"""
 def setup_transport():
    """Setup transport parameters for the obexftp program"""
-   transport_file = open(sys.argv[2], 'r')
-   line = transport_file.readline()
-   transport_file.close()
+   try:
+      transport_file = open(sys.argv[2], 'r')
+      line = transport_file.readline()
+      transport_file.close()
+   except IOError:
+      transport_error("cannot read '%s'" % sys.argv[2])
 
    parts = line.strip().split()
    transport = parts[0].lower()
 
    if transport == "bluetooth":
 
    parts = line.strip().split()
    transport = parts[0].lower()
 
    if transport == "bluetooth":
+      if len(parts) < 3:
+         transport_error("not enough arguments for 'bluetooth' transport")
+      elif len(parts) > 3:
+         transport_error("too many arguments for 'bluetooth' transport")
       return ' '.join(["-b", parts[1], "-B", parts[2]])
    elif transport == "tty":
       return ' '.join(["-b", parts[1], "-B", parts[2]])
    elif transport == "tty":
+      if len(parts) < 2:
+         transport_error("not enough arguments for 'tty' transport")
+      elif len(parts) > 2:
+         transport_error("too many arguments for 'tty' transport")
       return ' '.join(["-t", parts[1]])
    elif transport == "irda":
       return ' '.join(["-t", parts[1]])
    elif transport == "irda":
+      if len(parts) > 1:
+         transport_error("too many arguments for 'irda' transport")
       return "-i"
    else:
       return "-i"
    else:
-      logger.error("Unknown transport '%s'; expected 'bluetooth', 'tty' or 'irda'", transport)
+      logger.critical("Unknown transport '%s'; expected 'bluetooth', 'tty' or 'irda'", transport)
       sys.exit(1)
 
       sys.exit(1)
 
+
+command = sys.argv[1]
+procname = "mcobex_" + command
+
+g = globals()
+if not g.has_key(procname):
+   logger.critical("Unknown command %s", command)
+   sys.exit(1)
+
+
 try:
    obexftp_args = setup_transport()
 try:
    obexftp_args = setup_transport()
+except SystemExit:
+   raise
 except:
 except:
-   logger.exception("Exception while parsing the transport file")
+   logger.exception("Error parsing the transport file")
    sys.exit(1)
 
 try:
    g[procname]()
    sys.exit(1)
 
 try:
    g[procname]()
+except SystemExit:
+   raise
 except:
 except:
-   logger.exception("Exception during run")
+   logger.exception("Error during run")