1 /* Shared protocol functions */
8 #include <sys/time.h> /* FreeBSD needs this before resource.h */
10 #include <sys/types.h> /* FreeBSD needs this before resource.h */
11 #ifdef HAVE_SYS_RESOURCE_H
12 #include <sys/resource.h>
20 #include "config/options.h"
21 #include "osdep/osdep.h"
22 #include "protocol/common.h"
23 #include "protocol/protocol.h"
24 #include "protocol/uri.h"
25 #include "util/conv.h"
26 #include "util/memory.h"
27 #include "util/string.h"
30 /* Close all non-terminal file descriptors. */
32 close_all_non_term_fd(void)
39 if (!getrlimit(RLIMIT_NOFILE
, &lim
))
42 for (n
= 3; n
< max
; n
++)
47 init_directory_listing(struct string
*page
, struct uri
*uri
)
49 struct string dirpath
= NULL_STRING
;
50 struct string decoded
= NULL_STRING
;
51 struct string location
= NULL_STRING
;
53 int local
= (uri
->protocol
== PROTOCOL_FILE
);
55 if (!init_string(page
)
56 || !init_string(&dirpath
)
57 || !init_string(&decoded
)
58 || !init_string(&location
)
59 || !add_uri_to_string(&dirpath
, uri
, URI_DATA
)
60 || !add_uri_to_string(&location
, uri
, URI_DIR_LOCATION
))
63 if (dirpath
.length
> 0
64 && !dir_sep(dirpath
.source
[dirpath
.length
- 1])
65 && !add_char_to_string(&dirpath
, local
? CHAR_DIR_SEP
: '/'))
68 /* Decode uri for displaying. Do not use
69 * add_string_to_string, because it for some reason returns
70 * NULL if the second string is empty. */
71 if (!add_bytes_to_string(&decoded
, dirpath
.source
, dirpath
.length
))
73 decode_uri_string(&decoded
);
75 if (!local
&& !add_char_to_string(&location
, '/'))
78 if (!add_to_string(page
, "<html>\n<head><title>"))
81 if (!local
&& !add_html_to_string(page
, location
.source
, location
.length
))
84 if (!add_html_to_string(page
, decoded
.source
, decoded
.length
)
85 || !add_to_string(page
, "</title>\n<base href=\"")
86 || !add_html_to_string(page
, location
.source
, location
.length
)
87 || !add_html_to_string(page
, dirpath
.source
, dirpath
.length
))
90 if (!add_to_string(page
, "\" />\n</head>\n<body>\n<h2>"))
93 /* Use module names? */
94 switch (uri
->protocol
) {
104 case PROTOCOL_GOPHER
:
114 if (!add_to_string(page
, info
)
115 || !add_to_string(page
, " directory "))
118 if (!local
&& !add_string_to_string(page
, &location
))
121 /* Make the directory path with links to each subdir. */
123 const unsigned char *slash
= dirpath
.source
;
124 const unsigned char *pslash
= slash
;
125 const unsigned char sep
= local
? CHAR_DIR_SEP
: '/';
127 while ((slash
= strchr(slash
, sep
)) != NULL
) {
128 done_string(&decoded
);
129 if (!init_string(&decoded
)
130 || !add_bytes_to_string(&decoded
, pslash
, slash
- pslash
))
132 decode_uri_string(&decoded
);
134 if (!add_to_string(page
, "<a href=\"")
135 || !add_html_to_string(page
, location
.source
, location
.length
)
136 || !add_html_to_string(page
, dirpath
.source
, slash
+ 1 - dirpath
.source
)
137 || !add_to_string(page
, "\">")
138 || !add_html_to_string(page
, decoded
.source
, decoded
.length
)
139 || !add_to_string(page
, "</a>")
140 || !add_html_to_string(page
, &sep
, 1))
147 if (!add_to_string(page
, "</h2>\n<pre>")) {
152 done_string(&dirpath
);
153 done_string(&decoded
);
154 done_string(&location
);
156 return page
->length
> 0 ? S_OK
: S_OUT_OF_MEM
;