[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [arm/release] Using SAVECONF when able to persist torrc



commit d28bb39099548f46c97a1a11e5dd31bae0a47e41
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date:   Wed May 11 21:42:05 2011 -0700

    Using SAVECONF when able to persist torrc
    
    Moving config saving to the torConfig utility, and making it save via SAVECONF
    if it's equivilant (the contents and destination matches tor's state). This
    also includes other minor fixes and changes (like a bit more logging).
---
 src/cli/configPanel.py |   28 ++++---------------
 src/util/torConfig.py  |   69 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+), 22 deletions(-)

diff --git a/src/cli/configPanel.py b/src/cli/configPanel.py
index 6ec3fce..7c1a62e 100644
--- a/src/cli/configPanel.py
+++ b/src/cli/configPanel.py
@@ -3,14 +3,13 @@ Panel presenting the configuration state for tor or arm. Options can be edited
 and the resulting configuration files saved.
 """
 
-import os
 import curses
 import threading
 
 import controller
 import popups
 
-from util import conf, enum, panel, torTools, torConfig, uiTools
+from util import conf, enum, panel, sysTools, torConfig, torTools, uiTools
 
 DEFAULT_CONFIG = {"features.config.selectionDetails.height": 6,
                   "features.config.prepopulateEditValues": True,
@@ -401,35 +400,20 @@ class ConfigPanel(panel.Panel):
           elif key == curses.KEY_RIGHT: selection = min(len(selectionOptions) - 1, selection + 1)
         
         if selection in (0, 1):
-          loadedTorrc = torConfig.getTorrc()
+          loadedTorrc, promptCanceled = torConfig.getTorrc(), False
           try: configLocation = loadedTorrc.getConfigLocation()
           except IOError: configLocation = ""
           
           if selection == 1:
             # prompts user for a configuration location
             configLocation = popups.inputPrompt("Save to (esc to cancel): ", configLocation)
-            if configLocation: configLocation = os.path.abspath(configLocation)
+            if not configLocation: promptCanceled = True
           
-          if configLocation:
+          if not promptCanceled:
             try:
-              # make dir if the path doesn't already exist
-              baseDir = os.path.dirname(configLocation)
-              if not os.path.exists(baseDir): os.makedirs(baseDir)
-              
-              # saves the configuration to the file
-              configFile = open(configLocation, "w")
-              configFile.write("\n".join(configLines))
-              configFile.close()
-              
-              # reloads the cached torrc if overwriting it
-              if configLocation == loadedTorrc.getConfigLocation():
-                try:
-                  loadedTorrc.load()
-                  panels["torrc"]._lastContentHeightArgs = None
-                except IOError: pass
-              
+              torConfig.saveConf(configLocation, configLines)
               msg = "Saved configuration to %s" % configLocation
-            except (IOError, OSError), exc:
+            except IOError, exc:
               msg = "Unable to save configuration (%s)" % sysTools.getFileErrorMsg(exc)
             
             popups.showMsg(msg, 2)
diff --git a/src/util/torConfig.py b/src/util/torConfig.py
index 030a169..4a25f0f 100644
--- a/src/util/torConfig.py
+++ b/src/util/torConfig.py
@@ -3,6 +3,7 @@ Helper functions for working with tor's configuration file.
 """
 
 import os
+import time
 import socket
 import threading
 
@@ -381,6 +382,74 @@ def getCustomOptions(includeValue = False):
   if includeValue: return configLines
   else: return [line[:line.find(" ")] for line in configLines]
 
+def saveConf(destination = None, contents = None):
+  """
+  Saves the configuration to the given path. If this is equivilant to
+  issuing a SAVECONF (the contents and destination match what tor's using)
+  then that's done. Otherwise, this writes the contents directly. This raises
+  an IOError if unsuccessful.
+  
+  Arguments:
+    destination - path to be saved to, the current config location if None
+    contents    - configuration to be saved, the current config if None
+  """
+  
+  if destination:
+    destination = os.path.abspath(destination)
+  
+  # fills default config values, and sets isSaveconf to false if they differ
+  # from the arguments
+  isSaveconf, startTime = True, time.time()
+  
+  currentConfig = getCustomOptions(True)
+  if not contents: contents = currentConfig
+  else: isSaveconf &= contents == currentConfig
+  
+  currentLocation = None
+  try:
+    currentLocation = getConfigLocation()
+    if not destination: destination = currentLocation
+    else: isSaveconf &= destination == currentLocation
+  except IOError: pass
+  
+  if not destination: raise IOError("unable to determine the torrc's path")
+  logMsg = "Saved config by %%s to %s (runtime: %%0.4f)" % destination
+  
+  # attempts SAVECONF if we're updating our torrc with the current state
+  if isSaveconf:
+    try:
+      torTools.getConn().getTorCtl().save_conf()
+      
+      try: getTorrc().load()
+      except IOError: pass
+      
+      log.log(log.DEBUG, logMsg % ("SAVECONF", time.time() - startTime))
+      return # if successful then we're done
+    except:
+      # example error:
+      # TorCtl.TorCtl.ErrorReply: 551 Unable to write configuration to disk.
+      pass
+  
+  # if the SAVECONF fails or this is a custom save then write contents directly
+  try:
+    # make dir if the path doesn't already exist
+    baseDir = os.path.dirname(destination)
+    if not os.path.exists(baseDir): os.makedirs(baseDir)
+    
+    # saves the configuration to the file
+    configFile = open(destination, "w")
+    configFile.write("\n".join(contents))
+    configFile.close()
+  except (IOError, OSError), exc:
+    raise IOError(exc)
+  
+  # reloads the cached torrc if overwriting it
+  if destination == currentLocation:
+    try: getTorrc().load()
+    except IOError: pass
+  
+  log.log(log.DEBUG, logMsg % ("directly writing", time.time() - startTime))
+
 def validate(contents = None):
   """
   Performs validation on the given torrc contents, providing back a listing of



_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits