Browse Source

tinyproxy: import from packages, add myself as maintainer

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
Jo-Philipp Wich 10 years ago
parent
commit
f0e44cb3da

+ 51
- 0
net/tinyproxy/Makefile View File

@@ -0,0 +1,51 @@
1
+#
2
+# Copyright (C) 2006-2014 OpenWrt.org
3
+#
4
+# This is free software, licensed under the GNU General Public License v2.
5
+# See /LICENSE for more information.
6
+#
7
+
8
+include $(TOPDIR)/rules.mk
9
+
10
+PKG_NAME:=tinyproxy
11
+PKG_VERSION:=1.8.3
12
+PKG_RELEASE:=1
13
+
14
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
15
+PKG_SOURCE_URL:=http://www.banu.com/pub/tinyproxy/1.8/
16
+PKG_MD5SUM:=292ac51da8ad6ae883d4ebf56908400d
17
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
18
+
19
+PKG_INSTALL:=1
20
+
21
+include $(INCLUDE_DIR)/package.mk
22
+
23
+define Package/tinyproxy
24
+  SUBMENU:=Web Servers/Proxies
25
+  SECTION:=net
26
+  CATEGORY:=Network
27
+  TITLE:=Tinyproxy is a lightweight HTTP and HTTPS proxy
28
+  URL:=http://tinyproxy.sourceforge.net/
29
+endef
30
+
31
+define Package/tinyproxy/conffiles
32
+/etc/config/tinyproxy
33
+endef
34
+
35
+CONFIGURE_ARGS+= \
36
+	--enable-filter \
37
+	--enable-transparent \
38
+	--disable-regexcheck \
39
+
40
+define Package/tinyproxy/install
41
+	$(INSTALL_DIR) $(1)/usr/sbin
42
+	$(CP) $(PKG_INSTALL_DIR)/usr/sbin/tinyproxy $(1)/usr/sbin/
43
+	$(INSTALL_DIR) $(1)/usr/share/tinyproxy
44
+	$(CP) $(PKG_INSTALL_DIR)/usr/share/tinyproxy/*.html $(1)/usr/share/tinyproxy/
45
+	$(INSTALL_DIR) $(1)/etc/config
46
+	$(INSTALL_CONF) ./files/tinyproxy.config $(1)/etc/config/tinyproxy
47
+	$(INSTALL_DIR) $(1)/etc/init.d
48
+	$(INSTALL_BIN) ./files/tinyproxy.init $(1)/etc/init.d/tinyproxy
49
+endef
50
+
51
+$(eval $(call BuildPackage,tinyproxy))

+ 251
- 0
net/tinyproxy/files/tinyproxy.config View File

@@ -0,0 +1,251 @@
1
+config tinyproxy
2
+
3
+#
4
+# Enable the proxy
5
+#
6
+option enabled 0
7
+
8
+#
9
+# Name of the user the tinyproxy daemon should switch to after the port
10
+# has been bound.
11
+#
12
+option User nobody
13
+option Group nogroup
14
+
15
+#
16
+# Port to listen on.
17
+#
18
+option Port 8888
19
+
20
+#
21
+# If you have multiple interfaces this allows you to bind to only one. If
22
+# this is commented out, tinyproxy will bind to all interfaces present.
23
+#
24
+#option Listen 192.168.0.1
25
+
26
+#
27
+# The Bind directive allows you to bind the outgoing connections to a
28
+# particular IP address.
29
+#
30
+#option Bind 192.168.0.1
31
+
32
+#
33
+# Timeout: The number of seconds of inactivity a connection is allowed to
34
+# have before it closed by tinyproxy.
35
+#
36
+option Timeout 600
37
+
38
+#
39
+# ErrorFile: Defines the HTML file to send when a given HTTP error
40
+# occurs.  You will probably need to customize the location to your
41
+# particular install.  The usual locations to check are:
42
+#   /usr/local/share/tinyproxy
43
+#   /usr/share/tinyproxy
44
+#   /etc/tinyproxy
45
+#
46
+#option ErrorFile_404 "/usr/share/tinyproxy/404.html"
47
+#option ErrorFile_400 "/usr/share/tinyproxy/400.html"
48
+#option ErrorFile_503 "/usr/share/tinyproxy/503.html"
49
+#option ErrorFile_403 "/usr/share/tinyproxy/403.html"
50
+#option ErrorFile_408 "/usr/share/tinyproxy/408.html"
51
+
52
+# 
53
+# DefaultErrorFile: The HTML file that gets sent if there is no
54
+# HTML file defined with an ErrorFile keyword for the HTTP error
55
+# that has occured.
56
+#
57
+option DefaultErrorFile "/usr/share/tinyproxy/default.html"
58
+
59
+#
60
+# StatFile: The HTML file that gets sent when a request is made
61
+# for the stathost.  If this file doesn't exist a basic page is
62
+# hardcoded in tinyproxy.
63
+#
64
+option StatFile "/usr/share/tinyproxy/stats.html"
65
+
66
+#
67
+# Where to log the information. Either LogFile or Syslog should be set,
68
+# but not both.
69
+#
70
+option LogFile "/var/log/tinyproxy.log"
71
+#option Syslog 1
72
+
73
+#
74
+# Set the logging level. Allowed settings are:
75
+#	Critical	(least verbose)
76
+#	Error
77
+#	Warning
78
+#	Notice
79
+#	Connect		(to log connections without Info's noise)
80
+#	Info		(most verbose)
81
+# The LogLevel logs from the set level and above. For example, if the LogLevel
82
+# was set to Warning, than all log messages from Warning to Critical would be
83
+# output, but Notice and below would be suppressed.
84
+#
85
+option LogLevel Info
86
+
87
+#
88
+# Include the X-Tinyproxy header, which has the client's IP address when
89
+# connecting to the sites listed.
90
+#
91
+# list XTinyproxy mydomain.com
92
+
93
+#
94
+# This is the absolute highest number of threads which will be created. In
95
+# other words, only MaxClients number of clients can be connected at the
96
+# same time.
97
+#
98
+option MaxClients 100
99
+
100
+#
101
+# These settings set the upper and lower limit for the number of
102
+# spare servers which should be available. If the number of spare servers
103
+# falls below MinSpareServers then new ones will be created. If the number
104
+# of servers exceeds MaxSpareServers then the extras will be killed off.
105
+#
106
+option MinSpareServers 5
107
+option MaxSpareServers 20
108
+
109
+#
110
+# Number of servers to start initially.
111
+#
112
+option StartServers 10
113
+
114
+#
115
+# MaxRequestsPerChild is the number of connections a thread will handle
116
+# before it is killed. In practise this should be set to 0, which disables
117
+# thread reaping. If you do notice problems with memory leakage, then set
118
+# this to something like 10000
119
+#
120
+option MaxRequestsPerChild 0
121
+
122
+#
123
+# The following is the authorization controls. If there are any access
124
+# control keywords then the default action is to DENY. Otherwise, the
125
+# default action is ALLOW.
126
+#
127
+# Also the order of the controls are important. The incoming connections
128
+# are tested against the controls based on order.
129
+#
130
+list Allow 127.0.0.1
131
+#list Allow 192.168.0.0/16
132
+#list Allow 172.16.0.0/12
133
+#list Allow 10.0.0.0/8
134
+
135
+#
136
+# The "Via" header is required by the HTTP RFC, but using the real host name
137
+# is a security concern.  If the following directive is enabled, the string
138
+# supplied will be used as the host name in the Via header; otherwise, the
139
+# server's host name will be used.
140
+#
141
+option ViaProxyName "tinyproxy"
142
+
143
+#
144
+# The location of the filter file.
145
+#
146
+#option Filter "/etc/tinyproxy/filter"
147
+
148
+#
149
+# Filter based on URLs rather than domains.
150
+#
151
+#option FilterURLs 1
152
+
153
+#
154
+# Use POSIX Extended regular expressions rather than basic.
155
+#
156
+#option FilterExtended 1
157
+
158
+#
159
+# Use case sensitive regular expressions.
160
+#                                                                         
161
+#option FilterCaseSensitive 1
162
+
163
+#
164
+# Change the default policy of the filtering system.  If this directive is
165
+# commented out, or is set to "0" then the default policy is to allow
166
+# everything which is not specifically denied by the filter file.
167
+#
168
+# However, by setting this directive to "1" the default policy becomes to
169
+# deny everything which is _not_ specifically allowed by the filter file.
170
+#
171
+#option FilterDefaultDeny 1
172
+
173
+#
174
+# If an Anonymous keyword is present, then anonymous proxying is enabled.
175
+# The headers listed are allowed through, while all others are denied. If
176
+# no Anonymous keyword is present, then all header are allowed through.
177
+# You must include quotes around the headers.
178
+#
179
+#list Anonymous "Host"
180
+#list Anonymous "Authorization"
181
+
182
+#
183
+# This is a list of ports allowed by tinyproxy when the CONNECT method
184
+# is used.  To disable the CONNECT method altogether, set the value to 0.
185
+# If no ConnectPort line is found, all ports are allowed (which is not
186
+# very secure.)
187
+#
188
+# The following two ports are used by SSL.
189
+#
190
+list ConnectPort 443
191
+list ConnectPort 563
192
+
193
+#
194
+# Turns on upstream proxy support.
195
+#
196
+# The upstream rules allow you to selectively route upstream connections
197
+# based on the host/domain of the site being accessed.
198
+#
199
+# For example:
200
+#  # connection to test domain goes through testproxy
201
+#
202
+#config upstream
203
+#	option type proxy
204
+#	option via testproxy:8008
205
+#	option target ".test.domain.invalid"
206
+#
207
+#config upstream
208
+#	option type proxy
209
+#	option via testproxy:8008
210
+#	option target ".our_testbed.example.com"
211
+#
212
+#config upstream
213
+#	option type proxy
214
+#	option via testproxy:8008
215
+#	option target "192.168.128.0/255.255.254.0"
216
+#
217
+#  # no upstream proxy for internal websites and unqualified hosts
218
+#
219
+#config upstream
220
+#	option type reject
221
+#	option target ".internal.example.com"
222
+#
223
+#config upstream
224
+#	option type reject
225
+#	option target "www.example.com"
226
+#
227
+#config upstream
228
+#	option type reject
229
+#	option target "10.0.0.0/8"
230
+#
231
+#config upstream
232
+#	option type reject
233
+#	option target "192.168.0.0/255.255.254.0"
234
+#
235
+#config upstream
236
+#	option type reject
237
+#	option target "."
238
+#
239
+#  # default upstream is internet firewall
240
+#
241
+#config upstream
242
+#	option type proxy
243
+#	option via firewall.internal.example.com:80
244
+#
245
+# The LAST matching rule wins the route decision.  As you can see, you
246
+# can use a host, or a domain:
247
+#  name     matches host exactly
248
+#  .name    matches any host in domain "name"
249
+#  .        matches any host with no domain (in 'empty' domain)
250
+#  IP/bits  matches network/mask
251
+#  IP/mask  matches network/mask

+ 138
- 0
net/tinyproxy/files/tinyproxy.init View File

@@ -0,0 +1,138 @@
1
+#!/bin/sh /etc/rc.common
2
+# Copyright (C) 2008-2011 OpenWrt.org
3
+
4
+START=50
5
+
6
+CFGFILE=/var/etc/tinyproxy.conf
7
+
8
+section_enabled() {
9
+	config_get_bool enabled "$1" 'enabled' 0
10
+	[ $enabled -gt 0 ]
11
+}
12
+
13
+start() {
14
+	config_load 'tinyproxy'
15
+	config_foreach start_proxy 'tinyproxy'
16
+}
17
+
18
+stop() {
19
+	service_stop /usr/sbin/tinyproxy
20
+}
21
+
22
+start_proxy() {
23
+	section_enabled "$1" || return 1
24
+
25
+	mkdir -m0755 -p /var/etc
26
+	echo '### AUTOGENERATED CONFIGURATION' > $CFGFILE
27
+	echo '### DO NOT EDIT' >> $CFGFILE
28
+	echo '### SEE /etc/config/tinyproxy INSTEAD' >> $CFGFILE
29
+	echo '' >> $CFGFILE
30
+
31
+	proxy_atom "$1" User >> $CFGFILE
32
+	proxy_atom "$1" Group >> $CFGFILE
33
+	proxy_atom "$1" Port 8888 >> $CFGFILE
34
+	proxy_atom "$1" Listen >> $CFGFILE
35
+	proxy_atom "$1" Bind >> $CFGFILE
36
+	proxy_atom "$1" Timeout >> $CFGFILE
37
+
38
+	proxy_string "$1" ErrorFile_400 "ErrorFile 400" >> $CFGFILE
39
+	proxy_string "$1" ErrorFile_403 "ErrorFile 403" >> $CFGFILE
40
+	proxy_string "$1" ErrorFile_404 "ErrorFile 404" >> $CFGFILE
41
+	proxy_string "$1" ErrorFile_408 "ErrorFile 408" >> $CFGFILE
42
+	proxy_string "$1" ErrorFile_503 "ErrorFile 503" >> $CFGFILE
43
+
44
+	proxy_string "$1" DefaultErrorFile >> $CFGFILE
45
+	proxy_string "$1" StatHost StatHost 127.0.0.1 >> $CFGFILE
46
+	proxy_string "$1" StatFile >> $CFGFILE
47
+	proxy_string "$1" LogFile >> $CFGFILE
48
+
49
+	proxy_flag "$1" SysLog >> $CFGFILE
50
+
51
+	proxy_atom "$1" LogLevel >> $CFGFILE
52
+
53
+	proxy_list "$1" XTinyproxy >> $CFGFILE
54
+
55
+	proxy_atom "$1" MaxClients >> $CFGFILE
56
+	proxy_atom "$1" MinSpareServers >> $CFGFILE
57
+	proxy_atom "$1" MaxSpareServers >> $CFGFILE
58
+	proxy_atom "$1" StartServers >> $CFGFILE
59
+	proxy_atom "$1" MaxRequestsPerChild >> $CFGFILE
60
+	proxy_list "$1" Allow >> $CFGFILE
61
+
62
+	proxy_string "$1" ViaProxyName >> $CFGFILE
63
+	proxy_string "$1" Filter >> $CFGFILE
64
+
65
+	proxy_flag "$1" FilterURLs >> $CFGFILE
66
+	proxy_flag "$1" FilterExtended >> $CFGFILE
67
+	proxy_flag "$1" FilterCaseSensitive >> $CFGFILE
68
+	proxy_flag "$1" FilterDefaultDeny Yes No >> $CFGFILE
69
+
70
+	proxy_list "$1" Anonymous '"' >> $CFGFILE
71
+	proxy_list "$1" ConnectPort >> $CFGFILE
72
+
73
+	config_foreach write_upstream upstream
74
+
75
+	service_start /usr/sbin/tinyproxy -c "$CFGFILE"
76
+}
77
+
78
+write_upstream() {
79
+	local type
80
+	local via
81
+	local target
82
+
83
+	config_get "type" "$1" "type"
84
+	config_get via "$1" via
85
+	config_get target "$1" target
86
+	[ -n "$target" ] && target=' "'"$target"'"'
87
+
88
+	[ "$type" == "proxy" -a -n "$via" ] && \
89
+		echo "upstream $via$target" >> $CFGFILE
90
+
91
+	[ "$type" == "reject" -a -n "$target" ] && \
92
+		echo "no upstream$target" >> $CFGFILE
93
+}
94
+
95
+proxy_atom() {
96
+	local SECTION=$1
97
+	local OPTION=$2
98
+	local DEFAULT=$3
99
+
100
+	config_get _value "$SECTION" "$OPTION"
101
+	[ -z "$_value" ] && _value="$DEFAULT"
102
+	[ -n "$_value" ] && echo "$OPTION $_value"
103
+}
104
+
105
+proxy_string() {
106
+	local SECTION=$1
107
+	local OPTION=$2
108
+	local ALIAS=$3
109
+	local DEFAULT=$4
110
+
111
+	config_get _value "$SECTION" "$OPTION"
112
+	[ -z "$_value" ] && _value="$DEFAULT"
113
+	[ -n "$_value" ] && echo "${ALIAS:-${OPTION}} "'"'"$_value"'"'
114
+}
115
+
116
+proxy_flag() {
117
+	local SECTION=$1
118
+	local OPTION=$2
119
+	local TRUE="${3:-On}"
120
+	local FALSE="${4:-Off}"
121
+
122
+	config_get_bool _value "$SECTION" "$OPTION" 0
123
+	[ "$_value" -eq "1" ] && _value="$TRUE" || _value="$FALSE"
124
+	echo "$OPTION $_value"
125
+}
126
+
127
+proxy_list() {
128
+	local SECTION=$1
129
+	local OPTION=$2
130
+	local ENCLOSE=$3
131
+
132
+	config_get _value "$SECTION" "$OPTION"
133
+	[ -n "$_value" ] && {
134
+		for entry in $_value; do
135
+			echo "$OPTION ${ENCLOSE}${entry}${ENCLOSE}"
136
+		done
137
+	}
138
+}

+ 86
- 0
net/tinyproxy/patches/010-no-docs-and-tests.patch View File

@@ -0,0 +1,86 @@
1
+--- a/configure
2
++++ b/configure
3
+@@ -6815,59 +6815,8 @@ fi
4
+ 
5
+ 
6
+ 
7
+-# Check for asciidoc
8
+-# Extract the first word of "a2x", so it can be a program name with args.
9
+-set dummy a2x; ac_word=$2
10
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
11
+-$as_echo_n "checking for $ac_word... " >&6; }
12
+-if test "${ac_cv_path_A2X+set}" = set; then :
13
+-  $as_echo_n "(cached) " >&6
14
+-else
15
+-  case $A2X in
16
+-  [\\/]* | ?:[\\/]*)
17
+-  ac_cv_path_A2X="$A2X" # Let the user override the test with a path.
18
+-  ;;
19
+-  *)
20
+-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
21
+-for as_dir in $PATH
22
+-do
23
+-  IFS=$as_save_IFS
24
+-  test -z "$as_dir" && as_dir=.
25
+-    for ac_exec_ext in '' $ac_executable_extensions; do
26
+-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
27
+-    ac_cv_path_A2X="$as_dir/$ac_word$ac_exec_ext"
28
+-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
29
+-    break 2
30
+-  fi
31
+-done
32
+-  done
33
+-IFS=$as_save_IFS
34
+-
35
+-  test -z "$ac_cv_path_A2X" && ac_cv_path_A2X="no"
36
+-  ;;
37
+-esac
38
+-fi
39
+-A2X=$ac_cv_path_A2X
40
+-if test -n "$A2X"; then
41
+-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $A2X" >&5
42
+-$as_echo "$A2X" >&6; }
43
+-else
44
+-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
45
+-$as_echo "no" >&6; }
46
+-fi
47
+-
48
+-
49
+- if test "x$A2X" != "xno"; then
50
+-  HAVE_A2X_TRUE=
51
+-  HAVE_A2X_FALSE='#'
52
+-else
53
+   HAVE_A2X_TRUE='#'
54
+   HAVE_A2X_FALSE=
55
+-fi
56
+-
57
+-if test x"$A2X" = x"no"; then
58
+-  as_fn_error $? "Test for asciidoc failed. See the file 'INSTALL' for help." "$LINENO" 5
59
+-fi
60
+ 
61
+ ac_config_files="$ac_config_files Makefile src/Makefile data/Makefile data/templates/Makefile etc/Makefile docs/Makefile docs/man5/Makefile docs/man5/tinyproxy.conf.txt docs/man8/Makefile docs/man8/tinyproxy.txt m4macros/Makefile tests/Makefile tests/scripts/Makefile"
62
+ 
63
+--- a/Makefile.am
64
++++ b/Makefile.am
65
+@@ -2,9 +2,7 @@ SUBDIRS = \
66
+ 	src \
67
+ 	data \
68
+ 	etc \
69
+-	docs \
70
+ 	m4macros \
71
+-	tests
72
+ 
73
+ # tools want this on a single line
74
+ ACLOCAL_AMFLAGS = -I m4macros
75
+--- a/Makefile.in
76
++++ b/Makefile.in
77
+@@ -222,9 +222,7 @@ SUBDIRS = \
78
+ 	src \
79
+ 	data \
80
+ 	etc \
81
+-	docs \
82
+ 	m4macros \
83
+-	tests
84
+ 
85
+ 
86
+ # tools want this on a single line

+ 13
- 0
net/tinyproxy/patches/020-config_and_pid-path.patch View File

@@ -0,0 +1,13 @@
1
+--- a/src/main.c
2
++++ b/src/main.c
3
+@@ -326,8 +326,8 @@ static void initialize_config_defaults (
4
+         conf->errorpages = NULL;
5
+         conf->stathost = safestrdup (TINYPROXY_STATHOST);
6
+         conf->idletimeout = MAX_IDLE_TIME;
7
+-        conf->logf_name = safestrdup (LOCALSTATEDIR "/log/tinyproxy/tinyproxy.log");
8
+-        conf->pidpath = safestrdup (LOCALSTATEDIR "/run/tinyproxy/tinyproxy.pid");
9
++        conf->logf_name = safestrdup (LOCALSTATEDIR "/log/tinyproxy.log");
10
++        conf->pidpath = safestrdup (LOCALSTATEDIR "/tinyproxy.pid");
11
+ }
12
+ 
13
+ /**

+ 22
- 0
net/tinyproxy/patches/030-allow_bind_in_transparent_mode.patch View File

@@ -0,0 +1,22 @@
1
+--- a/src/conf.c
2
++++ b/src/conf.c
3
+@@ -865,7 +865,6 @@ static HANDLE_FUNC (handle_deny)
4
+ 
5
+ static HANDLE_FUNC (handle_bind)
6
+ {
7
+-#ifndef TRANSPARENT_PROXY
8
+         int r = set_string_arg (&conf->bind_address, line, &match[2]);
9
+ 
10
+         if (r)
11
+@@ -873,11 +872,6 @@ static HANDLE_FUNC (handle_bind)
12
+         log_message (LOG_INFO,
13
+                      "Outgoing connections bound to IP %s", conf->bind_address);
14
+         return 0;
15
+-#else
16
+-        fprintf (stderr,
17
+-                 "\"Bind\" cannot be used with transparent support enabled.\n");
18
+-        return 1;
19
+-#endif
20
+ }
21
+ 
22
+ static HANDLE_FUNC (handle_listen)

+ 38
- 0
net/tinyproxy/patches/120-fix_INET6.patch View File

@@ -0,0 +1,38 @@
1
+--- a/src/sock.c
2
++++ b/src/sock.c
3
+@@ -39,8 +39,7 @@
4
+  * returned if the bind succeeded.  Otherwise, -1 is returned
5
+  * to indicate an error.
6
+  */
7
+-static int
8
+-bind_socket (int sockfd, const char *addr, int family)
9
++static int bind_socket (int sockfd, const char *addr)
10
+ {
11
+         struct addrinfo hints, *res, *ressave;
12
+ 
13
+@@ -48,7 +47,7 @@ bind_socket (int sockfd, const char *add
14
+         assert (addr != NULL && strlen (addr) != 0);
15
+ 
16
+         memset (&hints, 0, sizeof (struct addrinfo));
17
+-        hints.ai_family = family;
18
++        hints.ai_family = AF_UNSPEC;
19
+         hints.ai_socktype = SOCK_STREAM;
20
+ 
21
+         /* The local port it not important */
22
+@@ -106,14 +105,12 @@ int opensock (const char *host, int port
23
+ 
24
+                 /* Bind to the specified address */
25
+                 if (bind_to) {
26
+-                        if (bind_socket (sockfd, bind_to,
27
+-                                         res->ai_family) < 0) {
28
++                        if (bind_socket (sockfd, bind_to) < 0) {
29
+                                 close (sockfd);
30
+                                 continue;       /* can't bind, so try again */
31
+                         }
32
+                 } else if (config.bind_address) {
33
+-                        if (bind_socket (sockfd, config.bind_address,
34
+-                                         res->ai_family) < 0) {
35
++                        if (bind_socket (sockfd, config.bind_address) < 0) {
36
+                                 close (sockfd);
37
+                                 continue;       /* can't bind, so try again */
38
+                         }