/[drupal]/contributions/modules/provision/provision.path.inc
ViewVC logotype

Contents of /contributions/modules/provision/provision.path.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.28 - (show annotations) (download) (as text)
Thu Oct 1 20:41:50 2009 UTC (7 weeks, 6 days ago) by anarcat
Branch: MAIN
CVS Tags: DRUPAL-6--0-4-ALPHA3, DRUPAL-6--0-4-ALPHA2, HEAD
Changes since 1.27: +11 -6 lines
File MIME type: text/x-php
make switch_path work if one of the paths is missing, return proper error values
1 <?php
2 // $Id: provision.path.inc,v 1.27 2009/08/26 01:18:38 anarcat Exp $
3 /**
4 * @defgroup pathhandling Managing paths, permissions and file ownership
5 *
6 * This group provides an interface to common path handling operations, through
7 * the provision_path helper function, which will take care of verification and
8 * any error logging required.
9 */
10
11 /**
12 * Perform tasks on a path.
13 *
14 * Perform tasks on a path, and logs error messages / codes on success or failure.
15 * This function will call another function which defines the functionality,
16 * and exists to provide a consistent interface for file operations with error logging
17 * integration.
18 *
19 * Many of the provision_path_$op functions are really simple, but are wrapped
20 * in functions to provide a consistent interface for provision_path to operate
21 * with.
22 *
23 * @param type
24 * The type of operation to perform. One of the following:
25 * writable - The $path can be written to.
26 * exists - The $path exists.
27 * is_dir - The $path is a directory.
28 * readable - The $path is readable.
29 * owner - The $path belongs to the user in $confirm.
30 * group - The $path belongs to the group in $confirm.
31 * mkdir - Create the $path directory.
32 * unlink - Delete the file $path.
33 * symlink - Create a symlink from $path to $confirm.
34 * rmdir - Delete the directory $path.
35 * chmod - Change the file permissions of $path to the octal value in $confirm.
36 * chown - Change the owner of $path to the user in $confirm.
37 * chgrp - Change the group of $path to the group in $confirm.
38 * switch_paths - Move $path to $confirm, and vice versa.
39 *
40 * @param path
41 * The path you want to perform the file operation on.
42 *
43 * @param confirm
44 * Confirm that the final value of the file operation matches this value.
45 * This value defaults to TRUE, which is sufficient for most file operations.
46 *
47 * Certain tasks such as chmod, chown and chgp will attempt to change the
48 * properties of $path to match the value in $confirm, and then test that
49 * the change was completed succesfully afterwards.
50 *
51 * These exceptions are :
52 * symlink - $confirm is the path to the symlink being created
53 * chmod - $confirm is an octal value denoting the desired file permissions.
54 * chown - $confirm is the name or user id you wish to change the file ownership to.
55 * chgrp - $confirm is the name of group id you wish to change the file group ownership to.
56 * switch_paths - $confirm is the path that you want to replace the $path with.
57 *
58 * @param succeed_message
59 * Log this as a notice into the logging system, if the operation completed succesfully.
60 *
61 * @param fail_message
62 * Log this as a error to the logging system, if the $error_codes parameter has been set,
63 * otherwise, log this as a warning. If the operation specifies an additional reason for
64 * the operation failing, it will be appended to this message.
65 *
66 * @param error_codes
67 * Generate these system level errors using the provision error bitmasks.
68 *
69 * @return
70 * Returns TRUE if the test against $confirm passed, otherwise returns FALSE.
71 */
72 function provision_path($op, $path, $confirm = TRUE, $succeed_message = NULL, $fail_message = NULL, $error_codes = NULL) {
73 # The code style is a bit weird here, but it's a bit easier to read this way.
74 $func = "provision_path_" . $op;
75 if (function_exists($func)) {
76 // The reason variable is passed into the operation function, to allow the function
77 // to specify an additional reason as to why the operation failed.
78 $reason = '';
79
80 $value = $func($path, $confirm, $reason);
81
82 clearstatcache(); // this needs to be called, otherwise we get the old info
83 $tokens = array("@path" => $path, "@op" => $op, "@confirm" => $confirm);
84 if ($reason) {
85 $fail_message = $fail_message . " (" . $reason . ")";
86 }
87 $status = ($value == $confirm);
88 if ($status) {
89 if (!is_null($succeed_message)) {
90 drush_log(dt($succeed_message, $tokens), 'message');
91 }
92 }
93 else {
94 if ($error_codes) {
95 // Trigger a sysem halting error
96 if (!is_null($fail_message)) {
97 drush_set_error($error_codes, dt($fail_message, $tokens));
98 }
99 else {
100 drush_set_error($error_codes);
101 }
102 }
103 else {
104 // Trigger a warning
105 if (!is_null($fail_message)) {
106 drush_log(dt($fail_message, $tokens), 'warning');
107 }
108 }
109 }
110 return $status;
111 }
112 }
113
114
115 function provision_path_writable($path) {
116 return is_writable($path);
117 }
118
119 function provision_path_exists($path) {
120 return file_exists($path);
121 }
122
123 function provision_path_is_dir($path) {
124 return is_dir($path);
125 }
126
127 function provision_path_readable($path) {
128 return is_readable($path);
129 }
130
131 function provision_path_owner($path) {
132 $info = posix_getpwuid(fileowner($path));
133 return $info['name'];
134 }
135
136 function provision_path_group($path) {
137 return filegroup($path);
138 }
139
140 function provision_path_mkdir($path) {
141 if (version_compare(PHP_VERSION, '5.0.0', '<')) {
142 return _provision_mkdir_recursive($path, 0770);
143 } else {
144 return mkdir($path, 0770, TRUE);
145 }
146 }
147
148 function provision_path_rmdir($path) {
149 return (file_exists($path) && is_dir($path)) ? rmdir($path) : false;
150 }
151
152 function provision_path_unlink($path) {
153 return (file_exists($path)) ? unlink($path) : false;
154 }
155
156
157 /*
158 * This is where the more complex file operations start
159 */
160
161 function provision_path_chmod($path, &$perms, &$reason, $recursive = FALSE) {
162 $func = ($recursive) ? '_provision_chmod_recursive' : 'chmod';
163
164 if (!@$func($path, $perms)) {
165 $reason = dt('chmod to @perm failed on @path', array('@perm' => sprintf('%o', $perms), '@path' => $path));
166 return false;
167 }
168 clearstatcache(); // this needs to be called, otherwise we get the old info
169 $value = substr(sprintf('%o', fileperms($path)), -4);
170 $perms = sprintf('%04o', $perms);
171 return $value;
172 }
173
174 function provision_path_chown($path, &$owner, &$reason, $recursive = FALSE) {
175 $func = ($recursive) ? '_provision_chown_recursive' : 'chown';
176 if ($owner = provision_posix_username($owner)) {
177 if (!$func($path, $owner)) {
178 $reason = dt("chown to @owner failed on @path", array('@owner' => $owner, '@path' => $path)) ;
179 }
180 }
181 else {
182 $reason = dt("the user does not exist");
183 }
184
185 clearstatcache(); // this needs to be called, otherwise we get the old info
186 return provision_posix_username(fileowner($path));
187 }
188
189 function provision_path_chgrp($path, &$gid, &$reason, $recursive = FALSE) {
190 $func = ($recursive) ? '_provision_chgrp_recursive' : 'chgrp';
191 if ($group = provision_posix_groupname($gid)) {
192 if (provision_user_in_group(drush_get_option('script_user'), $gid)) {
193 if ($func($path, $group)) {
194 return $group;
195 }
196 else {
197 $reason = dt("chgrp to @group failed on @path", array('@group' => $group, '@path' => $path));
198 }
199 }
200 else {
201 $reason = dt("@user is not in @group group", array("@user" => drush_get_option('script_user'), "@group" => $group));
202 }
203 }
204 elseif (!@$func($path, $gid)) { # try to change the group anyways
205 $reason = dt("the group does not exist");
206 }
207
208 clearstatcache(); // this needs to be called, otherwise we get the old info
209 return provision_posix_groupname(filegroup($path));
210 }
211
212
213 function provision_path_chmod_recursive($path, &$perms, &$reason) {
214 return provision_path_chmod($path, $perms, $reason, TRUE);
215 }
216
217 function provision_path_chown_recursive($path, &$owner, &$reason) {
218 return provision_path_chown($path, $owner, $reason, TRUE);
219 }
220
221 function provision_path_chgrp_recursive($path, &$gid, &$reason) {
222 return provision_path_chgrp($path, $gid, $reason, TRUE);
223 }
224
225
226 function provision_path_switch_paths($path1, &$path2, &$reason) {
227 //TODO : Add error reasons.
228 $temp = $path1 .'.tmp';
229 if (!file_exists($path1)) {
230 return rename($path2, $path1);
231 }
232 elseif (!file_exists($path2)) {
233 return rename($path1, $path2);
234 }
235 elseif (rename($path1, $temp)) {
236 if (rename($path2, $path1)) {
237 if (rename($temp, $path2)) {
238 return $path2; // path1 is now path2
239 }
240 else {
241 // same .. just in reverse
242 return rename($path1, $path2) && rename($temp, $path1);
243 }
244 }
245 else {
246 // same .. just in reverse
247 return rename($temp, $path1);
248 }
249
250 }
251 return FALSE;
252 }
253
254 function provision_path_extract($path, &$target, &$reason) {
255 if (file_exists($path) && is_readable($path)) {
256 if (is_writeable(dirname($target)) && !file_exists($target) && !is_dir($target)) {
257 mkdir($target);
258 drush_log(sprintf("Running: tar -zpxf %s -C %s", $path, $target));
259 $result = provision_shell_exec("tar -zpxf %s -C %s", $path, $target);
260
261 if ($result && is_writeable(dirname($target)) && is_readable(dirname($target)) && is_dir($target)) {
262 $target = TRUE;
263 return TRUE;
264 }
265 else {
266 $reason = dt("The file could not be extracted");
267 }
268 }
269 else {
270 $reason = dt("The target directory could not be written to");
271 return false;
272 }
273 }
274 else {
275 $reason = dt("Backup file could not be opened");
276 return false;
277 }
278
279 }
280
281 function provision_path_symlink($path, &$target, &$reason) {
282 if (file_exists($target) && !is_link($target)) {
283 $reason = dt("A file already exists at @path");
284 return FALSE;
285 }
286 if (is_link($target) && (readlink($target) != $path)) {
287 $reason = dt("A symlink already exists at target, but it is pointing to @link", array("@link" => readlink($target)));
288 return FALSE;
289 }
290 if (is_link($target) && (readlink($target) == $path)) {
291 $target = TRUE;
292 return TRUE;
293 }
294 if (symlink($path, $target)) {
295 $target = TRUE;
296 return TRUE;
297 }
298 else {
299 $reason = dt('The symlink could not be created, an error has occured');
300 return FALSE;
301 }
302
303
304 }
305
306 /**
307 *@} end filegroup
308 */
309
310 /**
311 * Small helper function for creation of configuration directories.
312 */
313 function _provision_create_dir($path, $name, $perms) {
314 $exists = provision_path("exists",$path, TRUE ,
315 $name . ' ' . dt("path exists."),
316 $name . ' ' . dt("path does not exist.")
317 );
318
319 if (!$exists) {
320 $exists = provision_path("mkdir", $path, TRUE,
321 $name . ' ' . dt("path has been created."),
322 $name . ' ' . dt("path could not be created."),
323 'DRUSH_PERM_ERROR');
324 }
325
326 if ($exists) {
327 provision_path("chown", $path, drush_get_option('script_user'),
328 $name . ' ' . dt("ownership of path has been changed to @confirm."),
329 $name . ' ' . dt("ownership of path could not be changed to @confirm."),
330 'DRUSH_PERM_ERROR');
331
332 provision_path("chmod", $path, $perms,
333 $name . ' ' . dt("permissions of path have been changed to @confirm."),
334 $name . ' ' . dt("permissions of path could not be changed to @confirm."),
335 'DRUSH_PERM_ERROR' );
336
337 $writable = provision_path("writable", $path, TRUE,
338 $name . ' ' . dt("path is writable."),
339 $name . ' ' . dt("path is not writable."),
340 'DRUSH_PERM_ERROR');
341
342 }
343
344 return ($exists && $writable);
345 }
346
347 /**
348 * Makes directory recursively, returns TRUE if exists or made (for PHP4 compatibility)
349 * Code courtesy of: http://ca3.php.net/manual/en/function.mkdir.php#81656
350 *
351 * @param string $pathname The directory path.
352 * @return boolean returns TRUE if exists or made or FALSE on failure.
353 */
354 function _provision_mkdir_recursive($path, $mode) {
355 is_dir(dirname($path)) || _provision_mkdir_recursive(dirname($path), $mode);
356 return is_dir($path) || mkdir($path, $mode);
357 }
358
359 /**
360 * Walk the given tree recursively (depth first), calling a function on each file
361 *
362 * $func is not checked for existence and called directly with $path and $arg
363 * for every file encountered.
364 *
365 * @param string $func a valid callback, usually chmod, chown or chgrp
366 * @param string $path a path in the filesystem
367 * @param string $arg the second argument to $func
368 * @return boolean returns TRUE if every $func call returns true
369 */
370 function _provision_call_recursive($func, $path, $arg) {
371 $status = 1;
372 if ($dh = @opendir($path)) {
373 while (($file = readdir($dh)) !== false) {
374 if ($file != '.' && $file != '..') {
375 $status = _provision_call_recursive($func, $path . "/" . $file, $arg) && $status;
376 }
377 }
378 closedir($dh);
379 }
380 $status = $func($path, $arg) && $status;
381 return $status;
382 }
383
384 /**
385 * Chmod a directory recursively
386 *
387 */
388 function _provision_chmod_recursive($path, $filemode) {
389 return _provision_call_recursive("chmod", $path, $filemode);
390 }
391
392 /**
393 * Chown a directory recursively
394 */
395 function _provision_chown_recursive($path, $owner) {
396 return _provision_call_recursive("chown", $path, $owner);
397 }
398
399 /**
400 * Chgrp a directory recursively
401 */
402 function _provision_chgrp_recursive($path, $owner) {
403 return _provision_call_recursive("chgrp", $path, $owner);
404 }

  ViewVC Help
Powered by ViewVC 1.1.2