9b80236441f3bad8b8a1c0a9f3d2b67c3b444056
[leap_pycommon.git] / src / leap / common / files.py
1 # -*- coding: utf-8 -*-
2 # files.py
3 # Copyright (C) 2013 LEAP
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18 """
19 Implements file helper methods
20 """
21
22 import os
23 import stat
24 import logging
25 import time
26 import errno
27
28 logger = logging.getLogger(__name__)
29
30
31 def check_and_fix_urw_only(cert):
32     """
33     Test for 600 mode and try to set it if anything different found
34
35     Might raise OSError
36
37     @param cert: Certificate path
38     @type cert: str
39     """
40     mode = stat.S_IMODE(os.stat(cert).st_mode)
41
42     if mode != int('600', 8):
43         try:
44             logger.warning('Bad permission on %s attempting to set 600' %
45                            (cert,))
46             os.chmod(cert, stat.S_IRUSR | stat.S_IWUSR)
47         except OSError:
48             logger.error('Error while trying to chmod 600 %s' %
49                          cert)
50             raise
51
52
53 def get_mtime(filename):
54     """
55     Returns the modified time or None if the file doesn't exist
56
57     @param filename: path to check
58     @type filename: str
59
60     @rtype: str
61     """
62     try:
63         mtime = time.ctime(os.path.getmtime(filename)) + " GMT"
64         return mtime
65     except OSError:
66         return None
67
68
69 def mkdir_p(path):
70     """
71     Creates the path and all the intermediate directories that don't
72     exist
73
74     Might raise OSError
75
76     @param path: path to create
77     @type path: str
78     """
79     try:
80         os.makedirs(path)
81     except OSError as exc:
82         if exc.errno == errno.EEXIST and os.path.isdir(path):
83             pass
84         else:
85             raise
86
87
88 # Twisted implementation of which
89 def which(name, flags=os.X_OK, path_extension="/usr/sbin:/sbin"):
90     """
91     Search PATH for executable files with the given name.
92
93     On newer versions of MS-Windows, the PATHEXT environment variable will be
94     set to the list of file extensions for files considered executable. This
95     will normally include things like ".EXE". This fuction will also find files
96     with the given name ending with any of these extensions.
97
98     On MS-Windows the only flag that has any meaning is os.F_OK. Any other
99     flags will be ignored.
100
101     @type name: C{str}
102     @param name: The name for which to search.
103
104     @type flags: C{int}
105     @param flags: Arguments to L{os.access}.
106
107     @rtype: C{list}
108     @param: A list of the full paths to files found, in the
109     order in which they were found.
110     """
111
112     result = []
113     exts = filter(None, os.environ.get('PATHEXT', '').split(os.pathsep))
114     path = os.environ.get('PATH', None)
115     path += ":" + path_extension
116     if path is None:
117         return []
118     parts = path.split(os.pathsep)
119     for p in parts:
120         p = os.path.join(p, name)
121         if os.access(p, flags):
122             result.append(p)
123         for e in exts:
124             pext = p + e
125             if os.access(pext, flags):
126                 result.append(pext)
127     return result