	protected function info($args) {
		$files = array();
		$sleep = 0;
		$compare = null;
		// long polling mode
		if ($args['compare'] && count($args['targets']) === 1) {
			$compare = intval($args['compare']);
			$hash = $args['targets'][0];
			if ($volume = $this->volume($hash)) {
				$standby = (int)$volume->getOption('plStandby');
				$_compare = false;
				if (($syncCheckFunc = $volume->getOption('syncCheckFunc')) && is_callable($syncCheckFunc)) {
					$_compare = call_user_func_array($syncCheckFunc, array($volume->realpath($hash), $standby, $compare, $volume, $this));
				}
				if ($_compare !== false) {
					$compare = $_compare;
				} else {
					$sleep = max(1, (int)$volume->getOption('tsPlSleep'));
					$limit = max(1, $standby / $sleep) + 1;
					$timelimit = ini_get('max_execution_time');
					do {
						$timelimit && @ set_time_limit($timelimit + $sleep);
						$volume->clearstatcache();
						if (($info = $volume->file($hash)) != false) {
							if ($info['ts'] != $compare) {
								$compare = $info['ts'];
								break;
							}
						} else {
							$compare = 0;
							break;
						}
						if (--$limit) {
							sleep($sleep);
						}
					} while($limit);
				}
			}
		} else {
			foreach ($args['targets'] as $hash) {
				if (($volume = $this->volume($hash)) != false
				&& ($info = $volume->file($hash)) != false) {
					$info['path'] = $volume->path($hash);
					$files[] = $info;
				}
			}
		}
		
		$result = array('files' => $files);
		if (!is_null($compare)) {
			$result['compare'] = strval($compare);
		}
		return $result;
	}
The software constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.