Rev 76 | Rev 143 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 76 | Rev 106 | ||
---|---|---|---|
1 | <?php |
1 | <?php |
2 | 2 | ||
3 | # |
3 | # |
4 | # VGWhoIs (ViaThinkSoft Global WhoIs, a fork of generic Whois / gwhois) |
4 | # VGWhoIs (ViaThinkSoft Global WhoIs, a fork of generic Whois / gwhois) |
5 | # Common functions in PHP |
5 | # Common functions in PHP |
6 | # |
6 | # |
7 | # (c) 2011-2013 by Daniel Marschall, ViaThinkSoft <info@daniel-marschall.de> |
7 | # (c) 2011-2013 by Daniel Marschall, ViaThinkSoft <info@daniel-marschall.de> |
8 | # |
8 | # |
9 | # License: https://www.gnu.org/licenses/gpl-2.0.html (GPL version 2) |
9 | # License: https://www.gnu.org/licenses/gpl-2.0.html (GPL version 2) |
10 | # |
10 | # |
11 | 11 | ||
12 | include_once __DIR__ . '/ipv4_functions.inc.php'; |
12 | include_once __DIR__ . '/ipv4_functions.inc.php'; |
13 | include_once __DIR__ . '/ipv6_functions.inc.php'; |
13 | include_once __DIR__ . '/ipv6_functions.inc.php'; |
14 | include_once __DIR__ . '/grep_functions.inc.php'; |
14 | include_once __DIR__ . '/grep_functions.inc.php'; |
15 | include_once __DIR__ . '/gwi_functions.inc.php'; |
15 | include_once __DIR__ . '/gwi_functions.inc.php'; |
16 | 16 | ||
17 | function file_age($filename) { |
17 | function file_age($filename) { |
18 | $m = file_exists($filename) ? filemtime($filename) : 0; |
18 | $m = file_exists($filename) ? filemtime($filename) : 0; |
19 | return time()-$m; |
19 | return time()-$m; |
20 | } |
20 | } |
21 | 21 | ||
22 | function human_timediff($t) { |
22 | function human_timediff($t) { |
23 | if ($t < 60) { |
23 | if ($t < 60) { |
24 | $e = 'seconds'; |
24 | $e = 'seconds'; |
25 | } else if ($t < 60*60) { |
25 | } else if ($t < 60*60) { |
26 | $t /= 60; |
26 | $t /= 60; |
27 | $e = 'minutes'; |
27 | $e = 'minutes'; |
28 | } else if ($t < 24*60*60) { |
28 | } else if ($t < 24*60*60) { |
29 | $t /= 60*60; |
29 | $t /= 60*60; |
30 | $e = 'hours'; |
30 | $e = 'hours'; |
31 | } else if ($t < 30*24*60*60) { |
31 | } else if ($t < 30*24*60*60) { |
32 | $t /= 24*60*60; |
32 | $t /= 24*60*60; |
33 | $e = 'days'; |
33 | $e = 'days'; |
34 | } else if ($t < 365*24*60*60) { |
34 | } else if ($t < 365*24*60*60) { |
35 | $t /= 30*24*60*60; |
35 | $t /= 30*24*60*60; |
36 | $e = 'months'; |
36 | $e = 'months'; |
37 | } else { |
37 | } else { |
38 | $t /= 365*24*60*60; |
38 | $t /= 365*24*60*60; |
39 | $e = 'years'; |
39 | $e = 'years'; |
40 | } |
40 | } |
41 | $t = floor($t); |
41 | $t = floor($t); |
42 | return "$t $e"; |
42 | return "$t $e"; |
43 | } |
43 | } |
44 | 44 | ||
45 | # http://www.phpeasycode.com/whois/ |
45 | # http://www.phpeasycode.com/whois/ |
46 | # TODO: code duplicate in maintenance/pattern-generator/generate_newgtld |
46 | # TODO: code duplicate in maintenance/pattern-generator/generate_newgtld |
47 | function QueryWhoisServer($whoisserver, $domain, $port=43, $timeout=10) { |
47 | function QueryWhoisServer($whoisserver, $domain, $port=43, $timeout=10) { |
48 | $fp = @fsockopen($whoisserver, $port, $errno, $errstr, $timeout); |
48 | $fp = @fsockopen($whoisserver, $port, $errno, $errstr, $timeout); |
49 | if (!$fp) die("Socket Error " . $errno . " - " . $errstr); |
49 | if (!$fp) die("Socket Error " . $errno . " - " . $errstr); |
50 | // if ($whoisserver == "whois.verisign-grs.com") $domain = "=$domain"; // whois.verisign-grs.com requires the equals sign ("=") or it returns any result containing the searched string. |
50 | // if ($whoisserver == "whois.verisign-grs.com") $domain = "=$domain"; // whois.verisign-grs.com requires the equals sign ("=") or it returns any result containing the searched string. |
51 | fputs($fp, $domain . "\r\n"); |
51 | fputs($fp, $domain . "\r\n"); |
52 | $out = ""; |
52 | $out = ""; |
53 | while(!feof($fp)){ |
53 | while(!feof($fp)){ |
54 | $out .= fgets($fp); |
54 | $out .= fgets($fp); |
55 | } |
55 | } |
56 | fclose($fp); |
56 | fclose($fp); |
57 | 57 | ||
58 | $res = ""; |
58 | $res = ""; |
59 | if ((strpos(strtolower($out), "error") === FALSE) && (strpos(strtolower($out), "not allocated") === FALSE)) { |
59 | if ((strpos(strtolower($out), "error") === FALSE) && (strpos(strtolower($out), "not allocated") === FALSE)) { |
60 | $rows = explode("\n", $out); |
60 | $rows = explode("\n", $out); |
61 | foreach($rows as $row) { |
61 | foreach($rows as $row) { |
62 | $row = trim($row); |
62 | $row = trim($row); |
63 | if (($row != '') && ($row[0] != '#') && ($row[0] != '%')) { |
63 | if (($row != '') && ($row[0] != '#') && ($row[0] != '%')) { |
64 | $res .= "$row\n"; |
64 | $res .= "$row\n"; |
65 | } |
65 | } |
66 | } |
66 | } |
67 | } |
67 | } |
68 | return $res; |
68 | return $res; |
69 | } |
69 | } |
70 | 70 | ||
71 | # TODO: rename (without "gwitc") |
71 | # TODO: rename (without "gwitc") |
72 | function gwitc_is_port_open($server, $default_port, $timeout=3) { |
72 | function gwitc_is_port_open($server, $default_port, $timeout=3) { |
73 | // TODO: "whois.namecoin.us" will always answer to a port request, because the domain parking service is shit |
73 | // TODO: "whois.namecoin.us" will always answer to a port request, because the domain parking service is shit |
74 | 74 | ||
75 | $x = explode(':', $server, 2); |
75 | $x = explode(':', $server, 2); |
76 | $host = $x[0]; |
76 | $host = $x[0]; |
77 | $port = isset($x[1]) ? $x[1] : $default_port; |
77 | $port = isset($x[1]) ? $x[1] : $default_port; |
78 | 78 | ||
79 | // First try with TOR |
79 | // First try with TOR |
80 | # $cmd = "vtor -- nc -zw$timeout $host $port 2>/dev/null"; |
80 | # $cmd = "vtor -- nc -zw$timeout $host $port 2>/dev/null"; |
81 | # exec($cmd, $out, $code); |
81 | # exec($cmd, $out, $code); |
82 | # if ($code == 0) return true; |
82 | # if ($code == 0) return true; |
83 | 83 | ||
84 | // Try without TOR |
84 | // Try without TOR |
85 | $cmd = "nc -zw$timeout $host $port 2>/dev/null"; |
85 | $cmd = "nc -zw$timeout $host $port 2>/dev/null"; |
86 | exec($cmd, $out, $code); |
86 | exec($cmd, $out, $code); |
87 | return ($code == 0); |
87 | return ($code == 0); |
88 | } |
88 | } |
89 | 89 | ||
90 | function getAllFiles($directory, $recursive = true, $include_dirs = false, $include_files = true) { |
90 | function getAllFiles($directory, $recursive = true, $include_dirs = false, $include_files = true) { |
91 | $result = array(); |
91 | $result = array(); |
92 | $handle = opendir($directory); |
92 | $handle = opendir($directory); |
93 | if (substr($directory, -1) == '/') $directory = substr($directory, 0, strlen($directory)-1); |
93 | if (substr($directory, -1) == '/') $directory = substr($directory, 0, strlen($directory)-1); |
94 | if ($include_dirs) { |
94 | if ($include_dirs) { |
95 | $result[] = $directory; |
95 | $result[] = $directory; |
96 | } |
96 | } |
97 | while ($datei = readdir($handle)) { |
97 | while ($datei = readdir($handle)) { |
98 | if (($datei != '.') && ($datei != '..')) { |
98 | if (($datei != '.') && ($datei != '..')) { |
99 | $file = $directory.'/'.$datei; |
99 | $file = $directory.'/'.$datei; |
100 | if (is_dir($file)) { |
100 | if (is_dir($file)) { |
101 | if ($include_dirs && !$recursive) { |
101 | if ($include_dirs && !$recursive) { |
102 | $result[] = $file; |
102 | $result[] = $file; |
103 | } |
103 | } |
104 | if ($recursive) { |
104 | if ($recursive) { |
105 | $result = array_merge($result, getAllFiles($file, $recursive, $include_dirs, $include_files)); |
105 | $result = array_merge($result, getAllFiles($file, $recursive, $include_dirs, $include_files)); |
106 | } |
106 | } |
107 | } else { |
107 | } else { |
108 | if ($include_files) $result[] = $file; |
108 | if ($include_files) $result[] = $file; |
109 | } |
109 | } |
110 | } |
110 | } |
111 | } |
111 | } |
112 | closedir($handle); |
112 | closedir($handle); |
113 | return $result; |
113 | return $result; |
114 | } |
114 | } |
115 | 115 | ||
116 | // TOR capable |
116 | // TOR capable |
117 | function file_get_contents2($url, $postvalues='', $headers=array()) { |
117 | function file_get_contents2($url, $postvalues='', $headers=array()) { |
118 | # exec ("wget -N -O - -- ".escapeshellarg($url), $out); |
118 | # exec ("wget -N -O - -- ".escapeshellarg($url), $out); |
119 | 119 | ||
120 | $add_cmd = ''; |
120 | $add_cmd = ''; |
121 | foreach ($headers as $name => $h) { |
121 | foreach ($headers as $name => $h) { |
122 | if (is_numeric($name)) { |
122 | if (is_numeric($name)) { |
123 | $add_cmd .= "-H ".escapeshellarg($h)." "; |
123 | $add_cmd .= "-H ".escapeshellarg($h)." "; |
124 | } else { |
124 | } else { |
125 | $add_cmd .= "-H ".escapeshellarg($name.': '.$h)." "; |
125 | $add_cmd .= "-H ".escapeshellarg($name.': '.$h)." "; |
126 | } |
126 | } |
127 | } |
127 | } |
128 | 128 | ||
129 | if ($postvalues != '') { |
129 | if ($postvalues != '') { |
130 | $add_cmd .= "-d ".escapeshellarg($postvalues)." "; |
130 | $add_cmd .= "-d ".escapeshellarg($postvalues)." "; |
131 | } |
131 | } |
132 | 132 | ||
133 | exec("curl --cookie ~/.cookiejar --cookie-jar ~/.cookiejar -s -k -L -A 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0' $add_cmd".escapeshellarg($url), $out); |
133 | exec("curl --cookie ~/.cookiejar --cookie-jar ~/.cookiejar -s -k -L -A 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0' $add_cmd".escapeshellarg($url), $out); |
134 | 134 | ||
135 | return implode("\n", $out); |
135 | return implode("\n", $out); |
136 | } |
136 | } |
137 | 137 | ||
138 | function make_tabs($text, $abstand = 4) { |
138 | function make_tabs($text, $abstand = 4) { |
139 | $ary = explode("\n", $text); |
139 | $ary = explode("\n", $text); |
140 | $longest = 0; |
140 | $longest = 0; |
141 | foreach ($ary as $a) { |
141 | foreach ($ary as $a) { |
142 | $bry = explode(':', $a, 2); |
142 | $bry = explode(':', $a, 2); |
143 | if (count($bry) < 2) continue; |
143 | if (count($bry) < 2) continue; |
144 | $c = strlen($bry[0]); |
144 | $c = strlen($bry[0]); |
145 | if ($c > $longest) $longest = $c; |
145 | if ($c > $longest) $longest = $c; |
146 | } |
146 | } |
147 | foreach ($ary as $n => $a) { |
147 | foreach ($ary as $n => $a) { |
148 | $bry = explode(':', $a, 2); |
148 | $bry = explode(':', $a, 2); |
149 | if (count($bry) < 2) continue; |
149 | if (count($bry) < 2) continue; |
150 | $rep = $longest-strlen($bry[0]) + $abstand; |
150 | $rep = $longest-strlen($bry[0]) + $abstand; |
151 | if ($rep < 1) { |
151 | if ($rep < 1) { |
152 | $wh = ''; |
152 | $wh = ''; |
153 | } else { |
153 | } else { |
154 | $wh = str_repeat(' ', $rep); |
154 | $wh = str_repeat(' ', $rep); |
155 | } |
155 | } |
156 | $ary[$n] = $bry[0].':'.$wh.trim($bry[1]); |
156 | $ary[$n] = $bry[0].':'.$wh.trim($bry[1]); |
157 | } |
157 | } |
158 | $x = implode("\n", $ary); |
158 | $x = implode("\n", $ary); |
159 | return $x; |
159 | return $x; |
160 | } |
160 | } |
161 | 161 | ||
162 | function uc_latin1($str) { |
162 | function uc_latin1($str) { |
163 | # Source: http://de3.php.net/manual/en/function.strtoupper.php#82592 |
163 | # Source: http://de3.php.net/manual/en/function.strtoupper.php#82592 |
164 | $str = strtoupper(strtr($str, "àáâãäåæçèéêëìíîïðñòóôõöøùúûüý", |
164 | $str = strtoupper(strtr($str, "àáâãäåæçèéêëìíîïðñòóôõöøùúûüý", |
165 | "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝ")); |
165 | "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝ")); |
166 | return strtr($str, array("ß" => "SS")); |
166 | return strtr($str, array("ß" => "SS")); |
167 | } |
167 | } |
168 | 168 | ||
169 | /** |
169 | /** |
170 | * Converts tabs to the appropriate amount of spaces while preserving formatting |
170 | * Converts tabs to the appropriate amount of spaces while preserving formatting |
171 | * |
171 | * |
172 | * @author Aidan Lister <aidan@php.net> |
172 | * @author Aidan Lister <aidan@php.net> |
173 | * @version 1.2.0 |
173 | * @version 1.2.0 |
174 | * @link http://aidanlister.com/repos/v/function.tab2space.php |
174 | * @link http://aidanlister.com/repos/v/function.tab2space.php |
175 | * @param string $text The text to convert |
175 | * @param string $text The text to convert |
176 | * @param int $spaces Number of spaces per tab column |
176 | * @param int $spaces Number of spaces per tab column |
177 | * @param boolean $html Output as HTML or not |
177 | * @param boolean $html Output as HTML or not |
178 | * @return string The text with tabs replaced |
178 | * @return string The text with tabs replaced |
179 | */ |
179 | */ |
180 | function tab2space($text, $spaces = 4, $html = false) { |
180 | function tab2space($text, $spaces = 4, $html = false) { |
181 | // Snippet from PHP Share: http://www.phpshare.org/scripts/Convert-Tabs-to-Spaces |
181 | // Snippet from PHP Share: http://www.phpshare.org/scripts/Convert-Tabs-to-Spaces |
182 | // Modified by Daniel Marschall: Added $html param |
182 | // Modified by Daniel Marschall: Added $html param |
183 | 183 | ||
184 | // Explode the text into an array of single lines |
184 | // Explode the text into an array of single lines |
185 | $lines = explode("\n", $text); |
185 | $lines = explode("\n", $text); |
186 | 186 | ||
187 | // Loop through each line |
187 | // Loop through each line |
188 | foreach ($lines as $line) { |
188 | foreach ($lines as $line) { |
189 | // Break out of the loop when there are no more tabs to replace |
189 | // Break out of the loop when there are no more tabs to replace |
190 | while (false !== $tab_pos = strpos($line, "\t")) { |
190 | while (false !== $tab_pos = strpos($line, "\t")) { |
191 | // Break the string apart, insert spaces then concatenate |
191 | // Break the string apart, insert spaces then concatenate |
192 | $start = substr($line, 0, $tab_pos); |
192 | $start = substr($line, 0, $tab_pos); |
193 | $tab = str_repeat($html ? ' ' : '', $spaces - $tab_pos % $spaces); |
193 | $tab = str_repeat($html ? ' ' : '', $spaces - $tab_pos % $spaces); |
194 | $end = substr($line, $tab_pos + 1); |
194 | $end = substr($line, $tab_pos + 1); |
195 | $line = $start . $tab . $end; |
195 | $line = $start . $tab . $end; |
196 | } |
196 | } |
197 | 197 | ||
198 | $result[] = $line; |
198 | $result[] = $line; |
199 | } |
199 | } |
200 | 200 | ||
201 | return implode("\n", $result); |
201 | return implode("\n", $result); |
202 | } |
202 | } |
203 | 203 | ||
204 | function trim_each_line($x) { |
204 | function trim_each_line($x) { |
205 | $res = ''; |
205 | $res = ''; |
206 | foreach (explode("\n", $x) as $y) { |
206 | foreach (explode("\n", $x) as $y) { |
207 | $res .= trim($y)."\n"; |
207 | $res .= trim($y)."\n"; |
208 | } |
208 | } |
209 | return $res; |
209 | return $res; |
210 | } |
210 | } |
211 | 211 | ||
212 | function generateRandomString($length = 10) { |
212 | function generateRandomString($length = 10) { |
213 | $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; |
213 | $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; |
214 | $randomString = ''; |
214 | $randomString = ''; |
215 | for ($i = 0; $i < $length; $i++) { |
215 | for ($i = 0; $i < $length; $i++) { |
216 | $randomString .= $characters[rand(0, strlen($characters) - 1)]; |
216 | $randomString .= $characters[rand(0, strlen($characters) - 1)]; |
217 | } |
217 | } |
218 | return $randomString; |
218 | return $randomString; |
219 | } |
219 | } |
220 | 220 | ||
221 | # http://stackoverflow.com/a/9361531 |
221 | # http://stackoverflow.com/a/9361531 |
222 | function _uniord($c) { |
222 | function _uniord($c) { |
223 | if (ord($c{0}) >=0 && ord($c{0}) <= 127) |
223 | if (ord($c[0]) >=0 && ord($c[0]) <= 127) |
224 | return ord($c{0}); |
224 | return ord($c[0]); |
225 | if (ord($c{0}) >= 192 && ord($c{0}) <= 223) |
225 | if (ord($c[0]) >= 192 && ord($c[0]) <= 223) |
226 | return (ord($c{0})-192)*64 + (ord($c{1})-128); |
226 | return (ord($c[0])-192)*64 + (ord($c[1])-128); |
227 | if (ord($c{0}) >= 224 && ord($c{0}) <= 239) |
227 | if (ord($c[0]) >= 224 && ord($c[0]) <= 239) |
228 | return (ord($c{0})-224)*4096 + (ord($c{1})-128)*64 + (ord($c{2})-128); |
228 | return (ord($c[0])-224)*4096 + (ord($c[1])-128)*64 + (ord($c[2])-128); |
229 | if (ord($c{0}) >= 240 && ord($c{0}) <= 247) |
229 | if (ord($c[0]) >= 240 && ord($c[0]) <= 247) |
230 | return (ord($c{0})-240)*262144 + (ord($c{1})-128)*4096 + (ord($c{2})-128)*64 + (ord($c{3})-128); |
230 | return (ord($c[0])-240)*262144 + (ord($c[1])-128)*4096 + (ord($c[2])-128)*64 + (ord($c[3])-128); |
231 | if (ord($c{0}) >= 248 && ord($c{0}) <= 251) |
231 | if (ord($c[0]) >= 248 && ord($c[0]) <= 251) |
232 | return (ord($c{0})-248)*16777216 + (ord($c{1})-128)*262144 + (ord($c{2})-128)*4096 + (ord($c{3})-128)*64 + (ord($c{4})-128); |
232 | return (ord($c[0])-248)*16777216 + (ord($c[1])-128)*262144 + (ord($c[2])-128)*4096 + (ord($c[3])-128)*64 + (ord($c[4])-128); |
233 | if (ord($c{0}) >= 252 && ord($c{0}) <= 253) |
233 | if (ord($c[0]) >= 252 && ord($c[0]) <= 253) |
234 | return (ord($c{0})-252)*1073741824 + (ord($c{1})-128)*16777216 + (ord($c{2})-128)*262144 + (ord($c{3})-128)*4096 + (ord($c{4})-128)*64 + (ord($c{5})-128); |
234 | return (ord($c[0])-252)*1073741824 + (ord($c[1])-128)*16777216 + (ord($c[2])-128)*262144 + (ord($c[3])-128)*4096 + (ord($c[4])-128)*64 + (ord($c[5])-128); |
235 | if (ord($c{0}) >= 254 && ord($c{0}) <= 255) // error |
235 | if (ord($c[0]) >= 254 && ord($c[0]) <= 255) // error |
236 | return FALSE; |
236 | return FALSE; |
237 | return 0; |
237 | return 0; |
238 | } |
238 | } |
239 | 239 | ||
240 | # urn:OID:2.0999 -> .2.999 |
240 | # urn:OID:2.0999 -> .2.999 |
241 | function normalize_oid($oid, $leading_dot=true) { |
241 | function normalize_oid($oid, $leading_dot=true) { |
242 | # remove urn:oid: and oid: |
242 | # remove urn:oid: and oid: |
243 | $oid = preg_replace('@^(urn:oid:|oid:|)@i', '', $oid); |
243 | $oid = preg_replace('@^(urn:oid:|oid:|)@i', '', $oid); |
244 | 244 | ||
245 | # add leading dot if it does not already exist |
245 | # add leading dot if it does not already exist |
246 | $oid = preg_replace('@^\.@', '', $oid); |
246 | $oid = preg_replace('@^\.@', '', $oid); |
247 | $oid = '.' . $oid; |
247 | $oid = '.' . $oid; |
248 | 248 | ||
249 | # remove leading zeros (requires leading dot) |
249 | # remove leading zeros (requires leading dot) |
250 | $oid = preg_replace('@\.0*([1-9])@', '.$1', $oid); |
250 | $oid = preg_replace('@\.0*([1-9])@', '.$1', $oid); |
251 | 251 | ||
252 | if (!$leading_dot) { |
252 | if (!$leading_dot) { |
253 | $oid = preg_replace('@^\\.@s', '', $oid); |
253 | $oid = preg_replace('@^\\.@s', '', $oid); |
254 | } |
254 | } |
255 | 255 | ||
256 | return $oid; |
256 | return $oid; |
257 | } |
257 | } |
258 | 258 | ||
259 | function generateRandomToken($haystack, $length = 20) { |
259 | function generateRandomToken($haystack, $length = 20) { |
260 | do { |
260 | do { |
261 | $t = generateRandomString($length); |
261 | $t = generateRandomString($length); |
262 | } while (strpos($haystack, $t) !== false); |
262 | } while (strpos($haystack, $t) !== false); |
263 | return $t; |
263 | return $t; |
264 | } |
264 | } |
265 | 265 | ||
266 | function github_commit_count($user, $repo) { |
266 | function github_commit_count($user, $repo) { |
267 | $cont = file_get_contents("https://github.com/$user/$repo"); |
267 | $cont = file_get_contents("https://github.com/$user/$repo"); |
268 | if (preg_match('@<strong>(\\d+)</strong>\s*<span[^>]+aria-label="Commits on master"[^>]*>\s*commits\s*</span>@smU', $cont, $m)) { |
268 | if (preg_match('@<strong>(\\d+)</strong>\s*<span[^>]+aria-label="Commits on master"[^>]*>\s*commits\s*</span>@smU', $cont, $m)) { |
269 | return $m[1]; |
269 | return $m[1]; |
270 | } else { |
270 | } else { |
271 | return "?"; |
271 | return "?"; |
272 | } |
272 | } |
273 | } |
273 | } |
274 | 274 |