This file is indexed.

/usr/share/pyshared/zeroinstall/helpers.py is in zeroinstall-injector 2.3.3-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
"""
Convenience routines for performing common operations.
@since: 0.28
"""

# Copyright (C) 2009, Thomas Leonard
# See the README file for details, or visit http://0install.net.

from __future__ import print_function

import os, sys
from zeroinstall import support, SafeException, logger
from zeroinstall.support import tasks

DontUseGUI = object()

def get_selections_gui(iface_uri, gui_args, test_callback = None, use_gui = True):
	"""Run the GUI to choose and download a set of implementations.
	The user may ask the GUI to submit a bug report about the program. In that case,
	the GUI may ask us to test it. test_callback is called in that case with the implementations
	to be tested; the callback will typically call L{zeroinstall.injector.run.test_selections} and return the result of that.
	@param iface_uri: the required program, or None to show just the preferences dialog
	@type iface_uri: str
	@param gui_args: any additional arguments for the GUI itself
	@type gui_args: [str]
	@param test_callback: function to use to try running the program
	@type test_callback: L{zeroinstall.injector.selections.Selections} -> str
	@param use_gui: if True, raise a SafeException if the GUI is not available. If None, returns DontUseGUI if the GUI cannot be started. If False, returns DontUseGUI always. (since 1.11)
	@type use_gui: bool | None
	@return: the selected implementations
	@rtype: L{zeroinstall.injector.selections.Selections}
	@since: 0.28"""
	if use_gui is False:
		return DontUseGUI

	if not os.environ.get('DISPLAY', None):
		if use_gui is None:
			return DontUseGUI
		else:
			raise SafeException("Can't use GUI because $DISPLAY is not set")

	from zeroinstall.injector import selections, qdom
	from io import BytesIO

	from os.path import join, dirname
	gui_exe = join(dirname(__file__), '0launch-gui', '0launch-gui')

	import socket
	cli, gui = socket.socketpair()

	try:
		child = os.fork()
		if child == 0:
			# We are the child (GUI)
			try:
				try:
					cli.close()
					# We used to use pipes to support Python2.3...
					os.dup2(gui.fileno(), 1)
					os.dup2(gui.fileno(), 0)
					if use_gui is True:
						gui_args = ['-g'] + gui_args
					if iface_uri is not None:
						gui_args = gui_args + ['--', iface_uri]
					os.execvp(sys.executable, [sys.executable, gui_exe] + gui_args)
				except:
					import traceback
					traceback.print_exc(file = sys.stderr)
			finally:
				sys.stderr.flush()
				os._exit(1)
		# We are the parent (CLI)
		gui.close()
		gui = None

		while True:
			logger.info("Waiting for selections from GUI...")

			reply = support.read_bytes(cli.fileno(), len('Length:') + 9, null_ok = True)
			if reply:
				if not reply.startswith(b'Length:'):
					raise Exception("Expected Length:, but got %s" % repr(reply))
				reply = reply.decode('ascii')
				xml = support.read_bytes(cli.fileno(), int(reply.split(':', 1)[1], 16))

				dom = qdom.parse(BytesIO(xml))
				sels = selections.Selections(dom)

				if dom.getAttribute('run-test'):
					logger.info("Testing program, as requested by GUI...")
					if test_callback is None:
						output = b"Can't test: no test_callback was passed to get_selections_gui()\n"
					else:
						output = test_callback(sels)
					logger.info("Sending results to GUI...")
					output = ('Length:%8x\n' % len(output)).encode('utf-8') + output
					logger.debug("Sending: %s", repr(output))
					while output:
						sent = cli.send(output)
						output = output[sent:]
					continue
			else:
				sels = None

			pid, status = os.waitpid(child, 0)
			assert pid == child
			if status == 1 << 8:
				logger.info("User cancelled the GUI; aborting")
				return None		# Aborted
			elif status == 100 << 8:
				if use_gui is None:
					return DontUseGUI
				else:
					raise SafeException("No GUI available")
			if status != 0:
				raise Exception("Error from GUI: code = %d" % status)
			break
	finally:
		for sock in [cli, gui]:
			if sock is not None: sock.close()
	
	return sels

def ensure_cached(uri, command = 'run', config = None):
	"""Ensure that an implementation of uri is cached.
	If not, it downloads one. It uses the GUI if a display is
	available, or the console otherwise.
	@param uri: the required interface
	@type uri: str
	@type command: str
	@return: the selected implementations, or None if the user cancelled
	@rtype: L{zeroinstall.injector.selections.Selections}"""
	from zeroinstall.injector.driver import Driver

	if config is None:
		from zeroinstall.injector.config import load_config
		config = load_config()

	from zeroinstall.injector.requirements import Requirements
	requirements = Requirements(uri)
	requirements.command = command

	d = Driver(config, requirements)

	if d.need_download() or not d.solver.ready:
		sels = get_selections_gui(uri, ['--command', command], use_gui = None)
		if sels != DontUseGUI:
			return sels
		done = d.solve_and_download_impls()
		tasks.wait_for_blocker(done)

	return d.solver.selections

def exec_man(stores, sels, main = None, fallback_name = None):
	"""Exec the man command to show the man-page for this interface.
	Never returns.
	@type stores: L{zeroinstall.zerostore.Stores}
	@type sels: L{zeroinstall.injector.selections.Selections}
	@type main: str | None
	@type fallback_name: str | None
	@since: 1.12"""
	interface_uri = sels.interface
	selected_impl = sels.selections[interface_uri]

	if selected_impl.id.startswith('package'):
		impl_path = None
	else:
		impl_path = selected_impl.get_path(stores)

	if main is None:
		if sels.commands:
			selected_command = sels.commands[0]
		else:
			print("No <command> in selections!", file=sys.stderr)
			sys.exit(1)
		main = selected_command.path
		if main is None:
			print("No main program for interface '%s'" % interface_uri, file=sys.stderr)
			sys.exit(1)

	prog_name = os.path.basename(main)

	if impl_path is None:
		# Package implementation
		logger.debug("Searching for man-page native command %s (from %s)" % (prog_name, fallback_name))
		os.execlp('man', 'man', prog_name)

	assert impl_path

	logger.debug("Searching for man-page for %s or %s in %s" % (prog_name, fallback_name, impl_path))

	# TODO: the feed should say where the man-pages are, but for now we'll accept
	# a directory called man in some common locations...
	for mandir in ['man', 'share/man', 'usr/man', 'usr/share/man']:
		manpath = os.path.join(impl_path, mandir)
		if os.path.isdir(manpath):
			# Note: unlike "man -M", this also copes with LANG settings...
			os.environ['MANPATH'] = manpath
			os.execlp('man', 'man', prog_name)
			sys.exit(1)

	# No man directory given or found, so try searching for man files

	manpages = []
	for root, dirs, files in os.walk(impl_path):
		for f in files:
			if f.endswith('.gz'):
				manpage_file = f[:-3]
			else:
				manpage_file = f
			if manpage_file.endswith('.1') or \
			   manpage_file.endswith('.6') or \
			   manpage_file.endswith('.8'):
				manpage_prog = manpage_file[:-2]
				if manpage_prog == prog_name or manpage_prog == fallback_name:
					os.execlp('man', 'man', os.path.join(root, f))
					sys.exit(1)
				else:
					manpages.append((root, f))
		for d in list(dirs):
			if d.startswith('.'):
				dirs.remove(d)

	print("No matching manpage was found for '%s' (%s)" % (fallback_name, interface_uri))
	if manpages:
		print("These non-matching man-pages were found, however:")
		for root, file in manpages:
			print(os.path.join(root, file))
	sys.exit(1)