PageRenderTime 53ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/framework/VC/VC/rcs.php

https://github.com/wrobel/horde-fw3
PHP | 235 lines | 187 code | 16 blank | 32 comment | 14 complexity | 1daecaa9731b8f13cbd26cef3b46c61c MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, LGPL-2.1, BSD-2-Clause
  1. <?php
  2. /**
  3. * VC_rcs implementation.
  4. *
  5. * Copyright 2004-2007 Jeff Schwentner <jeffrey.schwentner@lmco.com>
  6. *
  7. * $Horde: framework/VC/VC/rcs.php,v 1.3.8.7 2007-12-20 13:50:17 jan Exp $
  8. *
  9. * @author Jeff Schwentner <jeffrey.schwentner@lmco.com>
  10. * @author Chuck Hagenbuch <chuck@horde.org>
  11. * @package VC
  12. */
  13. class VC_rcs extends VC {
  14. /**
  15. * Checks an RCS file in with a specified change log.
  16. *
  17. * @param string $filepath Location of file to check in.
  18. * @param string $message Log of changes since last version.
  19. * @param string $user The user name to use for the check in.
  20. * @param boolean $newBinary Does the change involve binary data?
  21. *
  22. * @return string|object The new revision number on success, or a
  23. * PEAR_Error object on failure.
  24. */
  25. function ci($filepath, $message, $user = null, $newBinary = false)
  26. {
  27. if ($user) {
  28. putenv('LOGNAME=' . $user);
  29. } else {
  30. putenv('LOGNAME=guest');
  31. }
  32. $Q = VC_WINDOWS ? '"' : "'" ;
  33. $ci_cmd = $this->getPath('ci') . ' ' . $Q . $filepath . $Q.' 2>&1';
  34. $rcs_cmd = $this->getPath('rcs') . ' -i -kb ' . $Q . $filepath . $Q.' 2>&1';
  35. $output = '';
  36. $message_lines = explode("\n", $message);
  37. $pipe_def = array(0 => array("pipe", 'r'),
  38. 1 => array("pipe", 'w'));
  39. if ($newBinary) {
  40. $process = proc_open($rcs_cmd, $pipe_def, $pipes);
  41. } else {
  42. $process = proc_open($ci_cmd, $pipe_def, $pipes);
  43. }
  44. if (is_resource($process)) {
  45. foreach ($message_lines as $line) {
  46. if ($line == '.\n') {
  47. $line = '. \n';
  48. }
  49. fwrite($pipes[0], $line);
  50. }
  51. fwrite($pipes[0], "\n.\n");
  52. fclose($pipes[0]);
  53. while (!feof($pipes[1])) {
  54. $output .= fread($pipes[1], 8192);
  55. }
  56. fclose($pipes[1]);
  57. proc_close($process);
  58. } else {
  59. return PEAR::raiseError('Failed to open pipe in ci()');
  60. }
  61. if ($newBinary) {
  62. exec($ci_cmd . ' 2>&1', $return_array, $retval);
  63. if ($retval) {
  64. return PEAR::raiseError("Unable to spawn ci on $filepath from ci()");
  65. } else {
  66. foreach ($return_array as $line) {
  67. $output .= $line;
  68. }
  69. }
  70. }
  71. $rev_start = strpos($output, 'new revision: ');
  72. // If no new revision, see if this is an initial checkin.
  73. if ($rev_start === false) {
  74. $rev_start = strpos($output, 'initial revision: ');
  75. $rev_end = strpos($output, ' ', $rev_start);
  76. } else {
  77. $rev_end = strpos($output, ';', $rev_start);
  78. }
  79. if ($rev_start !== false && $rev_end !== false) {
  80. $rev_start += 14;
  81. return substr($output, $rev_start, $rev_end - $rev_start);
  82. } else {
  83. unlock($filepath);
  84. $temp_pos = strpos($output, 'file is unchanged');
  85. if ($temp_pos !== false) {
  86. return PEAR::raiseError('Check-in Failure: ' . basename($filepath) . ' has not been modified');
  87. } else {
  88. return PEAR::raiseError("Failed to checkin $filepath, $ci_cmd, $output");
  89. }
  90. }
  91. }
  92. /**
  93. * Checks the locks on a CVS/RCS file.
  94. *
  95. * @param string $filepath Location of file.
  96. * @param string &$locked_by Returns the username holding the lock.
  97. *
  98. * @return boolean|object True on success, or a PEAR_Error on failure.
  99. */
  100. function isLocked($filepath, &$locked_by)
  101. {
  102. $rlog_cmd = $this->getPath('rlog');
  103. $rlog_flag = ' -L ';
  104. $Q = VC_WINDOWS ? '"' : "'";
  105. $cmd = $rlog_cmd . $rlog_flag . $Q . $filepath . $Q;
  106. exec($cmd.' 2>&1', $return_array, $retval);
  107. if ($retval) {
  108. return PEAR::raiseError("Unable to spawn rlog on $filepath from isLocked()");
  109. } else {
  110. $output = '';
  111. foreach ($return_array as $line) {
  112. $output .= $line;
  113. }
  114. $start_name = strpos($output, 'locked by: ');
  115. $end_name = strpos($output, ';', $start_name);
  116. if ($start_name !== false && $end_name !== false) {
  117. $start_name += 11;
  118. $locked_by = substr($output, $start_name, $end_name - $start_name);
  119. return true;
  120. } elseif (strlen($output) == 0) {
  121. return false;
  122. } else {
  123. return PEAR::raiseError('Failure running rlog in isLocked()');
  124. }
  125. }
  126. }
  127. /**
  128. * Locks a CVS/RCS file.
  129. *
  130. * @param string $filepath Location of file.
  131. * @param string $user User name to lock the file with
  132. *
  133. * @return boolean|object True on success, or a PEAR_Error on failure.
  134. */
  135. function lock($filepath, $user = null)
  136. {
  137. // Get username for RCS tag.
  138. if ($user) {
  139. putenv('LOGNAME=' . $user);
  140. } else {
  141. putenv('LOGNAME=guest');
  142. }
  143. $rcs_cmd = $this->getPath('rcs');
  144. $rcs_flag = ' -l ';
  145. $Q = VC_WINDOWS ? '"' : "'" ;
  146. $cmd = $rcs_cmd . $rcs_flag . $Q . $filepath . $Q;
  147. exec($cmd.' 2>&1', $return_array, $retval);
  148. if ($retval) {
  149. return PEAR::raiseError('Failed to spawn rcs ("' . $cmd . '") on "' . $filepath . '" (returned ' . $retval . ')');
  150. } else {
  151. $output = '';
  152. foreach ($return_array as $line) {
  153. $output .= $line;
  154. }
  155. $locked_pos = strpos($output, 'locked');
  156. if ($locked_pos !== false) {
  157. return true;
  158. } else {
  159. return PEAR::raiseError('Failed to lock "' . $filepath . '" (Ran "' . $cmd . '", got return code ' . $retval . ', output: ' . $output . ')');
  160. }
  161. }
  162. }
  163. /**
  164. * Unlocks a CVS/RCS file.
  165. *
  166. * @param string $filepath Location of file.
  167. * @param string $user User name to unlock the file with
  168. *
  169. * @return boolean|object True on success, or a PEAR_Error on failure.
  170. */
  171. function unlock($filepath, $user = null)
  172. {
  173. // Get username for RCS tag.
  174. if ($user) {
  175. putenv('LOGNAME=' . $user);
  176. } else {
  177. putenv('LOGNAME=guest');
  178. }
  179. $rcs_cmd = $this->getPath('rcs');
  180. $rcs_flag = ' -u ';
  181. $Q = VC_WINDOWS ? '"' : "'" ;
  182. $cmd = $rcs_cmd . $rcs_flag . $Q . $filepath . $Q;
  183. exec($cmd . ' 2>&1', $return_array, $retval);
  184. if ($retval) {
  185. return PEAR::raiseError('Failed to spawn rcs ("' . $cmd . '") on "' . $filepath . '" (returned ' . $retval . ')');
  186. } else {
  187. $output = '';
  188. foreach ($return_array as $line) {
  189. $output .= $line;
  190. }
  191. $unlocked_pos = strpos($output, 'unlocked');
  192. if ($unlocked_pos !== false) {
  193. return true;
  194. } else {
  195. // Already unlocked.
  196. return true;
  197. }
  198. }
  199. }
  200. }