View | Details | Raw Unified | Return to bug 17915 | Differences between
and this patch

Collapse All | Expand All

(-)debian/changelog (+12 lines)
 Lines 1-3    Link Here 
1
univention-directory-manager-module-example (2.0.8-1) unstable; urgency=low
2
3
  * Fix installation path of translation catalog (Bug #17915)
4
  * Fix creating entry with immediate --redirect.
5
  * Handle errors in ip-phone-tool.
6
  * Parameter errors should exit with 2.
7
  * debian/rules: Fix clean target.
8
  * Fix quoting.
9
  * Add simple script to test implementation.
10
11
 -- Philipp Hahn <hahn@univention.de>  Thu, 17 Feb 2011 07:08:03 +0100
12
1
univention-directory-manager-module-example (2.0.7-1) unstable; urgency=low
13
univention-directory-manager-module-example (2.0.7-1) unstable; urgency=low
2
14
3
  * fix default value for TrueFalseUp syntax (Bug #17915)
15
  * fix default value for TrueFalseUp syntax (Bug #17915)
(-)debian/rules (-17 / +18 lines)
 Lines 44-50    Link Here 
44
44
45
PYVERS := $(shell pyversions -vr)
45
PYVERS := $(shell pyversions -vr)
46
46
47
MO_FILES=$(shell find modules -name '*.po' | sed 's/\.po/\.mo/g')
47
PO_FILES := $(shell find modules -name '*.po')
48
MO_FILES := $(PO_FILES:%.po=%.mo)
48
49
49
%.mo:	%.po
50
%.mo:	%.po
50
	msgfmt -o $@ $<
51
	msgfmt -o $@ $<
 Lines 52-71    Link Here 
52
configure: configure-stamp
53
configure: configure-stamp
53
configure-stamp:
54
configure-stamp:
54
	dh_testdir
55
	dh_testdir
55
	touch configure-stamp
56
	touch $@
56
57
57
build: configure-stamp build-stamp $(MO_FILES)
58
build: configure-stamp build-stamp
58
build-stamp:
59
build-stamp: $(MO_FILES)
59
	dh_testdir
60
	dh_testdir
60
	touch build-stamp
61
	touch $@
61
62
62
clean:
63
clean:
63
	dh_testdir
64
	dh_testdir
64
	dh_testroot
65
	dh_clean
65
	dh_clean
66
	rm -f build-stamp configure-stamp
66
	$(RM) build-stamp configure-stamp
67
	$(RM) debian/*.conffiles
67
	$(RM) debian/*.conffiles
68
	rm -f *~
68
	$(RM) $(MO_FILES)
69
	$(RM) *~
69
70
70
install: build-stamp
71
install: build-stamp
71
	dh_testdir
72
	dh_testdir
 Lines 81-100    Link Here 
81
82
82
	@for i in $(shell find modules/univention/admin/ -name '*.py'); do\
83
	@for i in $(shell find modules/univention/admin/ -name '*.py'); do\
83
		o=${D}/usr/share/pyshared/$${i#modules/};\
84
		o=${D}/usr/share/pyshared/$${i#modules/};\
84
		install -d "`dirname $$o`";\
85
		install -d "`dirname "$$o"`";\
85
		install -m755 $$i $$o;\
86
		install -m755 "$$i" "$$o";\
86
	done
87
	done
87
	@for i in `find modules/univention/admin/handlers/ -name "*.png" -o -name "*.gif"`; do\
88
	@for i in `find modules/univention/admin/handlers/ -name "*.png" -o -name "*.gif"`; do\
88
		o=${D}/usr/share/univention-webui-style/icon/$${i#modules/univention/admin/handlers/};\
89
		o=${D}/usr/share/univention-webui-style/icon/$${i#modules/univention/admin/handlers/};\
89
		install -d "`dirname $$o`";\
90
		install -d "`dirname "$$o"`";\
90
		install -m 644 $$i $$o;\
91
		install -m 644 "$$i" "$$o";\
91
	done
92
	done
92
	@for i in $(MO_FILES); do\
93
	@for i in $(MO_FILES); do\
93
		lang=`basename $$i .mo`;\
94
		lang=`basename "$$i" .mo`;\
94
		domain=`dirname $$i | sed 's,^modules/,,;s,/,-,g'`;\
95
		domain=`dirname "$$i" | sed 's,^modules/,,;s,/,-,g'`;\
95
		o=debian/${D}/usr/share/locale/$$lang/LC_MESSAGES/$$domain.mo;\
96
		o=${D}/usr/share/locale/$$lang/LC_MESSAGES/$$domain.mo;\
96
		install -d "`dirname $$o`";\
97
		install -d "`dirname "$$o"`";\
97
		install -m 644 $$i $$o;\
98
		install -m 644 "$$i" "$$o";\
98
	done
99
	done
99
100
100
	# Install example script
101
	# Install example script
(-)test-implementation (+22 lines)
Line 0    Link Here 
1
#!/bin/sh
2
#
3
# Test module and script
4
#
5
set -e
6
7
ip-phone-tool set voip1 10.1.0.42 sip:user1@dom.local
8
ip-phone-tool set voip1 10.1.0.42 sip:user1@dom.local --redirect sip:otheruser@dom.local
9
ip-phone-tool set voip2 10.1.0.43 sip:user2@dom.local --redirect sip:otheruser@dom.local
10
ip-phone-tool clear_redirect voip1
11
ip-phone-tool remove voip1
12
ip-phone-tool remove voip2
13
14
udm test/ip_phone create --set name=voip1 --set ip=10.1.0.42 --set active=TRUE --set priuser=sip:user1@dom.local
15
dn=$(udm test/ip_phone list --filter name=voip1 | sed -ne 's/^DN: //p')
16
udm test/ip_phone modify --dn "$dn" --option redirection --set redirect_user=sip:otheruser@dom.local
17
udm test/ip_phone create --set name=voip2 --set ip=10.1.0.43 --set active=TRUE --set priuser=sip:user2@dom.local --option redirection --set redirect_user=sip:otheruser@dom.local
18
udm test/ip_phone modify --dn "$dn" --set redirect_user=
19
udm test/ip_phone remove --dn "$dn"
20
udm test/ip_phone remove --filter name=voip2
21
22
echo "Success."
(-)scripts/ip-phone-tool (-29 / +62 lines)
 Lines 30-38    Link Here 
30
30
31
"""Univention IP-Phone Example UDM Client."""
31
"""Univention IP-Phone Example UDM Client."""
32
32
33
import sys, os
33
import sys
34
import os
34
import univention.debug
35
import univention.debug
35
univention.debug.init('/var/log/univention/ip-phone-tool.log', 1, 0)
36
univention.debug.init('/var/log/univention/ip-phone-tool.log', univention.debug.FLUSH, univention.debug.NO_FUNCTION)
36
37
37
import univention.config_registry
38
import univention.config_registry
38
import univention.admin.uldap
39
import univention.admin.uldap
 Lines 45-53    Link Here 
45
from optparse import OptionParser, OptionValueError
46
from optparse import OptionParser, OptionValueError
46
47
47
translation=univention.admin.localization.translation('univention.admin.handlers.test')	## missing in this example
48
translation=univention.admin.localization.translation('univention.admin.handlers.test')	## missing in this example
48
_=translation.translate
49
_ = translation.translate
49
50
50
class ipphonetool:
51
class ipphonetool:
52
	"""Simple example demonstrating how to implement and how to use custom Univention Directory Manager modules.
53
	This is an example tool to manage IP phones.
54
	"""
51
55
52
	def __init__(self, options, ucr=None):
56
	def __init__(self, options, ucr=None):
53
		"""Initialize an authenticated LDAP connection
57
		"""Initialize an authenticated LDAP connection
 Lines 63-75    Link Here 
63
			binddn = ','.join(('cn=admin', self.ldap_base))
67
			binddn = ','.join(('cn=admin', self.ldap_base))
64
			server_role = ucr.get('server/role', '')
68
			server_role = ucr.get('server/role', '')
65
			if server_role in ('domaincontroller_master', 'domaincontroller_backup'):
69
			if server_role in ('domaincontroller_master', 'domaincontroller_backup'):
66
				bindpw = open('/etc/ldap.secret','r').read().strip()
70
				try:
71
					bindpw = open('/etc/ldap.secret','r').read().strip()
72
				except IOError, e:
73
					print >>sys.stderr, "Could not read credentials."
74
					sys.exit(1)
67
			else:
75
			else:
68
				print >>sys.stderr, "No credentials available"
76
				print >>sys.stderr, "No credentials available"
69
				sys.exit(1)
77
				sys.exit(1)
70
78
71
		try:
79
		try:
72
			self.lo=univention.admin.uldap.access(host=ldap_master, base=self.ldap_base, binddn=binddn, bindpw=bindpw, start_tls=2)
80
			self.lo = univention.admin.uldap.access(host=ldap_master, base=self.ldap_base, binddn=binddn, bindpw=bindpw, start_tls=2)
73
		except Exception, e:
81
		except Exception, e:
74
			univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'authentication error: %s' % str(e))
82
			univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'authentication error: %s' % str(e))
75
			print 'authentication error: %s' % str(e)
83
			print 'authentication error: %s' % str(e)
 Lines 85-98    Link Here 
85
		"""This uses the lookup function of the udm module, allowing filtering in terms of UDM properties
93
		"""This uses the lookup function of the udm module, allowing filtering in terms of UDM properties
86
		"""
94
		"""
87
95
88
		filter=univention.admin.filter.expression('name', name)
96
		filter = univention.admin.filter.expression('name', name)
89
97
90
		objs = self.module.lookup(self.co, self.lo, filter, scope='domain', base=self.position.getDomain(), unique=1)
98
		objs = self.module.lookup(self.co, self.lo, filter, scope='domain', base=self.position.getDomain(), unique=1)
91
		if objs:
99
		if objs:
92
			obj=objs[0]
100
			obj = objs[0]
93
		else:
101
		else:
94
			obj = self.module.object(self.co, self.lo, self.position)
102
			obj = self.module.object(self.co, self.lo, self.position)
95
			obj['name']=name
103
			obj['name'] = name
96
104
97
		if not ip == obj['ip']:
105
		if not ip == obj['ip']:
98
			obj['ip'] = ip
106
			obj['ip'] = ip
 Lines 100-106    Link Here 
100
			obj['priuser'] = priuser
108
			obj['priuser'] = priuser
101
109
102
		if options.redirect:
110
		if options.redirect:
103
			obj.options.append('redirection')
111
			if 'redirection' not in obj.options:
112
				obj.options.append('redirection')
104
			obj['redirect_user'] = options.redirect
113
			obj['redirect_user'] = options.redirect
105
		else:		## if no redirection is given, this example removes the objectclass
114
		else:		## if no redirection is given, this example removes the objectclass
106
			if 'redirection' in obj.options:
115
			if 'redirection' in obj.options:
 Lines 108-152    Link Here 
108
			obj['redirect_user'] = options.redirect
117
			obj['redirect_user'] = options.redirect
109
118
110
		if objs:
119
		if objs:
111
			obj.modify()
120
			try:
121
				obj.modify()
122
			except univention.admin.uexceptions.ldapError, e:
123
				univention.debug.debug(univention.debug.ADMIN, univention.debug.ERROR, 'Could not modify entry: %s' % e)
124
				print >>sys.stderr, 'Could not modify entry: %s' % name
125
				sys.exit(1)
112
		else:
126
		else:
113
			obj.create()
127
			try:
128
				obj.create()
129
			except univention.admin.uexceptions.ldapError, e:
130
				univention.debug.debug(univention.debug.ADMIN, univention.debug.ERROR, 'Could not create entry: %s' % e)
131
				print >>sys.stderr, 'Could not create entry: %s' % name
132
				sys.exit(1)
114
133
115
	def remove(self, name):
134
	def remove(self, name):
116
		"""remove the object, no safty belt in this example"""
135
		"""remove the object, no safty belt in this example"""
117
136
118
		filter=univention.admin.filter.expression('name', name)
137
		filter = univention.admin.filter.expression('name', name)
119
138
120
		objs = self.module.lookup(self.co, self.lo, filter, scope='domain', base=self.position.getDomain(), unique=1)
139
		objs = self.module.lookup(self.co, self.lo, filter, scope='domain', base=self.position.getDomain(), unique=1)
121
		if objs:
140
		if objs:
122
			obj=objs[0]
141
			obj = objs[0]
123
			obj.remove()
142
			try:
143
				obj.remove()
144
			except univention.admin.uexceptions.ldapError, e:
145
				univention.debug.debug(univention.debug.ADMIN, univention.debug.ERROR, 'Could not remove entry: %s' % e)
146
				print >>sys.stderr, 'Could not remove entry: %s' % name
147
				sys.exit(1)
148
		else:
149
			print >>sys.stderr, 'Entry not found: %s' % name
150
			sys.exit(1)
124
151
125
	def clear_redirect(self, name):
152
	def clear_redirect(self, name):
126
		"""This example uses a raw LDAP search instead of performing a lookup to determine the dn
153
		"""This example uses a raw LDAP search instead of performing a lookup to determine the dn
127
		"""
154
		"""
128
		try:
155
		try:
129
			filter = unicode('(&(cn=%s)(objectClass=testPhoneCallRedirect))' % name, 'utf8')
156
			filter = unicode('(&(cn=%s)(objectClass=testPhoneCallRedirect))' % name, 'utf8')
130
			dn=self.lo.searchDn(filter=filter, base=self.ldap_base, unique=1)
157
			dn = self.lo.searchDn(filter=filter, base=self.ldap_base, unique=1)
131
			if not dn:
158
			if not dn:
132
				print "No object found matching filter %s" % filter
159
				print "No object found matching filter %s" % filter
133
				sys.exit(1)
160
				sys.exit(1)
134
161
135
			object=univention.admin.objects.get(self.module, self.co, self.lo, position=self.position, dn=dn[0])
162
			object = univention.admin.objects.get(self.module, self.co, self.lo, position=self.position, dn=dn[0])
136
			object.open()						## open the object
163
			object.open()						## open the object
137
164
138
			if 'redirection' in object.options:
165
			if 'redirection' in object.options:
139
				object.options.remove('redirection')
166
				object.options.remove('redirection')
140
167
141
			object['redirect_user']=''
168
			object['redirect_user'] = ''
142
169
143
			univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'ip-phone-tool: redirect_user cleared, modify object')
170
			univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'ip-phone-tool: redirect_user cleared, modify object')
144
			dn=object.modify()
171
			dn = object.modify()
145
172
146
			univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'ip-phone-tool: Redirection deactivated')
173
			univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'ip-phone-tool: Redirection deactivated')
147
174
148
		except univention.admin.uexceptions.valueError, e:
175
		except univention.admin.uexceptions.valueError, e:
149
			univention.debug.debug(univention.debug.ADMIN, univention.debug.ERROR, 'error: invalid syntax (%s)' % e)
176
			univention.debug.debug(univention.debug.ADMIN, univention.debug.ERROR, 'error: invalid syntax (%s)' % e)
177
			print >>sys.stderr, 'Could not modify entry: %s' % name
178
			sys.exit(1)
179
		except univention.admin.uexceptions.ldapError, e:
180
			univention.debug.debug(univention.debug.ADMIN, univention.debug.ERROR, 'Could not modify entry: %s' % e)
181
			print >>sys.stderr, 'Could not modify entry: %s' % name
182
			sys.exit(1)
150
183
151
184
152
if __name__ == '__main__':
185
if __name__ == '__main__':
 Lines 185-191    Link Here 
185
			action = 'store', dest = 'username',
218
			action = 'store', dest = 'username',
186
			help = _('Username') )
219
			help = _('Username') )
187
220
188
	parser.add_option( '', '--redirect',
221
	parser.add_option( '--redirect',
189
			action = 'store', dest = 'redirect',
222
			action = 'store', dest = 'redirect',
190
			help = _('Redirect address') )
223
			help = _('Redirect address') )
191
	(options, arguments) = parser.parse_args()
224
	(options, arguments) = parser.parse_args()
 Lines 198-222    Link Here 
198
	ucr.load()
231
	ucr.load()
199
232
200
	if len(arguments) < 1:
233
	if len(arguments) < 1:
201
		parser.print_help()
234
		parser.print_help(sys.stderr)
202
		sys.exit(1)
235
		sys.exit(2)
203
236
204
	udm_ipphone = ipphonetool(options, ucr)
237
	udm_ipphone = ipphonetool(options, ucr)
205
	if arguments[0] == 'set':
238
	if arguments[0] == 'set':
206
		if len(arguments) < 4:
239
		if len(arguments) < 4:
207
			parser.print_usage()
240
			parser.print_usage(sys.stderr)
208
			sys.exit(1)
241
			sys.exit(2)
209
		udm_ipphone.set( options, arguments[1], arguments[2], arguments[3] )
242
		udm_ipphone.set( options, arguments[1], arguments[2], arguments[3] )
210
	elif  arguments[0] == 'remove':
243
	elif  arguments[0] == 'remove':
211
		if len(arguments) < 2:
244
		if len(arguments) < 2:
212
			parser.print_usage()
245
			parser.print_usage(sys.stderr)
213
			sys.exit(1)
246
			sys.exit(2)
214
		udm_ipphone.remove( arguments[1] )
247
		udm_ipphone.remove( arguments[1] )
215
	elif  arguments[0] == 'clear_redirect':
248
	elif  arguments[0] == 'clear_redirect':
216
		if len(arguments) < 2:
249
		if len(arguments) < 2:
217
			parser.print_usage()
250
			parser.print_usage(sys.stderr)
218
			sys.exit(1)
251
			sys.exit(2)
219
		udm_ipphone.clear_redirect( arguments[1] )
252
		udm_ipphone.clear_redirect( arguments[1] )
220
	else:
253
	else:
221
		parser.print_usage()
254
		parser.print_usage(sys.stderr)
222
		sys.exit(0)
255
		sys.exit(2)
(-)modules/univention/admin/handlers/test/ip_phone.py (-3 / +7 lines)
 Lines 266-280    Link Here 
266
		## weitere Entscheidungen getroffen werden können.
266
		## weitere Entscheidungen getroffen werden können.
267
		self.options = []
267
		self.options = []
268
		if self.oldattr.has_key('objectClass'):
268
		if self.oldattr.has_key('objectClass'):
269
			# Das Objekt existiert bereits im LDAP und wurde von dort geladen
269
			ocs = set(self.oldattr['objectClass'])
270
			ocs = set(self.oldattr['objectClass'])
270
			for opt in ('redirection', ):
271
			for opt in ('redirection', ):
271
				if options[opt].matches(ocs):
272
				if options[opt].matches(ocs):
272
					self.options.append(opt)
273
					self.options.append(opt)
274
			self.old_options = copy.deepcopy(self.options)
273
		else:
275
		else:
276
			# Das Objekt existiert nocht nicht im LDAP und wird neu angelegt.
274
			univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, '%s: reset options to default by _define_options' % module)
277
			univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, '%s: reset options to default by _define_options' % module)
275
			self._define_options(options)
278
			self._define_options(options)
279
			self.old_options = []
276
280
277
		self.old_options = copy.deepcopy(self.options)
278
281
279
	def exists(self):
282
	def exists(self):
280
		u"""Von SimpleLdap intern verwendete Methode, um zu entscheiden, ob ein
283
		u"""Von SimpleLdap intern verwendete Methode, um zu entscheiden, ob ein
 Lines 285-291    Link Here 
285
		u"""Öffnen des LDAP-Objekts."""
288
		u"""Öffnen des LDAP-Objekts."""
286
289
287
		univention.admin.handlers.simpleLdap.open(self)
290
		univention.admin.handlers.simpleLdap.open(self)
288
		## In dieser Methode können die Eigenschaften des Objekts in self.info dynamisch Vor-initialisiert werden. 
291
		## In dieser Methode können die Eigenschaften des Objekts in self.info dynamisch vor-initialisiert werden.
289
		## Das self.info Dictionary kann indirekt angesprochen werden, d.h. z.B. durch self['active'] = 1
292
		## Das self.info Dictionary kann indirekt angesprochen werden, d.h. z.B. durch self['active'] = 1
290
		## Da der Basistyp von 'simpleLdap' (und damit von 'object') die Klasse 'base' ist, verhält sich
293
		## Da der Basistyp von 'simpleLdap' (und damit von 'object') die Klasse 'base' ist, verhält sich
291
		## 'self' wie ein spezielles Dictionary. Es überprüft Operationen anhand der 'property_descriptions'
294
		## 'self' wie ein spezielles Dictionary. Es überprüft Operationen anhand der 'property_descriptions'
 Lines 296-302    Link Here 
296
		## in self.oldinfo und self.oldpolicies gespeichert. Diese dienen später zum Vergleich mit dem
299
		## in self.oldinfo und self.oldpolicies gespeichert. Diese dienen später zum Vergleich mit dem
297
		## aktualisierten Eigenschaften in self.info.
300
		## aktualisierten Eigenschaften in self.info.
298
		self.save()
301
		self.save()
299
		self.old_options = copy.deepcopy(self.options) # Optionen zum späteren Vergleich speichern.
300
302
301
	def _ldap_pre_create(self):
303
	def _ldap_pre_create(self):
302
		u"""Wird vor dem Anlegen des LDAP Objektes aufgerufen."""
304
		u"""Wird vor dem Anlegen des LDAP Objektes aufgerufen."""
 Lines 323-328    Link Here 
323
		pass
325
		pass
324
326
325
	def _update_policies(self):
327
	def _update_policies(self):
328
		u""""Wird bim Anlegen und Modifizieren des Objekts aufgerufen, um ggf.
329
		aktivierte Policies auf das Objekt anzuwenden."""
326
		pass
330
		pass
327
331
328
	def _ldap_addlist(self):
332
	def _ldap_addlist(self):
(-)refresh-i18n (-12 / +11 lines)
 Lines 33-67    Link Here 
33
po=de
33
po=de
34
i18nfile=./modules/univention/admin/handlers/test/$po
34
i18nfile=./modules/univention/admin/handlers/test/$po
35
35
36
xgettext -L Python -o $po.pot modules/univention/admin/handlers/test/*.py scripts/ip-phone-tool
36
xgettext -L Python -o "$po.pot" modules/univention/admin/handlers/test/*.py scripts/ip-phone-tool
37
37
38
grep "Content-Type: text/plain; charset=CHARSET" $po.pot
38
if grep -qs "Content-Type: text/plain; charset=CHARSET" "$po.pot"
39
39
then
40
if [ $? -eq 0 ]; then
41
	echo "Rewriting encoding information from CHARSET to ISO-8859-15"
40
	echo "Rewriting encoding information from CHARSET to ISO-8859-15"
42
	sed -i "s#Content-Type: text/plain; charset=CHARSET#Content-Type: text/plain; charset=ISO-8859-15#" $po.pot
41
	sed -i "s#Content-Type: text/plain; charset=CHARSET#Content-Type: text/plain; charset=ISO-8859-15#" "$po.pot"
43
fi
42
fi
44
43
45
echo "Merging old gettext data with newly introduced strings"
44
echo "Merging old gettext data with newly introduced strings"
46
msgmerge $i18nfile.po  $po.pot > $po.pox
45
msgmerge "$i18nfile.po" "$po.pot" > "$po.pox"
47
46
48
echo "Now you need to fix up all "fuzzy" entries in your editor"
47
echo "Now you need to fix up all "fuzzy" entries in your editor"
49
read
48
read
50
49
51
if [ -n "$EDITOR" ]; then
50
if [ -n "$EDITOR" ]; then
52
    $EDITOR $po.pox
51
    $EDITOR "$po.pox"
53
else
52
else
54
	nano $po.pox
53
	sensible-editor "$po.pox"
55
fi
54
fi
56
55
57
echo "Use this entry? (Y/n)"
56
echo "Use this entry? (Y/n)"
58
read yn
57
read yn
59
58
60
if [ -z "$yn" -o "$yn" = "y" ]; then
59
if [ -z "$yn" ] || [ "$yn" = "y" ]; then
61
    echo "Copying po file"
60
    echo "Copying po file"
62
    cp $po.pox $i18nfile.po
61
    cp "$po.pox" "$i18nfile.po"
63
    echo "Regenerating mo file"
62
    echo "Regenerating mo file"
64
    msgfmt -o $i18nfile.mo $i18nfile.po
63
    msgfmt -o "$i18nfile.mo" "$i18nfile.po"
65
fi
64
fi
66
65
67
rm -rf $po.pot $po.pox
66
rm -rf "$po.pot" "$po.pox"

Return to bug 17915